Sansan Tech Blog

Sansanのものづくりを支えるメンバーの技術やデザイン、プロダクトマネジメントの情報を発信

Eightの検索機能をCloudSearchからOpenSearchに移行して得たもの

こんにちは!技術本部Eight Engineering Unitでサーバーサイドエンジニアをしている常盤です。 名刺アプリ「Eight」では最近、検索機能のうち2つをAmazon CloudSearchからAmazon OpenSearch Serviceに移行しました。今回は、移行した背景やそのメリットを紹介します。

Eightに存在する検索機能

Eightのシステム内には以下のように多数の検索システムが存在しており、その多くがCloudSearchを利用していました。

機能 説明 検索エンジン
所有名刺検索 ユーザー個人が所有する名刺情報を検索する OpenSearch
共有名刺検索 Eight Teamで共有した名刺を検索する CloudSearch
ネットワーク検索 Eight上のユーザーを検索する CloudSearch
企業検索 Eight上の企業を検索する CloudSearch
ECD候補者検索 採用サービスECDでスカウトできるEightユーザーを検索する OpenSearch
学校名検索 Eightのプロフィール(学歴)に登録できる学校を検索する CloudSearch

CloudSearchの課題点

Amazon CloudSearchは2012年にリリースされたフルマネージドの検索システムです。Apache Solrをベースに作られています。CloudSearchは(旧Amazon Elasticsearch Serviceがリリースされた)2015年頃からはあまり機能追加がされておらず、先日ついに新規のAWSアカウントからは利用を停止しOpenSearch Serviceへの移行を推奨するアナウンスが行われました。(ちょうど弊チームが移行作業を開始した1カ月後くらいでした)

CloudSearchで構築された検索システムには、今となっては以下のような課題が生じてきていました。 (注:すべてあくまで現在のOpenSearch / Elasticsearchと比較した場合の話です)

  • ドキュメントや社内外のノウハウが少ないため、開発スピードが低くなりやすい
  • テキストの正規化 (日本語文字や記号など)のオプションが充実しておらず、表記揺れなどによるミスヒットが生じやすい
  • クエリやスコアリングの表現力に限度があるので、細かなチューニングを行いづらい
  • N-gramによるトークナイズをする際に原則Bigram(2文字区切り)しか指定できない
  • 4バイト文字に対応していない
  • 結果整合性のため、実装に注意が必要なシーンがある(OpenSearchも同様だがrefreshオプションで多少コントロール可能)
  • リザーブドインスタンスを利用したコスト削減ができない
  • etc...

そしてこの度Web版Eightのリニューアルにより検索機能に大規模な機能追加を行うことが決まったタイミングで、重要機能である「共有名刺検索」と「ネットワーク検索」をOpenSearch Serviceに移行することで開発効率や検索精度の向上を試みました。

buildersbox.corp-sansan.com

OpenSearchへの移行手順

移行のためざっくりどのような作業を行ったかご紹介します。

インデックスとクエリの移行

インデックスの定義方法やクエリはCloudSearchとは全く異なるため、同じ検索体験になるように移行する必要があります。

インデックスの移行で助かったこととしては、OpenSearchではテキストの正規化機能が非常に充実しており、ほとんどsettingsのみで完結できるということです。 移行前は、多くの正規化処理を都度Rubyで実行してからCloudSearchに保存していました。

インデックス設定の例

{
  "index": {
    "analysis": {
      "filter": {
        "my_to_katakana_filter": {
          "type": "icu_transform",
          "id": "Hiragana-Katakana" # ひらがな・カタカナの正規化
        }
      },
      "analyzer": {
        "ngram_analyzer": {
          "char_filter": [
            "remove_whitespace", # 空白の除去 (↓で手動で設定)
            "my_variation_char_filter", # 異体字の正規化 (↓で手動でマッピングを設定)
            "icu_normalizer" # 半角全角や大文字小文字などUnicode関連のさまざまな正規化をしてくれる
          ],
          "filter": [
            "my_to_katakana_filter"
          ],
          "type": "custom",
          "tokenizer": "ngram_tokenizer"
        },
        # ...中略
      },
      "tokenizer": {
        # ...中略
      },
      "char_filter": {
        "remove_whitespace": {
          "type": "pattern_replace",
          "pattern": "[\\s\\p{Zs}]+",
          "replacement": ""
        },
        "my_variation_char_filter": {
          "type": "mapping",
          "mappings": [
            "髙 => 高","﨑 => 崎", # ...中略
          ]
        }
      }
    }
  }
}

