はじめに
こんにちは、検索基盤部 検索基盤ブロックの可児(@KanixT)とSRE部 ECプラットフォーム基盤SREブロックの大澤です。
本記事では、ZOZOTOWNの商品検索で利用しているElasticsearchをバージョンアップした知見と、その際に実施した検索基盤の改善についてご紹介します。
背景
ZOZOTOWNでは商品の検索エンジンとして、Elastic社が提供するElastic Cloudを利用しています。公式サポートの恩恵を受けるためElasticsearchのEOLに気を遣う必要がありました。Elasticプロダクトのサポート期限は、一般公開日(GA)から18か月と定義されており、弊社で利用しているElasticsearchの期限も迫っていました。ZOZOで実施したバージョンアップ、およびバージョンアップのタイミングに合わせて実施した検索基盤の改善について、知見をご紹介します。
なお現在は8.xがリリースされていますが、作業当時の最新は7.xだったため7.10.xからのマイナーバージョンアップについての知見となります。
バージョンアップの流れ
Elasticsearchをバージョンアップするタイミングに合わせて、LTRプラグインの独自ビルド廃止やクラスタのコード管理化など、以前からチーム内で課題感のあった点も改善しています。作業は以下の流れで進めました。
なおバージョンアップに関して、当初はRolling upgradeによる更新を検討していました。しかし検索機能で利用しているindexはドキュメントの更新が常時動いており、Rolling Upgradeで失敗した際にデータの復旧が難しくなり、リスクが高いと判断しました。そのため別クラスタに新しいバージョンのElasticsearchを構築し、切替えを行う方針を採用しました。
主な作業
新バージョンのMappingやQueryなどの調査
Javaクライアント
- LTRプラグインのバージョンアップにともなうJavaのバージョンアップ
- Elasticsearchクラスタのコード管理化
IaC方法の選択
TerraformによるIaC化
負荷試験の実施方法
インスタンスタイプ検証結果
サービスイン試験結果
別クラスタに新しいバージョンのElasticsearchを構築
新旧の両クラスタに対してのインデクシング
- 各種サービスの参照を旧クラスタから新クラスタへ切替え
- 旧クラスタの削除
変更箇所の調査
新バージョンのMappingやQueryなどの調査
バージョンアップの事前準備としてまずはMigration guideを確認し、利用予定の新バージョンまでにリリースされた機能でMappingやQueryに影響がある変更を一通り確認しました。
次にアップデートターゲットとなるバージョンのElasticsearchを新クラスタに検証目的で構築しました。その環境で現在動作している検索クエリとインデキシングを実行します。Deprecation logsを有効にすると非推奨のElasticsearchの機能を確認できるため、その方法についてご紹介します。
なお、今回のバージョンアップでは検索クエリとインデクシングの両方でクエリ修正は1件もありませんでした。
Deprecation logsが有効になっていることの確認
Kibana Dev Toolsを使用して下記リクエストを実行し、Deprecation logsの設定を確認します。詳細はDeprecation logsの公式ページをご覧ください。
GET /_cluster/settings?include_defaults&filter_path=defaults.cluster.deprecation_indexing
実行結果は次のようになり、"deprecation_indexing.enabled" : "true" の場合に非推奨のログが出力されます。
{
"defaults" : {
"cluster" : {
"deprecation_indexing" : {
"enabled" : "true",
"x_opaque_id_used" : {
"enabled" : "true"
}
}
}
}
}
Deprecation logsの有効が確認できましたので試しにログを出力し、出力内容を確認します。
非推奨のログメッセージを確認するため、Elasticsearch 7.16.0の環境にて、バージョン7.0で廃止されたタイプ(type)を利用します。
バージョン7.16.0でタイプ(type)を利用
次のPUTクエリを実行し、廃止されたタイプ(type)を利用します。
PUT /corp/employee/1
{
"first_name" : "hakoneko",
"last_name" : "max",
"age" : 25
}
実行結果のレスポンスはこちらです。タイプ(type)を廃止した旨のワーニングが表示されました。
#! [types removal] Specifying types in document index requests is deprecated, use the typeless endpoints instead (/{index}/_doc/{id}, /{index}/_doc, or /{index}/_create/{id}).
{
"_index" : "corp",
"_type" : "employee",
"_id" : "1",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1
}
次にDeprecation logに出力された内容を確認します。ログを検索するクエリはこちらです。
GET .logs-deprecation.elasticsearch-default/_search
{
"size": 1,
"sort": [
{
"@timestamp": {
"order": "desc"
}
}
]
}
検索結果のレスポンスはこちらです。
{
"_index" : ".ds-.logs-deprecation.elasticsearch-default-2022.05.19-000006",
"_type" : "_doc",
"_id" : "tZ9Q8YAB8Tww7jHGnFO2",
"_score" : null,
"_source" : {
"event.dataset" : "deprecation.elasticsearch",
"@timestamp" : "2022-05-23T14:27:11,423Z",
"log.level" : "CRITICAL",
"log.logger" : "org.elasticsearch.deprecation.rest.action.document.RestIndexAction",
"elasticsearch.cluster.name" : "es-docker-cluster",
"elasticsearch.cluster.uuid" : "********************",
"elasticsearch.node.id" : ""********************",",
"elasticsearch.node.name" : "elasticsearch",
"trace.id" : "",
"message" : "[types removal] Specifying types in document index requests is deprecated, use the typeless endpoints instead (/{index}/_doc/{id}, /{index}/_doc, or /{index}/_create/{id}).",
"data_stream.type" : "logs",
"data_stream.dataset" : "deprecation.elasticsearch",
"data_stream.namespace" : "default",
"ecs.version" : "1.7",
"elasticsearch.event.category" : "types",
"event.code" : "index_with_types",
"elasticsearch.http.request.x_opaque_id" : ""
}
PUTクエリのワーニングと同じように、タイプ(type)を廃止した旨のワーニングが表示されました。このように非推奨の機能が確認可能なため、バージョンアップの際は是非ご利用ください。
Javaクライアント
ZOZOTOWNの商品検索API(Spring Boot)は、Elasticsearchへ接続するクライアントに下記テックブログで紹介している通り、High Level Rest Client(以下、HLRC)を使用しています。
しかしながらHLRCは7.15.0で非推奨になり、新たなJava API Clientがリリースされました。そのため今回のバージョンアップ作業として、新Java API Clientに移行するかを移行ドキュメントと検索クエリのドキュメントで確認し検討しました。ドキュメントから実装方法が大きく異なっていることを確認したため、改修にはある程度の期間が必要であると想定出来ました。そのためEOLの迫っている現状での対応は見送ることとしました。新Java API Clientを利用することで得られる恩恵は少なからずあると思うので早めの移行したいと思います。
続きはこちら