Amazon OpenSearch Service の Cross-cluster replication

# クロスクラスタレプリケーションしてみる

基本はこちらの[ドキュメント](https://docs.aws.amazon.com/opensearch-service/latest/developerguide/replication.html)に全部書いてあります。こちらやってみた記事です。

## 概要説明

左側のレプリの元になるクラスタをリーダーと呼ぶ。右側のレプリケーション先をフォロワーと呼ぶ
図では、リーダードメイン"demo-repli1"のインデックス"test1_index"を、フォロワードメイン"demo-repli2"のインデックス"rep_test1_index"にレプリケーションしている

![名称未設定ファイル-ページ1.drawio (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27932/f1643b7d-3f13-7286-dc97-4ca3b3a253f9.png)

だが、実際はフォロワーからPULLする方式になる。そのため、以下の図のように示すと、この後に説明する"接続"設定や"アクセスポリシー"設定や"レプリコマンド"実行が、どちらのドメインで実行するかがスッと分かりやすい
アクセスポリシーの設定はレプリのアクセスを受ける左側のリーダーだよとか、レプリスタートはPULLをする右側のフォロワーだよとか
[公式Doc](https://docs.aws.amazon.com/opensearch-service/latest/developerguide/replication.html)から引用
>It follows an active-passive replication model where the follower index (where the data is replicated) pulls data from the leader index.

[OpenSearch Doc](https://opensearch.org/docs/latest/replication-plugin/get-started/)

>Cross-cluster replication follows a “pull” model, so most changes occur on the follower cluster, not the leader cluster.

![名称未設定ファイル-ページ2.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27932/c6ca9637-c61c-d39c-3ba8-22d78ffceb03.png)


## 注意点

* 前提条件
  * 2021/10/28現在は、Elasticsearch7.10のみだった
  * 同じメジャーバージョンを共有するか、最終的なマイナーバージョンと次のメジャーバージョンを共有する必要があります
  * M3およびT2はだめ
  * きめ細かいアクセス制御が有効
  * ノード間暗号化が有効
  * AWSCloudFormationを使用してドメインを接続することはできません
  * The user names must be identical.
  * フォロワーのIndexはリードオンリーになります。[参考リンク](https://opensearch.org/docs/latest/replication-plugin/get-started/)

## 事前準備

#### ドメイン2つ作成

* demo-repli01(リーダー), demo-repli02(フォロワー)
* AES v7.10, 1台, r5.large.search
* マスタユーザーを事前に作成(両方のクラスタで同じ名前にしておく)

#### リーダードメインのアクセスポリシーに以下を追加

リージョンは東京リージョン。AWSアカウントIDは"123456789012"としてる

```json:
xxx
xxx
xxx
,
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": "es:ESHttp*",
      "Resource": "arn:aws:es:ap-northeast-1:123456789012:domain/demo-repli01/*"
    },
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": "es:ESCrossClusterGet",
      "Resource": "arn:aws:es:ap-northeast-1:123456789012:domain/demo-repli01"
    }
```

#### リーダードメインに書き込みテスト

以後、操作はKibanaのDevTools
POSTしたものをGETで確認

![スクリーンショット 0003-10-29 15.02.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27932/2282590d-f2b4-3a3f-fc30-732381beaa64.png)

```json:
POST /test1_index/tmp_type/
{
  "group": "sales",
  "users": [
    {
      "first_name": "Taro",
      "last_name": "Kimura"
    },
    {
      "first_name": "Jiro",
      "last_name": "Maeda"
    }
  ]
}

GET test1_index/tmp_type/_search
{"query": {"match": { "users.first_name":"taro"}}}

```

## レプリケーション設定

#### 接続

* フォロワードメイン"demo-repli02"のマネコン画面から、[接続]タブをクリックし[リクエスト]をクリックする。

![スクリーンショット 0003-10-29 15.05.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27932/afb2f0ce-b485-8726-55f6-5c696e0f43c9.png)

* 接続エイリアスに"demo-repli"を入力し、送信先クラスターのドメインに"demo-repli01"を選択して、[リクエスト]をクリックする

![スクリーンショット 0003-10-29 15.07.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27932/f93695cf-2053-36ec-1123-1fd5736cc48b.png)

* リーダードメインの[接続]タブをクリックしてリクエストの確認をする。"インバウンド接続"の箇所にフォロワードメイン"demo-repli02"が表示されステータスが「保留中の承認」となっている。これにチェックを入れて右上の[承認]をクリックする。

![スクリーンショット 0003-10-29 15.10.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27932/c887cfea-e597-4a18-8fb7-f122c802fd72.png)

* ステータスが「承認済」になる

![スクリーンショット 0003-10-29 15.13.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27932/a0eb6b39-5aed-0efe-f809-2417342c73f8.png)

* フォロワードメイン側も承認されたことでステータスが「アクティブ」になる

![スクリーンショット 0003-10-29 15.14.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27932/8538d3ce-5116-223e-8054-1f086142ea24.png)

#### レプリケーションスタート

* フォロワードメインで、"_plugins/_replication/xxx/_start"でレプリスタート。フォロワードメイン側で行うことに注意。PULL型なのでフォロワー側を起点にレプリスタートする。
  * ※ use_rolesの権限は今回テストのためall_accessにしてますが、必要に応じて絞りましょう

![スクリーンショット 0003-10-29 15.18.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27932/ab2a5538-014c-d8b3-a366-645410532b4b.png)

* フォロワー側でレプリしてきたインデックス(rep_test1_index)はこの段階で作成されている。(既存のインデックスをフォロワーインデックスに変換することはできない)

![スクリーンショット 0003-10-29 15.41.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27932/407451d6-931a-47b2-5653-383c97c3f529.png)

* "_plugins/_replication/xxx/_status"でレプリの状態確認。statusがsyncingなので良さそう

![スクリーンショット 0003-10-29 15.19.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27932/11d4da25-1cdd-3429-02b5-9f3e02076181.png)

* searchしてみる。事前に書き込んだkimura taroさんがヒットした。レプリスタート前のデータもレプリしてくれることが分かる

![スクリーンショット 0003-10-29 15.24.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27932/df79fac1-a4f4-51ff-8f53-738f65a0a5d7.png)


```json:
PUT _plugins/_replication/rep_test1_index/_start
{
   "leader_alias": "demo-repli",
   "leader_index": "test1_index",
   "use_roles":{
      "leader_cluster_role": "all_access",
      "follower_cluster_role": "all_access"
   }
}

GET _cat/indices/rep_test1_index


GET _plugins/_replication/rep_test1_index/_status


GET rep_test1_index/test_type/_search
{"query": {"match": { "users.first_name":"taro"}}}

```

* リーダードメインで新規書き込み(uehara shingoを書き込み)してみる。もちろんリーダードメインではsearch出来る

![スクリーンショット 0003-10-29 15.28.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27932/8d846de6-1f85-befe-5ebe-331c145cd4a5.png)

* フォロワードメインでsearchするとヒットした。レプリ出来てる

![スクリーンショット 0003-10-29 15.29.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27932/e7e87cc8-39ed-1e7f-9cb4-57c040942bf8.png)

```json:
POST /test1_index/tmp_type/
{
  "group": "sales",
  "users": [
    {
      "first_name": "shingo",
      "last_name": "uehara"
    }
  ]
}

GET test1_index/tmp_type/_search
{"query": {"match": { "users.first_name":"shingo"}}}
```

#### フォロワー側でレプリしてるIndexに書き込んでみた

失敗。リードオンリーのようです。

![スクリーンショット 0003-10-29 17.35.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27932/f698780d-47aa-f8a7-314a-59f2e5e97cf8.png)


## その他レプリ操作

* status:ステータスチェック
* pause：一時停止
* resume：一時停止からの再開
* stop：完全停止

STOPは注意が必要で、フォロワーインデックスはリーダーのフォローを解除し、リードオンリーから書き込み可能な標準インデックスになります。レプリケーションを停止した後、レプリケーションを再開することはできません

PauseしてStatus確認してみる
(注意)「12時間以上一時停止した後は、レプリケーションを再開できないことに注意してください」らしい。[参考Doc](https://opensearch.org/docs/latest/replication-plugin/get-started/)

![スクリーンショット 0003-10-29 15.37.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27932/e3035d74-e402-99e3-5d1b-819280900c0a.png)


```json:
GET _plugins/_replication/rep_test1_index/_status

POST _plugins/_replication/rep_test1_index/_pause
{}

POST _plugins/_replication/rep_test1_index/_resume
{}

POST _plugins/_replication/rep_test1_index/_stop
{}
```

#### 他にも操作いくつかあります

opensearchのドキュメントにいろいろあります。stats系でいろいろ情報取れそうですね
https://opensearch.org/docs/latest/replication-plugin/api/

>Start replication
Stop replication
Pause replication
Resume replication
Get replication status
Get leader cluster stats
Get follower cluster stats
Get auto-follow stats
Update settings
Create replication rule
Delete replication rule

![スクリーンショット 0003-10-29 19.17.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27932/79558c21-0cfb-f45f-5341-624db357a9c0.png)


## その他機能

Auto-followという機能でreplication ruleを作り、ルールに記述したパターンにマッチしたインデックスを自動でレプリ出来る

>指定されたパターンに一致するインデックスを自動的に複製する単一のリーダードメインに対して一連の複製ルールを定義できます。 パターンの1つ（books* とか）に一致するリーダードメインにインデックスを作成すると、一致するフォロワーインデックスがフォロワードメインに作成されます。 OpenSearch Serviceは、パターンに一致する新しいインデックスを複製しますが、以前に作成したインデックスは複製しません。


# 公式ドキュメント

* What's New
https://aws.amazon.com/jp/about-aws/whats-new/2021/10/amazon-opensearch-service-amazon-elasticsearch-service-cross-cluster-replication/

* Amazon OpenSearch Service Doc
https://docs.aws.amazon.com/opensearch-service/latest/developerguide/replication.html

* OpenSearch Doc
https://opensearch.org/docs/latest/replication-plugin/get-started/