Elasticsearchのシャードとレプリカ設計のベストプラクティス:クラスター最適化のための実践ガイド
本記事は、2020年11月27日にObjectRocket.com/blogで公開された記事をもとに翻訳・編集したものです。
Elasticsearch®は、デフォルト設定でもクラスタ全体へデータを効率よく分散できる優れた検索エンジンです。しかし、クラスタが成長していくと、デフォルト設定のままではパフォーマンスやリソース効率が最適ではなくなることがあります。本記事では、シャーディングの基礎をおさらいしながら、インデックスとシャードに関するベストプラクティスを詳しく解説します。
Elasticsearchにおけるシャーディングの基礎知識
シャーディングとは、データを複数の小さな断片(シャード)に分割し、検索処理を並列に実行できるようにする仕組みです。クラスタリングやインデックス操作の並列化を実現するために、Elasticsearchでは各インデックスを番号付きの断片に分割します。この断片こそが「シャード」です。
シャードには以下のような重要な特性があります。
- レプリカ数の設定に応じて、各シャードは自動的に複製されます。たとえばレプリカ数が「1」の場合、各シャードには2つのコピーが存在することになります。1つはプライマリシャード、もう1つはレプリカシャードです。プライマリシャードは
indexing/write(書き込み)とsearch/read(読み取り)の両方を担当し、レプリカシャードは読み取り処理と、プライマリ障害発生時の復旧用途に使われます。 - レプリカシャードは、必ず元となるプライマリシャードとは別のホスト上に配置されます。
- デフォルトでは、シャードはクラスタ内のホスト数に応じて自動的に分散配置されます。ただし、同一の物理ホストに複数のプライマリシャードが割り当てられる場合もあります。この挙動はリバランシングやシャードアロケーションなどの設定で変更可能ですが、詳細は本記事の範囲外とします。
- シャードは分割できないため、必ず単一のホスト上にのみ存在します。
- シャード数はインデックス作成時に指定するか、グローバルデフォルト値を使用します。インデックス作成後にシャード数を変更するには再インデックスが必要なので注意しましょう。
- 一方、レプリカ数もインデックス作成時に指定できますが、こちらはインデックス作成後でも変更可能です。
具体例:3シャード×1レプリカの場合
簡単な例を見てみましょう。シャード数3、レプリカ数1でインデックスを作成すると、Elasticsearchは合計6つのシャードを生成します。すなわち、3つのプライマリシャード(Ap、Bp、Cp)と3つのレプリカシャード(Ar、Br、Cr)です。
Elasticsearchは、レプリカとプライマリが異なるホストに配置されることを保証しますが、複数のプライマリシャードが同じホストに割り当てられることはあります。それでは、シャードはどのようにホストへ割り当てられるのでしょうか。次のセクションで詳しく見ていきます。
シャードアロケーションの仕組み
デフォルトでは、Elasticsearchは利用可能なすべてのホストに対してシャードを分散配置しようとします。Rackspace ObjectRocketの構成では、各クラスタはマスターノード、クライアントノード、データノードで構成されており、そのうちデータノードがシャードの割り当て先(いわば「バケット」)となります。
先ほどの6つのシャードを、最小構成である2つのデータノードを持つObjectRocket for Elasticsearchクラスタに割り当ててみます。各シャードについて、プライマリは片方のデータノードに配置され、レプリカは必ずもう片方のノードに配置されます。なお、ここで示すのはあくまで一例であり、実際の配置はこれ以外にもあり得ます。確実に言えるのは、「レプリカは必ずそのプライマリとは別のデータノードに配置される」という点だけです。
次に、この例に3つ目のデータノードを追加してみます。すると、2つのシャードが新しいデータノードへ移動し、結果として各ノードに2つのシャードが配置されることになります。
さらに、このクラスタに「シャード数2・レプリカ数2」の新しいインデックスを追加してみましょう。これにより、2つの新しいプライマリ(Xp、Yp)と4つのレプリカ(Xr0、Xr1、Yr0、Yr1)が生成され、クラスタ全体に分散配置されます。
避けるべき落とし穴
Elasticsearchは面倒な作業の多くを自動的に処理してくれますが、運用において避けるべき落とし穴がいくつか存在します。
落とし穴①:巨大すぎるインデックスと巨大すぎるシャード
巨大なシャードを持つ巨大なインデックスのトラブルシューティングは、Elasticsearch運用において比較的対策しやすい問題の一つです。最初は扱いやすいサイズだった単一のインデックスも、アプリケーションの成長とともに肥大化していきます。シャードサイズはクラスタ内のデータ量に直接比例するため、結果として巨大なシャードが生まれてしまいます。
この状態が引き起こす問題は主に2つあります。
1つ目は、クラスタリソース利用率の低下です。シャードが大きくなるほど、データノードへの配置が難しくなります。シャードを格納するには大きな空き領域が必要になるため、ノードに未使用の無駄なスペースが残りがちになります。たとえば、8GBのデータノードに6GBのシャードがある場合、各ノードに2GBずつ遊休容量が残ってしまうのです。
2つ目は「ホットスポット」の発生です。データを少数のシャードに集約していると、複雑なクエリを多数のノードに分散して並列実行できなくなります。
インデックスをケチらない
遊休スペースの問題を解決するには、複数のインデックスを使いましょう。データを複数のインデックスに分散させることで、クラスタ内のシャード数を増やし、データを均等に配置できます。テトリスにたとえるなら、小さめのピースの方が隙間なく詰めやすいのと同じ理屈です。さらに、Elasticsearchのエイリアス機能を使えば、アプリケーション側からは複数のインデックスをあたかも1つのインデックスのように扱えます。
Elastic Stackの多くのコンポーネントは、デフォルトで日次インデックスを作成しますが、これは良いプラクティスです。日次インデックスにしておけば、エイリアスで検索範囲を特定の日付区間に限定したり、Curatorで古いインデックスを削除したり、データの増加に応じてインデックス設定を変更したりすることが、古いデータの再インデックスなしに行えます。
インデックスサイズの増加に合わせてシャード数を増やす
インデックスの作成頻度を高め、インデックスの成長に合わせてシャード数を増やすのも有効です。シャードサイズが目標値を超え始めたら、インデックステンプレート(または新規インデックス作成に使用している仕組み)を更新して、以降のインデックスにより多くのシャードを持たせましょう。ただし、この方法は新規インデックスを頻繁に作成している場合にしか効果がないため、優先度は前述の「複数インデックス活用」の次とします。そうでなければ、シャード数変更のために再インデックスが必要になり、複数インデックスを管理する手間より大きな負担になってしまうからです。
私たちの経験則として、シャードがデータノードサイズの40%を超える場合は大きすぎると判断しています。その場合は、より多くのシャードを持つインデックスへの再インデックス、あるいはより大容量のプラン(データノードあたりの容量増加)への移行を推奨します。
落とし穴②:多すぎるインデックスと多すぎるシャード
逆の極端、つまりインデックスやシャードが多すぎるケースも問題です。「じゃあ、ドキュメントごとに個別のインデックスを作って、100万個のシャードを作ればいいんだね」と考えたくなるかもしれません。しかし、インデックスやシャードにはオーバーヘッドが伴います。そのオーバーヘッドは、ストレージ消費、メモリリソース、処理パフォーマンスに現れます。
クラスタはすべてのシャードの状態と配置場所を維持し続けなければならないため、シャード数が膨大になるとその管理(ブックキーピング)コストが増大し、メモリ使用量に影響します。また、クエリをより細かく分散する必要があるため、クエリのscatter/gather(分散・収集)フェーズに要する時間も大幅に増加します。この問題の許容範囲はクラスタサイズやユースケースなどに大きく依存しますが、一般的には以下の推奨事項で緩和できます。
シャードは50GB以内に抑える
一般的に、大型シャードの理想的なサイズは25GB程度とされ、50GBを超えたら再インデックスを検討すべきです。これはシャード自体のパフォーマンスだけでなく、必要に応じたシャード移動のしやすさにも関係します。リバランシング時には、シャードをクラスタ内の別ノードへ移動させますが、50GBものデータ転送には時間がかかりすぎ、移動中は2つのノードがその処理に拘束されてしまうのです。
シャードサイズをデータノード容量の40%未満に保つ
前述のとおり、注目すべき2つ目の指標は「シャードがデータノード容量に占める割合」です。Rackspace ObjectRocketでは、データノードのストレージ量に応じた複数のプランサイズを提供しており、最大のシャードでもデータノード容量の40%を超えないよう、クラスタとシャードのサイジングを行っています。さまざまなサイズのインデックスが混在するクラスタでは、この基準はかなり有効です。ただし、少数の巨大インデックスしかないクラスタでは、さらに厳しく30%未満を目標にしています。
理想としては、データノードに遊休容量を残さないことです。たとえばシャードがデータノードの約45%のサイズだとすると、そのシャードを配置するにはデータノードの使用率が半分程度でなければなりません。これはかなりの無駄な予備容量です。
まとめ
適切なシャード数とインデックス設定を選ぶのは簡単ではありませんが、事前に計画を立て、初期段階で良い判断を下し、運用しながらチューニングを続ければ、クラスタを健全かつ最適な状態に保つことができます。私たちは企業様のElasticsearch環境の改善を常々サポートしています。
Rackspace DBA Servicesの詳細については、ぜひお問い合わせください。フィードバックタブからコメントやご質問をお寄せいただくことも、Sales Chatから今すぐチャットを始めることも可能です。
-
Windows 10・8・7対応!おすすめダウンロードマネージャー5選
映画、音楽、テレビ番組、ソフトウェアなど、インターネット上にはダウンロードできるコンテンツが数多く存在します。通信速度の向上とデータプランの低価格化により、コンテンツをダウンロードして楽しむユーザーがますます増えています。お気に入りの映画があるなら、ストリーミング再生でデータ容量を消費するよりも、ダウンロードしてドライブに保存しておく方が賢い選択といえるでしょう。 しかし、大容量ファイルのダウンロードには長い時間がかかることがあります。さらに厄介なのは、途中でインターネット接続が切断されると、それまでダウンロードしたデータが失われ、最初からやり直しになってしまう点です。 こうした問題を一挙に解
-
知って得する!Googleの隠れた裏技・トリック10選
実は、Googleには数多くの隠されたトリックや秘密機能が搭載されていることをご存じでしょうか?信じられないかもしれませんが、これは本当の話です。私たちは独自性があり魅力的なさまざまなトリックを調査し、実際にすべて試してみました。この記事では、あなたがまだ知らないかもしれない、Googleの隠れた秘密・裏技ベスト10をご紹介します! 1. Google Gravity(グーグルグラビティ) Google Gravityは、Googleが提供する遊び心あふれる機能の一つです。名前の通り「重力」をテーマにしたもので、学校で習った重力の定義をここで改めて説明する必要はないでしょう。この仮想世界で、