Amazon OpenSearch Service の Elasticsearch を OpenSearch へ移行してみた

2021.12.16

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

プロフィールビューアーサービスProflly(プロフリー)の開発にて、Amazon Elasticsearch Service で Elasticsearch を利用していたのですが、Amazon OpenSearch Service となり、OpenSearch を利用することができるようになったので、移行することにしました。
本記事では、その移行方法について、紹介させていただきます。

移行について

移行前の Elasticsearch は、AWS CDK を利用してドメインを構築していました。ですので、OpenSearch へ移行後も AWS CDK を利用した構成のままとしたいと思います。移行方法については既存のスタックをアップデートをする方法もありますが、今回は OpenSearch のスタックを新規で作成し、接続先を Elasticsearch スタックから OpenSearch スタックに切り替える手法を取ることにしました。

詳細な対応については記載を省略しますが、おおまかな移行方法としては以下の通り進めました。

  1. OpenSearch スタックを新規作成
  2. 既存の処理(Lambda 等)の向き先(エンドポイント)を OpenSearch に向けるように実装を修正
  3. デプロイ
  4. Elasticsearch から OpenSearch へデータを移行
  5. Elasticsearch スタックを削除

OpenSearch スタックを新規作成

まずはこちらのモジュールを使って、OpenSearch Service スタックを作成します。 基本的には Elasticsearch スタックをベースに作成しましたが、主な変更点としては、version の指定や capacity.dataNodes などの値を変更しました。

import * as opensearch from "@aws-cdk/aws-opensearchservice";
...
    const domain = new opensearch.Domain(this, this.resourceName.esDomainName("os-domain"), {
      version: opensearch.EngineVersion.OPENSEARCH_1_0,
      capacity: {
        dataNodes: "r6g.large.search",
...

既存の処理(Lambda 等)の向き先(エンドポイント)を OpenSearch に向けるように実装を修正

Proflly(プロフリー)では、Elasticsearch へのアクセスは、主に Lambda を利用しています。Lambda から Elasticsearch へアクセスする際は、環境変数に Elasticsearch へのエンドポイントを設定しておき、そのエンドポイントを使ってアクセスしています。 このエンドポイントを Elasticsearch から OpenSearch に変更しました。 なお、エンドポイントについては、SSM ParameterStore から OpenSearch のエンドポイント取得し、デプロイ時に環境変数に設定されるように実装を修正しました。

デプロイ

デプロイ対象の環境に対して、デプロイします。デプロイについては特に考慮せず、いつものデプロイフローで各スタックをデプロイしました。デプロイが完了した段階では、Elasticsearch スタックと OpenSearch スタックが共存した状態となります。

Elasticsearch から OpenSearch へデータを移行

デプロイが完了してから、Elasticsearch から OpenSearch へデータを移行します。データ移行の方法はいくつかありますが、今回は elasticdump を利用することにしました。 データ移行の際は、事前に OpenSearch にインデックスを作成し、その作成したインデックスに対して elasticdump を利用してデータを移行していきます。

まずは、OpenSearch Dashboards の Dev Tools を利用して、インデックスを作成します。

PUT /my-index1
{
  "settings": {
    "index": {
      ...
    },
    "analysis": {
      "char_filter": {
        ...
      },
      "filter" : {
        ...
      },
      "tokenizer": {
        ...
      },
      "analyzer": {
        ...
      }
    }
  },
  "mappings": {
    "properties": {
      "my_id": {
        "type": "keyword"
      },
      "my_name": {
        "type": "keyword"
      },
      ...
    }
  }
}

PUT /my-index2
{
...
}

続いて、作成したインデックスにデータを移行します。elasticdump コマンド実行時は、Elasticsearch, OpenSearch にアクセス可能なロールを利用して実行しました。接続情報は、事前に環境変数に設定してからコマンドを実行します。移行対象のインデックスが複数ある場合は、移行対象のインデックス数分、移行コマンドを実行します。

# Elasticsearch のエンドポイント
SOURCE_HOST=https://XXX.ap-northeast-1.es.amazonaws.com
# OpenSearch のエンドポイント
DEST_HOST=https://YYY.ap-northeast-1.es.amazonaws.com

# Elasticsearch のインデックス名
SOURCE_INDEX=my-indexXXX
# OpenSearch のインデックス名
DEST_INDEX=my-index1

elasticdump --input=$SOURCE_HOST/$SOURCE_INDEX --output=$DEST_HOST/$DEST_INDEX --type=data \
--awsAccessKeyId=$AWS_ACCESS_KEY_ID \
--awsSecretAccessKey=$AWS_SECRET_ACCESS_KEY \
--sessionToken=$AWS_SESSION_TOKEN

SOURCE_INDEX=my-indexYYY
DEST_INDEX=my-index2
...

Elasticsearch スタックを削除

データ移行まで完了したら、Elasticsearch スタックを利用する用途がないので、スタックを削除します。削除の際は、CDK の実装上から削除しておかないと、次回のデプロイ時に Elasticsearch ドメインが構築されて、起動されていたということも起こり得るので注意が必要です。 また、スタックを削除しても DeletionPolicy の設定によっては Elasticsearch ドメインが削除され無いこともあるので、しっかりと確認することをおすすめします。

これで OpenSearch への移行は完了したので、動作確認をして問題なければ、移行完了です。
お疲れさまでしたー!!

さいごに

OpenSearch への移行方法の1つの案を紹介させていただきました。プロダクトのアーキテクチャやデプロイフローなどによって、検討するべきことが多くあると思います。 いろいろな移行方法がある中の、手段の1つとして、どなたかの参考になれば幸いです。

参考