【Perl】【Redis】利用Redis的list,來做成低頻寬成本的檔案傳輸。LPOP,RPUSH,Zlib,perl

動機


前陣子幫同事做了perl的mv以後,突然有個想法。
既然bash對系統負擔太大這件事情解決了,那有沒有更好的方法減少專線的傳輸量呢?
於是我看了一下cpu的負載,好像只用到1x%而已。
那麼壓縮內文,傳輸還原這件事情似乎變的可行。畢竟cpu不用白不用,放著也是在吃電。

接著又想起主管講的,有沒有辦法跟redis整合起來。
對吼。redis用的是記憶體,這樣又進一步減少了disk io的使用量。
想想就覺得速度超快的,於是就動手做看看吧。
會不會採用就看成效如何吧,畢竟我現在超興奮。做了再說!


想法


大致上的流程如下圖:
那麼進入動手做吧!

動手做


這邊用到了perl的Redis,Json,跟Zlib。
安裝方式一樣perl make make install。
連結:RedisJsonZlib
首先我們要把他讀出、壓縮、送入redis
#!/usr/bin/perl
use strict;

use Redis;
use Redis::List;
use JSON;

use Compress::Zlib;

my $redis = Redis->new(server => 'localhost:6379');
my $filename = 'test';
open(FILES,$filename);
my $reads;
while (my $row = ){
    $reads.= $row;
}
close(FILES);
my %jsondata = ('filename'=>$filename,'context'=>compress($reads));
my $json_str = encode_json(\%jsondata);

$redis->rpush('mylist',$json_str);

接收端的程式,負責redis讀出、解壓縮、還原檔案
#!/usr/bin/perl
use strict;

use Redis;
use Redis::List;

use JSON;

use Compress::Zlib;

my $redis = Redis->new(server => 'localhost:6379');
my $json_str = $redis->lpop('mylist');
my $jsondata = decode_json($json_str);
my $filename = ${$jsondata}{filename};
my $context = uncompress(${$jsondata}{context});

open(FILES,'>',$filename.'-remote');
print FILES $context;
close(FILES);
很好,完美運作。原本的檔案是test,搬過的檔案則是test-remote。

驗證


畢竟傳輸的資料是壓縮過的,所以我也不用管編碼問題
簡單的用md5來算是不是同一個檔案。
# md5sum test
1dea7d362a8ccdd3a16d645df41c487b test
# md5sum test-remote
1dea7d362a8ccdd3a16d645df41c487b test-remote
完成驗證,是同一個檔案沒錯。那麼來看看壓縮比。
本來的字節是29205,壓縮後只有3562。
節省空間率 88% ...
媽阿省了快九成的傳輸資料...也避開了disk io的附載
缺點是用了好多的cpu時間,反正....還有 90% 的 cpu 沒用到嘛 XD

留言