はじめに
本稿はサーバーワークスアドベントカレンダー7日目の投稿です
Amazon OpenSearch Serviceとは
Amazon OpenSearch Service(以下AOSと略します)は、OSSの検索・分析エンジンであるOpenSearchのマネージドサービスです。
多彩な機能があり、かつ他のAWSサービスとのインテグレーションパターンが豊富で外部からのデータの取り込みを非常にスムーズに実現できる特徴ももっており、一旦使いこなせるようになると何かと重宝するサービスです。
本連載の目的・内容
一方で、OpenSearch自体の学習コストが比較的高く、学習コンテンツもやや限られていることから、その辺りのとっつきづらさが導入のハードルとなっているケースも少なからず見受けられます。
特に鍵となるトピックの1つが「index(RDBでいうところのテーブル)の取り扱い」で、筆者も学びはじめの時に自分なりの見取り図をつくるのに苦労した記憶があります。
そこで本連載では、indexに関する設計業務・運用業務に焦点をおいて、主要な概念や関連機能群を網羅的に紹介することで、皆さんの学習コストを下げて円滑に導入・運用を進めていただくこと・AOS利用の裾野を少しでも広げることを目的としたいと思います。
補足
なお、このindexの運用について、通常のAOSからさらに運用上の手間を削減することができるAmazon OpenSearch Serverlessというサービスも今日では存在します。
こちらについてもぜひ紹介したいと思うのですが、通常のAOSの運用を多少理解していただいてからでないと その真価をつかみづらいサービスですので、便宜上連載の終盤に触れることにしたいと思います。
indexに関する基礎知識
まずは導入としてindexに関わる用語・機能について必要最小限触れておきたいと思います。
index・shard・document
OpenSearchではjson構造のデータ = documentを大量に管理することになります。 これらのdocument群の見かけ上の格納場所をindexと呼びます。
「見かけ上」と述べましたが、indexで管理されているdocument群は実際のところはshardという単位で分割されて保持されています。
shardを適切な数量に設定しておくことで、1つのマシンノードではなく複数のマシンノードで分担してdocument群を管理することができます。
複数のマシンノードでdocument群を管理することによって、可用性を向上するだけではなく、書き込み処理・検索処理を分担して担う余地が生まれます。
サーバーを増やしそれに応じてshardを増やせば増やすほど書き込み・検索性能についてもスケールアウトさせることができるというわけです。
AOSではドメイン(クラスタ)作成時に当該ドメイン固有のエンドポイントが払い出されますので、当該エンドポイントに対して特定indexへのdocument投入をリクエストすることで各shardへの保存処理が実施されます。
shardの種類
shardについてはprimary shardとreplica shardの2種類があります。文字通りprimary shardが大元のshardで、replica shardがその複製ということになります。primary shardは最低で1・replica shardは最低で0となります。
書き込み時の挙動としては以下の流れになります
- まずprimary shardに書き込みが行われる
- ついで(replica shard設定が1以上の場合で、かつ必要数分のノードが実際にある場合には)replica shardにデータ複製が実施される
上記のフローが示唆する通り、多量のdocumentを一度に投入することを考えた場合に書き込み性能を向上するに当たってはreplica shardの増加は効果がなくprimary shardの増加が必要です
むしろreplica shardが多いと複数のノードへの複製/書き込みが必要になり負荷が生じますから、初期構築等のタイミングでデータを大量に投入する際には一時的にreplicaを削減する処置をとる場合もあります
一方で、検索処理についてはprimary shardもreplica shardも同様に担うことができます。
のちの回のblogで詳述する機会があると思いますが、primary shardの増減よりもreplica shardの増減を図る方がはるかにオペレーション上のハードルが低いため検索性能の向上を考える場合、普通はreplica shardの増加により調整を行います。
運用上の主要な注意点
shardの管理
OpenSearchの運用で特に注意をしなければいけない点があります。それは、適正なパフォーマンスを保つためには「1shardあたりで管理するデータ容量」ないし「クラスタ内のshard数」を適正に保つ必要があるということです。
主に気を配る必要があるのは前者で、後者のshard数については、この連載で触れていくような適切な設計・運用をしていれば多くの場合普段気にかける必要はないのですが、一応どちらにも触れておくことにしましょう。
1shardあたりで管理するデータ容量
まず、各1shardで管理するデータ容量は、検索レイテンシを重視するワークロードでは10~30GiB程度、そうでない場合でも30~50GiB程度に収めることが適当とされています。
実はshardは単なる入れ物というわけではなく、それ自体で自身の保管するデータに関する検索スレッドを走らせたりキャッシュを持ったりする等、実は検索処理機構の一翼も担っています。
そのため各shardの維持には一定のCPU・メモリリソースが必要となるのです。1shardで管理するデータ容量が多すぎる場合は検索効率の劣化につながるばかりか障害時の復旧速度等にも影響が生じます。
対して、1shardで管理するデータ容量が少なすぎる場合については前者ほどの問題は生じませんが先に述べた事情(各shardの維持には一定のCPU・メモリリソースが必要)からマシンリソースを非効率に使用している状態とはいえます。
クラスタ内のshard数
また、ノードあたりのshard数も増え過ぎないようにすることが重要です。OpenSearchはJavaで動作していますが、Javaヒープ1GiBあたりのshard数を25以下で収めることが推奨されます。ここでいうshard数はprimary shardだけではなくreplica shardの個数も含めます。
OpenSearch Service は、インスタンスの RAM の半分を Java ヒープ(最大 32 GiB)として割り当てる仕様となっていますから、例えば16GiBのRAMを持つr6gd.large.searchタイプのインスタンスであれば1ノードあたり多くとも200個までに保管shardを収める必要があるということになります。
この理屈でいうとr6gd.16xlarge.searchのような極めて強力なスペックのインスタンスを複数台展開するようなクラスターであればshard数はあまり気にしなくてもいいのでしょうか。そういうことでもありません。
デフォルトで1ドメイン(OpenSearch Serviceの1クラスタの単位)につき1000しかshardは展開できない仕様となっています。この上限は引き上げられるのですが、AWSの推奨監視設定として30000を閾値として監視することが推奨されています。この30000という数字を一つの上限として考えておくのがよいでしょう。
ストレージの容量
ストレージ容量の管理にも注意が必要です。先ほど検索性能を増強するにはreplica shardを増強することが多い・・・と書きました。
では、検索性能を上げるために無計画にreplica shardを増やしても問題は生じないものでしょうか。答えはNoです。
まず、replica shardは増やせば増やすほど、そのindexで保管するデータ量が増えていくことに注意が要ります。
本稿の時点では「データの保持期間を可能なかぎり長くしたい」という要望と「検索性能を高く保ちたい」という要望とはなかなか相容れづらい微妙な関係にある・・・と指摘するにとどめておきます
(運用予算が潤沢にある場合は両立可能ですがそのような場合はあまり多くはありません・・・。おりあいをつける諸々のテクニックについては後続の連載で詳述したいと思います)
また、そもそもreplica shardを増やしたところでそれを実際に割り当てられるノード数を十分に確保していないと効力が発揮できないことにも留意する必要があります。
ノードを増やせば性能も上がりますが、やはり費用は上がってしまうというところで、この辺りの設計はお財布と相談しつつ検討する必要があります。
おわりに
いかがだったでしょうか。初回から「AOS、なんかめんどくさそうだなぁ」という印象を抱かせてしまったかもしれません。
ただ、適正なshard容量・ストレージ容量を維持するための運用作業は実はかなりの程度自動化できます。次回以降は、その「適正スペックを維持するための運用作業の種別」や「自動化」の仕組みについて何回かの記事に分けてフォーカスしていきたいと思います。