Taste of Tech Topics

Taste of Tech Topics

Acroquest Technology株式会社のエンジニアが書く技術ブログ

Elasticsearchの圧縮方式の比較

こんにちは。
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を用いてデータサイズを計測します。
f:id:acro-engineer:20180409003727p:plain

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)
投入処理については割愛します。
f:id:acro-engineer:20180409012135p:plain

同様に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などの技術を使ったり、データ分析機械学習などのスキルを活かしたい。
  • 社会貢献性の高いプロジェクトや、顧客の価値を創造するようなプロジェクトで、提案からリリースまで携わりたい。
  • 書籍・雑誌等の執筆や、対外的な勉強会の開催・参加を通した技術の発信、社内勉強会での技術情報共有により、エンジニアとして成長したい。