CSVや固定長データ形式など、テキストファイルは扱いやすい反面、ファイルサイズが大きくなりがちです。テキストファイルを zip 等の書庫形式ファイルで保存出来れば、高い圧縮率が期待できるので、場所をとらず論理バックアップやアーカイブにとても便利です。しかし、テキストファイルを一旦出力してから zipへ圧縮するのは二度手間ですし一時的な領域を必要とします。
MTU v4.1 から登場した「並列化可能なパイプ処理」と言う機能は、上記のように他のユーティリティーを使って、テキストファイルを直接何か他のものへ変換する用途にぴったりです。例えば zip アーカイバーと組み合わせてこの機能を使うとダイレクトに zip ファイルへ圧縮されたCSVデータを作ることができます。
処理はとてもスピーディーで弊社の実証実験では1.44ギガバイト分のCSVデータを844メガバイト(圧縮率58パーセント)のzipファイルへ直接圧縮して出力するのに277秒で完了しました。対象が複数あれば、並列実行により更にスピードアップ可能です。
このトピックでは、サンプルなどを挟みながらデータ圧縮の方法を説明したいと思います。
準備するもの | 入手先 | 摘要 |
---|---|---|
MTU v4.1 サンプル版 | こちらから入手 | 64-bit版、32-bit版どちらでも可 |
Zip | Oracle Database Client | ORACLE_HOMEのbinにあります |
7-Zip | こちらから入手 | 64-bit x64版、32-bit x86版どちらでも可 |
MTU は取扱説明書(4.28MB)に解説された方法に従ってインストールしてください。
Zipあるいは7-Zipのいずれを使う場合においても、それぞれの実行形式のあるフォルダを環境変数PATHの指し示す場所に含めてください。
環境変数名 | 出荷時初期値 | 書き換える値 |
---|---|---|
USERID | SYSTEM/MANAGER | SYSTEM/パスワード@DB別名 |
LISTTABLE | EMP,DEPT,SALGRADE | |
STDOUT | 0x0000 | 0x0001 |
STREAM_LOCATOR | zipを使う場合 ipc_pipe://zip “{O}\{C}” -v – 7-Zipを使う場合 ipc_pipe://7z a -t7z -mx1 -si{C}.{X} “{O}/{C}” |
|
SKIPSCR | true | |
EMBED_COLUMN_NAME | ,:”: |
MTUはSTREAM_LOCATORに与えられたipc_pipe://というスキーム文字列の後に続くコマンドを子プロセスとして実行します。
子プロセスは標準入力に対応していなければなりません。また、上記の文字列中にコマンドを与えるとき、標準入力を扱う指定が選択されていなければなりません。
zip の場合、コマンド末尾の’-‘ ハイフンが、7-Zip の場合は -si というスイッチが標準入力を扱う指定となります。
子プロセスが同時に起動される数は環境変数PARALLELISMの値を上限とします。
1つ以上の名無しパイプを使ってMTUと各子プロセスがプロセス間通信を行います。この時、各プロセスは並列に動作します。
中括弧で囲まれたアルファベット文字は、子プロセスへ引き渡される文字列のプレースフォルダを示しており、{O}は出力先フォルダ名、{C}はテーブル名+パーティション名、{X}は拡張子名へそれぞれ変換されます。
これで準備が整いました。それでは実行してみましょう。STREAM_LOCATOR へ zip を使う設定をした場合の事例です。
C:\ProgramData\PLUMSIX\mtu_4.1\x64>unload
Multi-threaded Unloader version 4.11
(c) 2003 Plumsix Co.,Ltd. All rights reserved.
Windows 7 Professional Service Pack 1 (build 7601), 64-bit native
Number of NUMA nodes: 1
Number of physical processor packages: 1
Number of processor cores: 2
Number of logical processors: 2
Number of processor L1/L2/L3 caches: 4/1/0
表データファイル出力を実行します...
#### 途中略 ####
空領域サイズチェックの閾値は 1024Mバイトです。
データファイルと制御ファイルを出力中です。[5280M] C:\ProgramData\PLUMSIX\mtu_4.1\x64\output
ストリームの位置:ipc_pipe://zip "{O}\{C}" -v -
TableName : NumRows: Elapse:Rows/s:Bytes: B/s: Len
EMP : 12: 0.09: 127.: 774.:8234.: 64.
DEPT : 4: 0.10: 41.: 219.:2257.: 54.
SALGRADE : 5: 0.12: 43.: 245.:2112.: 49.
処理対象となった表の総数 : 3
ラウンドトリップ(回) : 137
出力バイト総数(kbytes) : 3.88
所要時間(秒) : 2.68
処理速度(kbytes/秒) : 1.45
正常終了しました。
C:\ProgramData\PLUMSIX\mtu_4.1\x64>dir output ドライブ C のボリューム ラベルがありません。 ボリューム シリアル番号は 5CDE-F5D3 です C:\ProgramData\PLUMSIX\mtu_4.1\x64\output のディレクトリ 2012/10/30 17:24. 2012/10/30 17:24 .. 2012/10/30 17:24 298 DEPT.ctl 2012/10/30 17:24 296 DEPT.zip 2012/10/30 17:24 618 EMP.ctl 2012/10/30 17:24 510 EMP.zip 2012/10/30 17:24 299 SALGRADE.ctl 2012/10/30 17:24 283 SALGRADE.zip 2012/10/30 17:24 594 _stderr.log 2012/10/30 17:24 877 _stdout.log 8 個のファイル 3,775 バイト 2 個のディレクトリ 5,536,919,552 バイトの空き領域
C:\ProgramData\PLUMSIX\mtu_4.1\x64> type output\_stderr.log Information - [B:2012-10-30 17:24:37:zip "C:\ProgramData\PLUMSIX\mtu_4.1\x64\output\SALGRADE" -v -] Information - [E:2012-10-30 17:24:37:zip "C:\ProgramData\PLUMSIX\mtu_4.1\x64\output\SALGRADE" -v -] Information - [B:2012-10-30 17:24:37:zip "C:\ProgramData\PLUMSIX\mtu_4.1\x64\output\EMP" -v -] Information - [E:2012-10-30 17:24:37:zip "C:\ProgramData\PLUMSIX\mtu_4.1\x64\output\EMP" -v -] Information - [B:2012-10-30 17:24:37:zip "C:\ProgramData\PLUMSIX\mtu_4.1\x64\output\DEPT" -v -] Information - [E:2012-10-30 17:24:37:zip "C:\ProgramData\PLUMSIX\mtu_4.1\x64\output\DEPT" -v -]
Information という接頭辞で始まる行はMTUが出力したものです。今回はエラーが発生しなかったので zip が出力したエラーメッセージは何もありません。
C:\ProgramData\PLUMSIX\mtu_4.1\x64> type output\_stdout.log Information - [B:2012-10-30 17:24:37:zip "C:\ProgramData\PLUMSIX\mtu_4.1\x64\output\SALGRADE" -v -] adding: - (in=152) (out=87) (deflated 43%) total bytes=152, compressed=87 -> 43% savings Information - [E:2012-10-30 17:24:37:zip "C:\ProgramData\PLUMSIX\mtu_4.1\x64\output\SALGRADE" -v -] Information - [B:2012-10-30 17:24:37:zip "C:\ProgramData\PLUMSIX\mtu_4.1\x64\output\EMP" -v -] adding: - (in=679) (out=314) (deflated 54%) total bytes=679, compressed=314 -> 54% savings Information - [E:2012-10-30 17:24:37:zip "C:\ProgramData\PLUMSIX\mtu_4.1\x64\output\EMP" -v -] Information - [B:2012-10-30 17:24:37:zip "C:\ProgramData\PLUMSIX\mtu_4.1\x64\output\DEPT" -v -] adding: - (in=124) (out=100) (deflated 19%) total bytes=124, compressed=100 -> 19% savings Information - [E:2012-10-30 17:24:37:zip "C:\ProgramData\PLUMSIX\mtu_4.1\x64\output\DEPT" -v -]
こちらには zip のメッセージが各表ごとに2行分ずつ記録されていました。
C:\ProgramData\PLUMSIX\mtu_4.1\x64> unzip -l output\EMP.zip Archive: output/EMP.zip Length Date Time Name --------- ---------- ----- ---- 679 2012/10/30 17:24 - --------- ------- 679 1 file
C:\ProgramData\PLUMSIX\mtu_4.1\x64> unzip -p output\EMP.zip > output\EMP.dat C:\ProgramData\PLUMSIX\mtu_4.1\x64> type output\EMP.dat "EMPNO","ENAME","JOB","MGR","HIREDATE","SAL","COMM","DEPTNO" 7369,"SMITH","CLERK",7902,"1980/12/17",800,,20 7499,"ALLEN","SALESMAN",7698,"1981/02/20",1600,300,30 7521,"WARD","SALESMAN",7698,"1981/02/22",1250,500,30 7566,"JONES","MANAGER",7839,"1981/04/02",2975,,20 7654,"MARTIN","SALESMAN",7698,"1981/09/28",1250,1400,30 7698,"BLAKE","MANAGER",7839,"1981/05/01",2850,,30 7782,"CLARK","MANAGER",7839,"1981/06/09",2450,,10 7839,"KING","PRESIDENT",,"1981/11/17",5000,,10 7844,"TURNER","SALESMAN",7698,"1981/09/08",1500,0,30 7900,"JAMES","CLERK",7698,"1981/12/03",950,,30 7902,"FORD","ANALYST",7566,"1981/12/03",3000,,20 7934,"MILLER","CLERK",7782,"1982/01/23",1300,,10
C:\ProgramData\PLUMSIX\mtu_4.1\x64> for /F %I in ('dir /b /s output\*.zip') do (unzip -p %~dpnI > %~dpnI.dat) C:\ProgramData\PLUMSIX\mtu_4.1\x64>dir output\*.dat ドライブ C のボリューム ラベルがありません。 ボリューム シリアル番号は 5CDE-F5D3 です C:\ProgramData\PLUMSIX\mtu_4.1\x64\output のディレクトリ 2012/10/31 13:37 124 DEPT.dat 2012/10/31 13:37 679 EMP.dat 2012/10/31 13:37 152 SALGRADE.dat 3 個のファイル 955 バイト 0 個のディレクトリ 5,529,391,104 バイトの空き領域
如何でしたか。ここまで zip を使った実例を示しながら、ファイルの圧縮方法について説明いたしました。
このトピックで取り上げた「並列化可能なパイプ処理」と言う機能は、zip に限らず標準入力を選択できるプログラムであれば何にでも応用することが出来ます。
最後にこの機能を弊社のテスト環境を使って測定したときの性能データを示します。レコード長は151バイト、件数は1千万件で、並列度は1です。
指標 \ 手段 | ノーマル | zip 2.1 | 7-Zip v9.20 |
---|---|---|---|
ファイルサイズ(MB) | 1445 (100%) | 844 (58%) | 832 (57%) |
所要時間(秒) | 103 | 277 | 274 |
データ率(MB/秒) | 14 | 3 | 3 |
テストに使用したCSVデータの一部を示します。
0000000152"cF6vWw","18640222001321",2472159193122,"aVdvGVF1gKkj3Q6",144531.53,"38570401121539","pVczuj ","tR0u6NL6AEZc",681023439147420,"PoLEtACubVlRHluCSt8P", 0000000144"fZUnV8Wct","30770602063844",1910787657492,"ldE3lAcAdCp",961432.64,"33430104102212","jjchhNkk","4uM0U7jIG",604006539366843,"fj4dTUWpin1XF4Gm", 0000000140"dvEyofq4t","23420602183330",745431829922,"2Dv5YDgIU4ZjWz",194972.07,"19340131053824","dLcv ","g1hYDPGjy",785274274473772,"46v3o7YOT3", 0000000146"dZkvpFq","30191030061548",4539188173119,"Vua5uLfUR",302624.1,"25000423200315","4OrYwkG5","y2wRrz7jb9Pp",621299403202238,"fzIqtMNW3NZHCKSNPIAN", 0000000147"X9q3qt6","38440417052938",6169028453271,"isxCj1BFxejQ",39493.22,"28650804021748","aYf1 ","tmWxAa2zWXj",659607368215518,"bX4wjP9Y8RRHy7Pf0SM", 0000000150"bONPzUuwG","28070724103315",1852577489160,"DekdwHPhi9svOG",754542.41,"35201222185540","xxxsoCil","x1mMTsVN0Csn",865734756064736,"u7rwyZIO63UOivc0", 0000000144"adMhv","34220820222923",6006456727601,"IGW1F8ePSOP3Yr",510889.91,"26591028124825","9GqtV ","PxXx7HCgx",83097569186830,"rA4C1W9e4J6xvbS9yY", 0000000133"aiS4k","25110312221040",2088306807610,"p5U0CyRT0",220063.51,"34891229132924","DsyEq ","kFDwnc",652425843337974,"eEInEsqSRaVLVK",
乱数表を使用してランダムに生成した文字が続くので、冗長性が低くあまり圧縮率は上がっていません。従って現実的なデータを対象に行った場合は、圧縮率と所要時間はこれよりも良い結果が得られると思われます。
by 開発1号