Amazon Elasticsearch Serviceクラスタ構成を対障害性の観点から検討してみる

Amazon Elasticsearch Serviceクラスタ構成を検討したので、そのメモを残しておきます。

※Elasticsearch Serviceの インスタンス ですが、資料によっては ノード と表記されています。この記事ではManagement Consoleの表記に合わせて インスタンス に統一して書きます。適当に読み替えて読んでください。

Amazon Elasticsearch Serviceの内部アーキテクチャ

まず、ElasticsearchのOSS部分をAWSがパッケージングして出している、Amazon Elasticsearch Serviceですが、実際にその中身はどうなっているのでしょう。それがわかる資料ですが、以下のスライドが端的に表現されていて、わかりやすかったです。

IAM認証とロードバランサがフロントにあって、リクエストがデータインスタンスに振り分けられる。クラスタを管理するマスターインスタンスが3台でクォーラム(Quorum)構成を取っている感じですね。今回は、このマスタインスタンスとデータインスタンスの構成を考えてみます。

Elasticsearch Serviceのインスタンスの種類

クラスタの構成を検討する前に、Elasticsearch Serviceのインスタンスの種類について簡単に書きます。一度、ウィザードを流してみると一発でわかるのですが、マスターインスタンスとデータインスタンスの2種類になります。

マスターインスタンス

クラスタへのインスタンスの参加や離脱の管理、クラスタのメタデータの管理、シャードの割当と再配置などクラスタ管理を行うインスタンス。3台、5台などでクォーラム(Quorum)構成を取ることが多いです。マスター昇格可能な候補インスタンスのことをMaster-eligible(適格)と呼んだりします。

専用マスターインスタンス

マスターインスタンスはデータインスタンスとも1台に役割の同居ができますが、負荷が高い場合は、クラスタの管理が不安定になってしまう場合があります。対策としてクラスタ管理専用の専用マスターインスタンスを立てることができます。専用マスターインスタンスはリクエストやクエリは処理しません。クラスタ管理を外出しすることでクラスタの安定性が増します。

Solr Cloud組んでた経験からすると、zookeeperみたいなもんだなと思いました。

https://docs.aws.amazon.com/ja_jp/elasticsearch-service/latest/developerguide/es-managedomains-dedicatedmasternodes.html

データインスタンス

少しわかりにくいかもですが、Amazon Elasticsearch Serviceにおいて設定可能なデータインスタンスは、ElasticsearchのDataロールと、Ingestロールの2つロールを兼務しています。

Dataロール

データの格納、クエリへの応答など

Ingestロール

データの変換や加工のようなETLのような前処理をElasticsearch側に実装できます。こちらの記事を見るとわかりやすいです。

https://dev.classmethod.jp/server-side/elasticsearch/elasticsearch-ingest-node/

確認方法

以下のようにRoleの種類を確認できます。

この場合、di となっているのが dataingest ロールをもつデータインスタンス、m となっているのが専用マスターインスタンスです。

マスターインスタンスとデータインスタンスの役割を同居させると mdi と表記されるようになります。

GET _cat/nodes?v&h=ip,name,role&pretty

ip            name                             role
x.x.x.x  2ad600a844abc013e8aff77d809eac3f di
x.x.x.x 6193f0acdc6a19253c5bcbf2a53e178a m
x.x.x.x 5795984143d7cd2ebcacdb10d30cf3e8 m
x.x.x.x  48037c42512aa22cf2af2b0055af54c8 di
x.x.x.x d2bf51a5557fa06088b5201ac9966e54 m

正確には上記で m となっているのはマスターと Master-eligible の2種類があります。実際に選出されているマスターは以下のように取得できます。

GET _cat/master?v

id                     host          ip            node
5LWXJfm5TuaUutE06kF2_g x.x.x.x x.x.x.x 6193f0acdc6a19253c5bcbf2a53e178a

クラスタ構成例

ここまで理解した上でいくつかの構成例を挙げます。

f:id:yomon8:20191108002636p:plain

マスター・データ共存インスタンス シングル

f:id:yomon8:20191108002349p:plain

1インスタンスで構成。マスターインスタンスとデータインスタンスの役割が同居します。当然障害があればサービスダウン。ダウンによるデータロストはしない場合もあるみたいですが、サポートにも確認したところ、基本的にデータはロストすると考えて設計した方が良さそうです。最新のスナップショットからリストアになります。

最近のElasticsearch Serviceは、自動的に1時間毎でスナップショットがS3に取得されるので、1時間分くらいのデータロストに耐えられる開発環境などならあり。

最新のElasticsearchのバージョンの場合は、最小構成でt2.small.elasticsearchで5,000円弱で利用可能。t2インスタンスはディスクの暗号化がサポートされていないので注意です。

マスター・データ共存インスタンス × 3

f:id:yomon8:20191108002428p:plain

マスタインスタンスとデータインスタンスの両方の役割を持ったインスタンスを3台並べてクラスタを組んでいます。3AZに分散すればAZ障害にも耐えられます。データインスタンスが高負荷になるとマスタの役割が不安定になるので、大きな処理や大量のインデックスには向いてない構成です。処理自体は重くないけど、冗長性は保ちたいとかの用途には向いていると思います。

単一インスタンス障害時

3台のデータインスタンスがマスターを兼ねるので、Quorum の計算が可能。自動でインスタンス復旧、レプリカ等のデータが正しく再配置される。(ユーザ側の作業は発生しない)

※専用マスターを置く場合と比較してクラスタ管理機能がワークロードの影響を受けやすく、動作不安定になる場合がある

複数インスタンス同時障害時

シングルインスタンスと同じ。毎時取得されているスナップショットからリストアが必要。最終スナップショット取得後に更新されたデータはロスト。

専用マスターインスタンス x 3 & データインスタンス x N

f:id:yomon8:20191108002447p:plain

専用マスターインスタンスを用意することで、データインスタンスが行うインデクシング、クエリリクエストの処理などと、クラスタ管理を分離することで、安定したクラスタ運用が可能になります。ただ最低でも5~6台のインスタンスが必要になるので、一番高額にはなります。

データインスタンス障害時

残ったインスタンスにレプリカが存在していれば、マスターにより再配置が行われ、自動復旧。インデックスのデータが全て消失した場合はスナップショットからのリストア。

データインスタンス、マスターインスタンス共に3AZに分散すればAZ障害にも耐えられます。

単一のマスターインスタンス障害時

Quorum の計算が可能。自動でインスタンス復旧。

複数のマスターインスタンス同時障害時

マスターインスタンスはデータを保持していないため、クラスターにダウンタイムが発生するもののデータロストは発生しない(マスターインスタンス復旧後にクラスターは復旧)  

  

ここに挙げたのはあくまでも構成例になります。専用マスターインスタンス5台にすれば、2台の同時障害にも耐えられるなど、上を目指せばもっと大きな構成も組めるし、データインスタンスのスケールアウトも容易なのが良いところです。

最後に重要

ここまで理解した上で以下を読めば、対障害性の観点からの構成は考えられるのではないでしょうか。

aws.amazon.com