UD Day 13 アーキテクチャーの検討8(データサイズの極小化)

データを極小化するためには、データの圧縮保存が必要となります。どういったアルゴリズムの選択が望ましいかについて考察します。

圧縮方法としては、以下のものが考えられそうです。
1. base64(数字、アルファベット、+-=の64文字)への変換
2. バイナリーコードへの変換8bit, 16bitなどのエンコード
3. 数字圧縮アルゴリズム(VB Code, γCode …etc)の利用。主に小さい値が多くあるような偏りのあるケースで有効そうです
併せて、DBのの圧縮モードを利用可能である場合はそれを利用するなども検討する対象になります。

圧縮を検討する対象としては、以下のaからcのものが考えられます。

a. ハッシュ値
ハッシュ値は、視覚的には、0から9の数字とaからfの文字で表現されます。上記の方法のうち、1、2の適用が考えられます。ここでは、MySQLの利用を前提とした場合にどのようなサイズの差が生じるかを見たいと思います。base64については、文字列長が固定的にならないため、比較対象からは外しました。つまり、0からfの文字列(hex(0-f))、およびバイナリー(binary, USC2)の間で比較しました。
 ー hex(0-f):varchar(32)、lanti1(1byte code)で定義
 ー binary:binary(16)、unhex(16進数) でバイナリー文字列に変換して、返す(バイナリー文字の1文字は16進数のペア)
 ー USC2:varchar(8)、USC2(2byte code)で定義

ハッシュ値の圧縮

結果は上記の通りとなり、それぞれ93M、69M、73Mとある箇所が、DBの圧縮モード不使用の場合のサイズ、それぞれ49Mとある箇所がDBの圧縮モード利用の場合のサイズとなります。
非圧縮の場合は、binaryが一番優れており、圧縮モードを利用した場合はいずれも変わらない事がわかります。
利用するDB製品によっても異なると思いますが、非圧縮の場合には、binary変換の上で保存するのが望ましいとの見解を得ています。

b. INTの圧縮
INT型には複数の種類があるので、INT型のうちどれが適切かを正しく設定する必要があります。最大値を鑑みて、小さい型にするのがサイズの観点からは望ましいです。
INT等の大きい値を含む型については、数値圧縮アルゴリズムを実装することも検討が必要です(アプリ側)。UDでは、INTの圧縮は特に行っていないので、ここについては、方針のみ考えました。

c. VARCHAR
VARCHAR(m)とした場合のmはバイト数ではなく、文字数になります。
コメント文の場合、モバイル端末では280byte以下までの入力を仕様としています。
この場合、280byteの制限をこの時点でしているため、VARCHAR(280)とすれば良いことになります。

d. テーブルの圧縮 (ROW_FORMAT = COMPRESSED)
読み取りの頻度が多い、SSDを利用する等のケースで特に有効なようです。圧縮によって、ディスク〜メモリー間の転送量、ディスク、メモリーにおける使用量が少なくなります。
圧縮領域と非圧縮領域は最大で1:1程度の比率、低い場合で9:1程度になります。圧縮は少なくとも50%以下なので、メモリ利用の観点では、圧縮の利用が望ましいようです。変更が少しでもあるたびに該当のブロック全体を再圧縮・ディスク書き込みとなるので、書き込み頻度が多いケースでは利用に向かないとされています。
上記は、MySQLの主要なDBエンジンであるInnoDBの場合ですが、Facebookが書き込み性能・圧縮成功率を更に高めたエンジンMyRocksというプロダクトがあります。今回のユースケースは書き込みそれなりに多いことが考えられるので、MyRocksの採用もありかなと考えていました。結果的には、Cassandra系なので、この部分は無駄になりましたが…(続く)

参考リンク)
InnoDB Pluginことはじめ
データ型のストレージ要件
DBでバイナリー型にSELECT実行
MyRocks

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です