[AWS] Elasticsearch Serviceの自分まとめ

# 前置き

- これは AWS の Elasticsearch についてまとめた記事
- 公式ドキュメントから重要そうな部分を抜粋してるだけの記事

# 機能

- 多数のインスタンスタイプによりスケールさせることが可能
- 最大３PBのストレージ
- コンスとパフォーマンスに優れた UltraWarm ストレージ

# 料金

- 選択しているインスタンスタイプの1時間あたり料金
    - 可動しているノード数分掛け算された料金
- EBSストレージの累積サイズに応じた料金

# ドメイン

- Elasticsearchクラスターと同義
- ドメインは指定した設定、インスタンスタイプ、インスタンス数、およびストレージリソースを含むクラスター

## ドメイン管理

### 設定変更

- もろもろの設定変更によりBlue/Greenデプロイが発生する
    - [参照](https://docs.aws.amazon.com/ja_jp/elasticsearch-service/latest/developerguide/es-managedomains.html#es-managedomains-configuration-changes)
- Blue/Greenデプロイが発生しない
    - アクセスポリシーの変更
    - 自動スナップショットの時間の変更
    - ドメインに専用マスターノードがある場合、データインスタンス数の変更

### サービスソフトウェア更新

- 機能追加やドメイン強化のためのリリースが定期的に実施される
- 更新は任意のタイミングで実施することもできる
- 任意更新をしない場合特定の期間が経過すると自動的に更新される
    - いつ、何時に更新されるか分からない
    - プロダクション環境の更新の場合はトラフィックの少ない、または停止した状態で任意更新するのがいいかと

### CloudWatchでの監視

- [各種メトリクス情報](https://docs.aws.amazon.com/ja_jp/elasticsearch-service/latest/developerguide/es-managedomains.html#es-managedomains-cloudwatchmetrics)

### マルチAZドメイン

- 同じリージョン内の2つまたは3つのAzにノードを分散することができる
    - これを `マルチAZ` と呼ぶ！！！！！！！！！！！
- 3つのAZをサポートするリージョンを選ぶことをおすすめ
    - Tokyo は勿論対象だよ♪
- 3つのAZにドメインをデプロイする
- 専用マスターノード、データノードに現行世代のインスタンスタイプを選択
- 3つの専用マスターノードと少なくとも３つのデータノードを使用
- クラスター内のインデックス毎に少なくとも1つのレプリカを作成

#### シャード分散

- マルチAZの場合、クラスターの各インデックスには少なくとも1つのレプリカが必要
- レプリカがないとESはデータのコピーを他のAZに分散できない、マルチAZの意味ないじゃ〜ん
- 全てのインデックスはデフォルトで1つのレプリカが作成される

#### AZの中断

- 発生することはほとんど無いが、起こりえます（迫真）
- [中断時の動作](https://docs.aws.amazon.com/ja_jp/elasticsearch-service/latest/developerguide/es-managedomains.html#es-managedomains-za-summary)

# スナップショット

- スナップショットはクラスターの指数と状態のバックアップです
    - `なんやねんクラスターの指数って`
- 状態は、クラスター設定、ノード情報、インデックス設定、シャード割当などが含まれる

## 自動スナップショット

- クラスター復元専用
- 赤のクラスター状態、またはその他のデータ損失が発生した場合にドメインを復元できる
    - `赤のクラスター状態とは`
- 追加料金なしで取得可能で事前設定したS3に保存する
- Elasticsearchのバージョンにより取得頻度が異なる
    - `5.3以降` : 1時間毎、最大336個を14日間
    - `5.1以前` : 1日毎、14個を30日間
- 赤のクラスター状態となった場合自動スナップショットの作成を停止する
    - `2週間以内に問題を解決しない場合永遠にデータを失うことになる` （こわっ）
- [赤のクラスター状態](https://docs.aws.amazon.com/ja_jp/elasticsearch-service/latest/developerguide/aes-handling-errors.html#aes-handling-errors-red-cluster-status)

## 手動スナップショット

- クラスターの復元、クラスター間でのデータ移行に使用する
- そのなの通り手動で取得する必要がある
    - 言い換えれば自動ではないってこと > 何言ってんだ
- 自動と同様にS3に保存される
- [手動スナップショット取得前提条件](https://docs.aws.amazon.com/ja_jp/elasticsearch-service/latest/developerguide/es-managedomains-snapshots.html)

# スナップショットからの復元

## 自動スナップショット

- [自動スナップショットからの復元](https://dev.classmethod.jp/cloud/aws/amazon-elasticsearch-service-restore-from-automatic-snapshot/)

### 作業内容

1. リカバリ対象のドメインの自動スナップショットを確認する
2. 既存インデックスを全て削除する
3. 自動スナップショットを使用してリカバリする
4. 疎通確認を行う

#### 1. リカバリ対象のドメインの自動スナップショットを確認する

1. AWSコンソール -> Elasticsearch を開く
2. 復元対象のドメインを選択する
3. KibanaのURLをクリックする
4. サイドメニュー「Dev Tools」を選択
5. 自動スナップショット一覧を取得
   1. `GET _snapshot/cs-automated/_all`
6. スナップショット一覧が取得されることを確認
   1. 基本的に1時間毎にスナップショット取得してるので1つも無いってことは無いはず

#### 2. 既存インデックスを全て削除する

- 既存インデックスが存在しているスナップショットからの復元ができないため削除する

1. KibanaのDev Toolsを開く
2. 既存のインデックス一覧が表示される
   1. `GET _cat/indices` を実行
3. 既存インデックスを全て削除する
   1. `DELETE *`
4. インデックスが削除されていることを確認する
   1. `GET _cat/indices` を実行

#### 3. 自動スナップショットを使用してリカバリする

1. KibanaのDev Toolsを開く
2. 自動スナップショット一覧を取得
   1. `GET _snapshot/cs-automated/_all`
3. 一覧の中から復元するスナップショットのIDをひかえる
   1. `"snapshot":` がそれにあたる
4. スナップショットから復元する
   1. `POST /_snapshot/cs-automated/[snapshot]/_restore` を実行
5. インデックスが復元されていることを確認する
   1. `GET _cat/indices` を実行
6. AWSコンソール -> Elasticasech を開く
3. 対象ドメインの「Elasticsearch クラスターの状態」が「緑」または「黄色」であるか確認する
   1. 「緑」「黄色」であればリカバリ完了している状態


## 手動スナップショット

- [手動スナップショットからの復元](https://docs.aws.amazon.com/ja_jp/elasticsearch-service/latest/developerguide/es-managedomains-snapshots.html#es-managedomains-snapshot-prerequisites)

# 全般的なリファレンス

## サポートされるインスタンスタイプ

- 一部インスタンスタイプはElasticsearchのバージョン条件がある
- [インスタンスタイプ](https://docs.aws.amazon.com/ja_jp/elasticsearch-service/latest/developerguide/aes-supported-instance-types.html)
- マスターノード、データノードは異なるインスタンスタイプを使用することが可能

## Elasticsearchバージョン別の機能

- [バージョン別の機能](https://docs.aws.amazon.com/ja_jp/elasticsearch-service/latest/developerguide/aes-features-by-version.html)

# ベストプラクティス

- 本番稼働用ドメインは以下ページの各項目に準拠してることが望ましいみたい
    - [ベストプラクティス](https://docs.aws.amazon.com/ja_jp/elasticsearch-service/latest/developerguide/aes-bp.html)

## ドメインのサイジング

## 専用マスターノード

- [専用マスターノード](https://docs.aws.amazon.com/ja_jp/elasticsearch-service/latest/developerguide/es-managedomains-dedicatedmasternodes.html)
- クラスターの安定性を向上するために専用マスタノードを使用するのが望ましい
- 専用マスターノードはクラスター管理タスクの実行をするがデータは保持しない
    - データアップロードリクエストにも応答しない
    - クラスター管理タスクに全振りしたのがマスターノード
- 本番運用では「3つのマスターノード」を割り当てるのが望ましい
    - 1つだと障害発生時にバックアップが取れない
    - 2つだと障害発生時に新しいマスターノードを選択するためのクォーラムがクラスターにない
        - クォーラムは `専用マスターノードの数/2 + 1 (直近の整数まで切り捨て) ` で計算される
        - 2つだと1つマスターノードが障害あると `1/2 + 1 = 1.5 = 1` となりクォーラムが無い状態となり新しいマスターの選択ができない
    - [クォーラムとは](https://qiita.com/everpeace/items/632831371da5ff215995)
- マスターノードのインスタンスタイプは、管理可能なインスタンス、インデックス、シャード数と相関関係にある
    - 大きなインスタンスタイプほど管理できる数が増える

## 推奨CloudWatchアラーム

# トラブルシューティング

## 赤のクラスター状態

- 少なくとも1つのプライマリシャードとそのレプリカしがノードに割当られていないことを意味する
- 赤いクラスター状態が続く限り正常なインデックスの場合でも自動スナップショットの取得を停止する
    - 14日間以上赤のクラスター状態が続くと自動スナップショットを失うことになるので要注意

### 原因

- 一般的な原因は、クラスターノード障害と継続的な高負荷によるプロセスのクラッシュ
- 最終的に、赤のシャードにより赤のクラスターが発生し、赤のインデックスにより赤のシャードが発生する

### 解決

- 赤のクラスター状態の原因となっているインデックスを識別するための方法が用意されている
- 未割り当てインデックスの識別
    - `GET /_cluster/allocation/explain`
- インデックスの状態を表示
    - `GET /_cat/indices?v`
- 赤のインデックスを削除することが赤のクラスター状態を修正するための最速の方法

#### インデックス削除が不可能な場合

- スナップショットを復元する、インデックスからドキュメントを削除する、インデックスの設定を変更する、レプリカの数を減らす、または他のインデックスを削除してディスク領域を解放する
- 重要なステップは、Amazon ES ドメインを再設定する前に、赤のクラスター状態を解決する
- 赤のクラスター状態のドメインを再設定すると、問題が複雑化し、状態を解決するまで、設定状態が [Processing (処理中)] のままドメインがスタックする可能性がある

## 黄色のクラスター状態

- 全てのプライマリシャードがクラスター内のノードに割り当てられ、少なくとも1つのインデックスのレプリカシャードは割り当てられていない状態
    - 1ノードしかないドメインは基本的に黄色のクラスター状態ってこと
- 緑のクラスター状態とするにはノード数を増やす必要がある

## クラスターノードの障害

- ESの基盤となるEC2は予期しないタイミングで終了と再起動を実施する
- その場合通常はノードの再起動が実施される
- ただしクラスターの1つ以上のノードが失敗した状態となることがある
- 設定したクラスターのノード数よりも少ない状態の場合はAWSサポートへ問い合わせる