Elastic Cloud Serverlessは、検索負荷に基づいてインデックスのレプリカ数を自動的に調整し、手動設定なしで最適なクエリパフォーマンスを確保します。このブログでは、レプリカのスケーリング方法、システムがレプリカを追加または削除するタイミング、そしてこれがインデックスに与える影響について説明します。
パーティーは混雑してきています
ピザパーティーを開催する予定だとします。数人の友人が配膳を手伝ってくれていて、ピザは部屋のあちこちに配置されています。あなたは友人一人ひとりにピザを渡し、友人たちは到着する空腹の客にピザを一切れずつ配り始めます。
最初は順調です。数人の客がぽつぽつとやって来て、友達が一切れずつ配ってくれて、みんな幸せそうです。しかし、あなたのサワードウピザの評判が広まると、ドアベルが鳴り続け、ゲストが次々と押し寄せるようになります。すぐに、ペパロニピザを持っている友人の周りに人だかりができ始めます。どうやら皆がそのピザを欲しがっているようです。
ペパロニピザを持ったあなたの友人は、圧倒されています。ゲストは待たされて苛立ち、長い列ができています。一方、マルゲリータピザを持った友人は、誰にも興味を持たれず、ただ突っ立っているだけでした。
さて、どうすればよいでしょうか?
あなたはさらに数枚のペパロニピザを注文し、他の友人に渡します。1人ではなく3人の友人がペパロニピザを持つようになりました。ゲストが分散すれば、一度に3倍ものゲストに対応できるようになります。
パーティーを開催するうちに、いくつかのことが明らかになります。
- すべてのピザが同じように人気なわけではない。需要が高いものもあれば、需要が少ないものもあります。人気のないものの「コピー」を余分に用意する必要はありません。行列ができているタイプのものを余分に用意する必要があります。
- 行列が長くなる前にピザを追加注文する。友人が完全に手に負えなくなり、ゲストが怒って帰ってしまうまで待つようでは、待ちすぎです。人だかりができているのを見たら、ピザを追加で注文するほうがよいでしょう。
- ピザをすぐに捨ててはいけない。ペパロニピザの人だかりが5分ほどまばらになったからといって、混雑が終わったわけではありません。飲み物を補充しているだけかもしれませんし、あるいは単におしゃべりしているだけかもしれません(今でもそういうことがあるかは別にして)。予備のピザを用意しておいてください。しばらく静かな状態が続くようなら、よけておいても構いません。
- 手伝ってくれる友達の数だけピザを配れる。手伝ってくれる友達が4人しかいない場合は、ピザを10枚配っても結果は変わりません。一度に提供できるピザは4枚だけです。ピザの枚数と手伝いの人数を合わせてください。
- 友達が持ち場を離れるときは、その友達のピザの担当を代わる。友達の誰かが外出する必要があったら、すぐにその友達のピザを引き継ぎます。ピザを放置しておくことはできません。誰かに渡すか、しまっておきます。
ピザからレプリカへ
これをElasticsearchに当てはめて考えてみましょう。
この例えでは、ピザはレプリカ(インデックスシャードのコピー)、配膳を手伝ってくれる友人は検索ノード、お腹を空かせたゲストは検索クエリ、そして人だかりができている人気のピザは、検索負荷の高いホットインデックスに相当します。
特定のインデックスに対する検索トラフィックが増加すると、追加のレプリカを作成し、それらを検索ノード全体に分散させます。任意のレプリカは、そのインデックスに対して任意のクエリを処理できます。これは、ペパロニを持っている友人がペパロニの一切れを配るのと同じです。レプリカが多いほどスループットも高くなります。3つのレプリカは、1つのレプリカの3倍のクエリを処理できます。
空腹感の測定
ピザを何枚注文するかを決める前に、参加者の空腹度を把握する必要があります。
Elasticsearchはすべてのシャードの検索負荷を追跡します。これは、シャードが処理している検索アクティビティの量を示す指標です。検索需要全体を把握するために、インデックスのすべてのシャードにわたってこれを集計します。
最も重要なのは相対的な検索負荷です。これは、プロジェクトの総検索トラフィックのうち、各インデックスにどれだけの割合がヒットしているかを指します。あるインデックスが全検索の60%を受け取っている一方で、別のインデックスが5%を受け取っている場合、どこにキャパシティを追加すべきかがわかります。
ピザに隠された数学的な背景
最適なレプリカ数は次の式に従って計算します。
定義:
- L = インデックスの相対的な検索負荷(0~1の間)。
- N = プロジェクト内で必要な検索ノードの数。
- S = インデックス内のシャード数。
- X = ホットスポットを回避するためのしきい値(デフォルト値:0.5)。
例として、4つの検索ノード、1つのインデックス、2つのプライマリシャードが検索トラフィックの80%を受け取る場合、以下のようになります。
このホットインデックスは検索ノードに分散された4つのレプリカを取得します。
しきい値X(デフォルト値は0.5)は重要です。レプリカシステムが完全に処理能力を超えるまで待つのではなく、半分の処理能力に達した時点で規模を拡大します。余ったピザは、客が帰り始めてからではなく、人だかりができ始めた時に配りましょう。
素早くスケールアップし、ゆっくりとスケールダウン
検索負荷が増えたら、すぐにレプリカを追加します。ユーザーを待たせる理由はありません。
検索負荷が落ちたら、少し待ってからアクションを取ります。レプリカを減らす前に、約30分間需要が安定して低い状態になることを確認する必要があります。(これは、交通量が急激に変動する状況に対処するためのもので、一時的に交通量が減ったからといって、パーティーが終わったわけではないからです。)
レプリカを追加するにはコストがかかるため、これは重要な点です。新しいレプリカは、クエリを効率的に処理する前に、データをコピーし、キャッシュを準備します。レプリカを性急に削除すると、トラフィックが自然に変動するたびに、この初期費用を継続的に支払うことになります。
トポロジー境界を尊重
レプリカは検索ノードの数を超えてはなりません。レプリカの数をノードの数より多くしても何のメリットもありません(ピザを配るのを手伝ってくれる友人の数だけしかピザを配ることができないからです)。
プロジェクトからノードが削除されたら、レプリカ数を即座に削減して一致させます。割り当てられていないレプリカは存在できないため、クールダウンを待つ必要はありません。友人が席を外した瞬間にそのピザを引き継ぎます。
サーバーレスの全体像
レプリカによる検索負荷分散は、他の自動スケーリングシステムと共に機能します。
- 検索自動スケーリングは検索ノードの数を調整します(協力する友人の数)。
- 検索負荷分散のためのレプリカは、インデックスごとのレプリカ数を調整することでトラフィックを分散します(各種のピザが何枚必要かを示すようなものです)。
- データストリームの自動シャード化は書き込みのシャード数を最適化します(各ピザをどのようにカットするかについては前回の投稿をご覧ください)。
重要な設計原則:負荷分散のためのレプリカは、検索の自動スケーリングを直接トリガーしません。その代わりに、検索リクエストをより多くのレプリカに分散させることで、検索ノード全体のリソース利用率を高めることができます。利用率の上昇に伴い、必要に応じて既存の自動スケーリングロジックが作動し、容量が追加されます。負荷分散のためのレプリカを使用することで、自動スケーリングが本来の役割を果たせるようになり、他のノードがアイドル状態になっている間にすべてのトラフィックが単一のレプリカに集中するのではなく、検索ノードが実際に使用されるようになります。
防御側への示唆
どのインデックスが人気になるかを予測する必要はありません。トラフィックパターンが変わってもレプリカを手動で調整する必要はありません。最も取引量の多いインデックスが急激なアクセス集中で処理能力を超えたからといって、午前3時に起きる必要はありません。
システムは、行列ができる場所を監視し、それらのスポットではさらにピザを注文します。コールドインデックスは不要なレプリカにリソースを浪費しません。ホットインデックスは必要な容量を取得します。予算は重要なところに使われます。
まとめ
オートシャーディングに関する記事では、ピザを正しくカットする方法を説明しました。検索のロードバランシングのためのレプリカにより、空腹の群衆が到着した際に、適切な人に十分なピザが行き渡るようにできます。
Elastic Cloud Serverlessを試して、ピザの配送は当社にお任せください。