クエリに関しても、特殊な記法が必要なCloudSearchとは異なりJSONで表現できますし、多様なオプションによって検索条件を細かくチューニングできます。

データの移行

検索エンジンに格納するデータはRDB(Aurora MySQL)のデータを正としてそこから複製する設計にしています。データの移行に当たってはRDBのデータをOpenSearchのインデックスに同期する処理を実装し、データ件数や検索結果が問題ないことを慎重に確認した上でリリースしました。 OpenSearchへの検索データの同期処理は以前おこなったECDの検索機能にElasticsearchを導入した際と同じような設計を採用し、SQSを通じた非同期処理でOpenSearchドキュメントの作成・更新・削除を行うようにしました。

楽観ロックを利用して個人情報を安全に扱う

Eightのシステムでは名刺情報やユーザー情報のような機密性の高い個人情報をお預かりしています。特に、ユーザーがEight上から削除したはずの個人情報がOpenSearchには残存していた、といったような事象は絶対に防ぐ必要があります。OpenSearchのような、RDBほど整合性を保証するための仕組みが充実していないデータストアでは注意深い実装が必要になります。

OpenSearchには楽観ロックの機能が存在するため、それにより基本的には整合性を保証する実装を行えます。 しかしながら、同じドキュメントの作成・削除が連続して発生するケースでは注意が必要になります。 例えばあるドキュメントに対して 作成 => 削除 の順でジョブがエンキューされたが、ワーカー側で 削除 => 作成 の順で実行された場合、削除済みのドキュメントに対しては楽観ロックを行うことができません。そのため、タイミングによっては削除したはずのドキュメントが消えずに残ってしまうリスクがあります。

この問題にはジョブの実行順序を保証するなどいくつかの対策が考えられます。私たちのチームでは「ドキュメントを削除するのではなく、idと削除フラグのみにした状態でしばらくの間インデックス内に残す」という方法により確実に楽観ロックを行えるようにしました。これによりRDBとの間で確実に整合性を維持できています。

OpenSearchへの移行により得たメリット

共有名刺検索機能とネットワーク検索機能のOpenSearchへの移行により、以下のような多くのメリットを得られました。

1. 豊富なドキュメント・ノウハウによる開発スピードの向上

OpenSearch / Elasticsearchは社内外の情報が非常に充実しているため、機能改善をスピーディに行えるようになりました。

2. 検索精度の向上によるユーザビリティの改善

正規化処理やクエリの利便性が向上したことにより、CloudSearch時代に発生していたいくつかの問題が解消されました。例えば、空白や記号が含まれるとヒットしない、1文字単位で正しくヒットしないといった問題がありました。

3. AWS費用の大幅な削減

移行にあわせて構成を見直したことと、OpenSearch Serviceではリザーブドインスタンスが利用できることから、最終的に費用の 45%($15,000/年!)程度を削減できました。

4. 今後の機能改善余地の拡大

OpenSearchにはCloudSearchと比較してさまざまなチューニングの選択肢があり、機能も日々アップデートされています。それにより今後さらにEightユーザーの利便性向上を行っていける状態になりました。(ECDにおける精度チューニングの事例

デメリット

私たちのユースケースでは、CloudSearchからOpenSearchへの移行によるデメリットは特に感じませんでした。唯一あるとすれば、OpenSearch Serviceへの移行によりオートスケーリング機能は利用できなくなります。とはいえクラスタに十分なリソースを与えれば問題なく運用できていますし、余裕がなくなってきた場合はブルー/グリーンデプロイにより無停止でリソースの拡張が可能です。

OpenSearch Serverless であればオートスケーリングを行ってくれますが、OpenSearch Serviceと比較すると一部の機能などに制限があるので目的に応じて使い分けるのが良さそうです。

最後に

CloudSearchはマネージドな検索システムを容易に構築できる点がメリットで、Eightは実に10年近くその恩恵を受けてきています。OpenSearch Serviceへの移行により、そのメリットをほとんど保ったまま多数の改善を行えました。今後も残りのCloudSearchをOpenSearchに移行したり、OpenSearchの豊富な機能を利用したりしてEightをどんどん良くしていきたいと思います!

© Sansan, Inc.