エンジニアリング

7.7がもたらす進化 - Elasticsearchのヒープ領域使用量が大幅ダウン

Elasticsearchユーザーなら、1つのElasticsearchノードに格納できるデータ量の上限を押し上げるべく奮闘したことがあるかもしれません。その結果、ディスク容量が一杯になる以前にヒープ領域が不足することもあります。これは、ユーザーにとって頭の痛い問題です。1ノードあたりに割り当てるデータを可能な限り多くすることがコスト削減に有効であるケースが少なくないためです。

しかしそもそも、なぜElasticsearchはデータを格納するためにヒープ領域を必要とするのでしょうか。なぜディスク容量だけでは不十分なのでしょうか。これには複数の理由がありますが、最大の理由はLuceneがメモリに一部の情報を格納することにより、ディスクのどこを参照するか判断するためです。たとえばLuceneの転置インデックスは、用語をソート順にグループにわけて作ったブロック状の“用語ディクショナリー”と、用語ディクショナリーをすばやく参照するための“用語インデックス”で構成されています。この用語インデックスは用語の接頭辞をディスクのオフセットにマップし、そこにその接頭辞で始まる用語を含むブロックが作成されます。この用語ディクショナリーはディスク上にありますが、用語インデックスの方はつい最近までヒープ領域に置かれていました。

実際、インデックスに必要なメモリサイズはどれくらいでしょうか?通常は、インデックス1GBあたり数MB程度です。それほど大きいわけではありません。しかし、ノードに何テラバイトものディスクを装着した結果、数テラバイト分のインデックスの格納に占めるヒープ領域が10GBや10GBに達するケースも散見されます。Elasticはヒープを30GB未満に保つことを推奨していますが、その場合、アグリゲーションなどに消費するヒープ領域は少なくなります。また、JVMに十分なクラスター管理オペレーションの余地がない場合、安定性の問題にもつながります。

いくつか、実践的な数値を検討してみましょう。Elasticは複数のデータセットでナイトリーベンチマークを実行し、さまざまなメトリック、特にセグメントでのメモリ使用量を長時間にわたって追跡しています。そこで興味深い結果を示したのが、Geonamesデータセットです。Elasticsearch 7.xで導入された変更による影響を、明確に示しています。

Geonamesデータセットのナイトリーベンチマーク

このインデックスはディスク上で3GBを占め、6か月前は最大5.2MBのメモリを必要としていました。このヒープストレージ比は~1:600です。仮に各ノードに装着したディスクサイズの合計が10TBであれば、必要なヒープは10 TB ÷ 600 = 17GBとなり、Geonamesのようなデータを格納するインデックスをぎりぎり開くことができます。しかしグラフを見ると、時間とともに値が良くなっています。青の“points”が必要とするメモリ量が減り、次にピンクの“terms”、緑の“stored fields”、最後に再び“terms”の値が大きく下がっています。最終的にヒープストレージ比は~1:4000になり、6.xや7.xの初期リリースと比較しておよそ7倍近く向上しています。つまり、10TBのインデックスを開くために必要なヒープ領域はわずか2.5GBになります。

どの程度向上するかはデータセットによって大きく異なりますが、ここで嬉しいお知らせがあります。実はGeonamesはヒープ使用量の減少率を最も緩やかに示したデータセットの1つで、使用量は最大で7分の1に下がりました。他方、NYC taxisおよびHTTP logsデータセットでは、100分の1以下にまで使用量が下がっています。冒頭でも触れたように、この進化に伴い、Elasticsearchの以前のバージョンに比べて1ノードあたりに格納できるデータが増えれば、コスト削減に貢献します。

NYCタクシーのナイトリーベンチマーク

HTTPログデータセットのナイトリーベンチマーク

さて、どういう仕組みでこのような進化が起きたのでしょうか。何かデメリットを伴っているといったことはないのでしょうか?これと同じ変更は、Luceneインデックスの複数のコンポーネントに段階的に適用されてきました。すなわち、JVMヒープからディスクにデータストラクチャーを移行し、ファイルシステムキャッシュに依存する(ページキャッシュ、あるいはOSキャッシュとも呼ばれます)ことで使えるメモリの容量を残すという変更です。一見するとまだメモリは使用され、別のどこかに割り当てられているように思えますが、実際、ユースケースによってはメモリの大部分が一切使われなくなります。たとえば最後にTermsが大きく下がったのは、_idフィールドの用語インデックスをディスクに移動したためです。このフィールドはGET APIを使うとき、あるいは明白なIDでドキュメントをインデックスする場合しか役立ちません。Elasticsearchにログやメトリックをインデックスするユーザーの大多数は、こうした操作を一度も行いません。つまり、純粋にメリットだけをもたらす進化ということになります。

7.7で、Elasticsearchのヒープ使用量が下がる!

Elasticsearch 7.7より導入されるこの変更は私たちにとって非常にエキサイティングなものであり、ユーザーの皆さんにもそのように感じていただけましたら幸いです。ぜひ今後のリリース発表をチェックして、実際にお試しいただきたいと思います。現在お使いのデプロイでお試しいただくことも、Elastic CloudのElasticsearch Service(いつでも最新バージョンのElasticsearchが提供されます)で無料のトライアルを立ち上げることもできます。また、Elasticは皆さまからのフィードバックをお待ちしています。ぜひご意見をディスカッションフォーラムにお寄せください。