こんにちは。
2年目エンジニアのノムラです。
普段はElasticStackを用いた分析基盤の開発等を行っています。
Elasticsearchを使っているとストレージの使用量を節約したいと思う方は多いのではないでしょうか。
Elasticsearchはデータを格納するときにデフォルトでLZ4という圧縮方式でデータ圧縮を行っていますが、
実はLZ4よりも圧縮率の高いbest_compressionという圧縮方式を利用することもできます。
このbest_compressionは圧縮率が高い分、検索時にはLZ4よりも遅くなると言われるのですが、
実際にどれくらいデータサイズに違いがあるのか、検索速度の違いはどれくらいになるのかが
実はよく分かりません。
ということで今回はこの2つの圧縮方式のデータサイズと検索速度への影響を比較してみました。
目次は以下になります
環境情報
OS: Amazon Linux release 2.0 (2017.12) LTS Release Candidate
インスタンスタイプ: t2.2xlarge
ディスクサイズ: 30gb
バージョン情報
elasticsearch 6.2.2
kibana 6.2.2
logstash 6.2.2
準備
今回はapacheログを用いて比較を実施します。
比較のためのデータは apache-loggenを使って1000万件のデータ(2.2gb)を作成しました。
appache-loggenのURLは以下
github.com
データは以下のような形式です。
160.87.30.197 - - [05/Jan/2018:15:01:07 +0900] "GET /category/music HTTP/1.1" 200 113 "/item/finance/777" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11"
検証のための準備は以下となります。
1.インデックステンプレートの適用
今回は1ノードでの検証になるため、シャード数を1にレプリカ数を0に設定します
curl -XPUT -u user:pass 'localhost:9200/_template/tmpl_00_shard?pretty' -H 'Content-Type: application/json' -d' { "index_patterns": "*", "settings": { "index": { "number_of_shards": "1", "number_of_replicas": "0" } } } '
2.LZ4形式のデータ投入
lz4_sampleインデックスにLZ4形式(デフォルト形式)でデータを投入します
$cat apache_logs | bin/logstash -f apache_lz4.conf
apache_lz4.confの設定は以下です。
input{ stdin{} } filter{ grok { match => [ "message", "%{COMBINEDAPACHELOG}" ] } } output{ stdout{ codec => dots } elasticsearch{ hosts => localhost index => "lz4_sample" user => "user" password => "pass" } }
3. best_compression形式のデータ投入
APIを用いてbest_compression_sampleインデックスの圧縮方式をbest_compressionに設定します
curl -XPUT -u user:pass 'localhost:9200/best_compression_example?pretty' -H 'Content-Type: application/json' -d' { "settings": { "index.codec": "best_compression" } } '
best_compression_sampleインデックスにbest_compression形式でデータを投入します
$cat apache_logs | bin/logstash -f apache_best_compression.conf
apache_best_compression.confの設定は以下
input{ stdin{} } filter{ grok { match => [ "message", "%{COMBINEDAPACHELOG}" ] } } output{ stdout{ codec => dots } elasticsearch{ hosts => localhost index => "best_compression_sample" user => "user" password => "pass" } }
4.投入されたデータの確認
curl -XGET ‘localhost:9200/lz4_sample/_search
以下の様なデータが投入されていることが確認できます。(best_compression_sampleでも同様です)
{ "took" : 23, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 10310974, "max_score" : 1.0, "hits" : [ { "_index" : "lz4_sample", "_type" : "doc", "_id" : "PsXqDmEBl8mqXpdfS3ci", "_score" : 1.0, "_source" : { "request" : "/category/software", "agent" : "\"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)\"", "auth" : "-", "ident" : "-", "verb" : "GET", "message" : "104.129.152.199 - - [05/Jan/2018:14:56:46 +0900] \"GET /category/software HTTP/1.1\" 200 63 \"/search/?c=Sports+Computers\" \"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)\"\r", "referrer" : "\"/search/?c=Sports+Computers\"", "@timestamp" : "2018-01-19T14:54:46.064Z", "response" : "200", "bytes" : "63", "clientip" : "104.129.152.199", "@version" : "1", "host" : "HOGE", "httpversion" : "1.1", "timestamp" : "05/Jan/2018:14:56:46 +0900" } }, (略) ] } }
データサイズの比較
KibanaのDevToolsからCAT APIを用いてデータサイズを計測します。
best_compression形式で圧縮されたデータの方が、LZ4形式で圧縮されたデータと比較してデータサイズが16%程小さくなっています。
検索速度の比較
KibanaのDevToolsを用いて、検索速度を計測します。
計測はlz4_sampleインデックス、best_compression_sampleインデックスそれぞれ10回ずつ実施しました。
検索クエリは以下
# lz4 GET lz4_sample/_search { "size": 10000, "query": { "match_all": {} } }
# best_compression GET best_compression_sample/_search { "size": 10000, "query": { "match_all": {} } }
結果は以下
圧縮方式 | 平均 | 最大 | 最小 |
---|---|---|---|
LZ4 | 1.14s | 1.53s | 0.87s |
best_compression | 1.86s | 2.11s | 1.61s |
best_compression形式で圧縮されたデータに対する検索速度は、LZ4形式と比較すると163%と遅くなりました。
データの解凍が遅い分検索処理にも時間がかかっているようです。
LZ4とbest_compressionのデータが両方存在する場合
ここで、実際の利用シーンではLZ4形式とbest_compression形式、両方の形式で圧縮されたデータに跨って、検索するシーンが考えられます。
単純に考えれば、検索対象のドキュメント数が同じ場合、検索速度はLZ4形式のみの検索速度と、best_compression形式のデータのみの検索速度の間になりそうです。
そちらも検証してみました。
そこで、先ほどのデータとは別に、ドキュメント数は同じで、LZ4形式とbest_compression形式が半分ずつになるようにデータを投入しました。(データサイズ:計4.2gb)
投入処理については割愛します。
同様にKibanaのDevToolsを用いて、検索速度を計測します。
検索クエリは以下
# 混合 GET apache_*/_search { "size": 10000, "query": { "match_all": {} } }
結果は以下のようになりました。
圧縮方式 | 平均 | 最大 | 最小 |
---|---|---|---|
LZ4 | 1.14s | 1.53s | 0.87s |
混合 | 1.38s | 1.49s | 1.28s |
best_compression | 1.86s | 2.11s | 1.61s |
予想通り、混合したデータに対する検索速度はLZ4形式とbest_compression形式、それぞれの形式の間の値になりました。
まとめ
LZ4とbest_compressionのデータサイズと検索速度への影響の違いは以下のようになります。
圧縮方式 | 元データ | LZ4 | 混合 | best_compression |
---|---|---|---|---|
データサイズ | 2.2 gb | 4.6gb | 4.2gb | 3.9gb |
検索速度 | - | 1.14s | 1.38s | 1.86s |
今回はapacheログを用いて圧縮形式の比較を行いました。
他のデータの場合にはまた状況が違ってくると思いますが、一つの例として参考になれば嬉しいです。
それでは!
Acroquest Technologyでは、キャリア採用を行っています。
- データ分析(Elasticsearch、Python関連)、ビッグデータ(Hadoop/Spark、NoSQL)、Web開発(SpringCloud/SpringBoot、AngularJS)といった最新のOSSを利用する開発プロジェクトに関わりたい。
- マイクロサービス、DevOpsなどの技術を使ったり、データ分析、機械学習などのスキルを活かしたい。
- 社会貢献性の高いプロジェクトや、顧客の価値を創造するようなプロジェクトで、提案からリリースまで携わりたい。
- 書籍・雑誌等の執筆や、対外的な勉強会の開催・参加を通した技術の発信、社内勉強会での技術情報共有により、エンジニアとして成長したい。