BUYMAの検索システムを刷新したお話

こんにちは。主にBUYMAの検索周りを担当しているエンジニアの伊藤です。

BUYMAではSolrを利用した検索システムがいくつかあります。
BUYMAの検索というと検索ボリュームが一番大きな商品検索を想像されると思いますが、
今回はデータボリュームが一番大きい検索システムをターゲットとして、インフラ周りを含め全面的にシステムの刷新を行いました。

ここでは、

  • 既存の検索システムがどういったものだったのか
  • なぜシステム更改が必要だったのか(どういう課題があったのか)
  • 更改後の検索システムはどういったものか
  • 今後の課題について

等々についてご紹介したいと思います。

既存の検索システムについて

既存の検索システムは下記の通り、シンプルという点ではとても素晴らしいものでした。

f:id:pma1013:20200203151456p:plain

ただし下記のような問題を抱えている状況でした。

  • スケールアウトしない構成である
  • スケールアップの限界
  • Solrのバージョンが古い
  • 本番環境のデータを利用した検証が難しい
  • 開発担当者にもSolrの知識が必要とされる
  • 問題に気付けない

以降でその内容について補足していきます。

スケールアウトしない構成である

  • 検索システムはデータ増とアクセス増の2軸でスケールアウト構成を取る必要があります。
  • アクセス増にはSolrサーバを追加することで対応できるようにはなっていましたが、該当の検索システムはアクセス数というよりデータが多いことが特徴でこのデータ増に追従出来なくなっていました。

スケールアップの限界

  • 該当の検索システムは元々オンプレ環境で運用していましたが、ヒープサイズ不足やFull GCが頻発するようになっていたため、暫定対処としてAWS側に移行し、GCチューニングを行いました。
  • ただしこの対応も一時的なもので、データ数自体は日々増加している状況の中で使用しているGCアルゴリズム的に、メモリを増やしてどうこうできる状況ではなくなっていました。
    • データ増に伴いOOM Killer、ヒープサイズ不足が発生 → ヒープサイズを拡張 → STWのインパクトが大きくなるという負のループに陥る

Solrのバージョンが古い

  • 既存の検索システムで利用しているSolrのバージョンは3.2.0でした
  • バージョンが古くても通常時の運用にはそれほど支障はありませんが、何か問題があった場合の調査が大変でした(ドキュメントが見つからない)
  • またSolrのバージョンupに伴いindexing/検索性能はupしていますので、性能面でのデメリットであったり
  • 以降のバージョンで提供された様々な機能が利用できない等のデメリットがありました

本番環境のデータを利用した検証が難しい

  • 既存システムで本番環境相当のデータで検証する際にはindexing処理だけで数日かかるという状況で、環境構築自体がハードルとなっていました。

開発担当者にもSolrの知識が必要とされる

  • Solrへの検索時はphprubyといったクライアント側でSolrのクエリを組み立てて実行していました。
  • クライアント側を担当する開発担当者はその時々で変わり、ある程度はSolrを知っている人もいれば、全く知らない人まで様々です。
  • 一方Solrのクエリは書き方によってはキャッシュを使えていなかったり、または逆にキャッシュを無駄に汚してしまったりと、同じ検索結果を得るにしてもある程度Solrの知識を必要とします。

問題に気付けない

  • 必要なデータやログが適切に可視化され監視されていないため、サービス影響、ユーザ問い合わせがあって初めて問題に気付くケースがありました

更改後の検索システム

上記で挙げた課題感を解決するために設計したアーキテクチャが下記になります。

f:id:pma1013:20200203172549p:plain

  • 変化に強いシステムへ

    • SolrCloud構成に変更しつつ、データ増にはデータsharding、アクセス増にはデータreplicationでスケールアウト可能な構成に変更
  • 環境再現性

    • 全てコンテナベースのアプリケーションとなっているため、本番と同じマシンスペック、構成を簡単に構築可能
    • 本番データを利用した検証も短時間で可能となった
    • indexing処理についてもBUYMAで利用しているメインのDBにアクセスする必要がなく、中間DBを利用することで数時間でfull-import可能
  • 耐障害性の向上

    • プラットフォームにKubernetesを採用し、想定外のアプリケーション停止、ノードdown時にもセルフヒーリングで自動復旧可能
  • マイクロサービス化(隠蔽化)

    • アプリケーション〜Solr間に検索APIを新たに用意。これによりアプリケーション側はSolrの独自クエリを意識することなく、検索APIを介したシンプルなI/Fをベースとした開発が可能に。
    • Solrの独自クエリなど、専門的な知識を開発者が持つ必要がなくなり、学習コストが抑えられることで開発効率が上がる
    • 不適切なクエリにより、Solr側のキャッシュをうまく使えないなどの問題回避
  • 障害検知

    • 監視、ログ運用基盤としてDatadogを利用し、インフラ/ミドル/アプリケーションのメトリクス情報やログを統合的に管理可能とした
  • 属人性の排除

    • 検索システム間でバラバラだったスキーマ定義を汎用的なものにし、複数の検索システムをシームレスに対応可能に
    • dynamicフィールドをベースとしているため、スキーマ定義自体も運用上ほぼ変更する必要がない
  • GitOps対応

    • 全てのシステム設定をコードとしてGit上で管理
    • 運用上変更頻度が高いものはコマンド実行不要でCI/CDで可能

苦労した点

今回せっかくシステム更改するならCloudNativeなシステムにしたいという思いがありこのような構成にしました。
SolrのようなstatefulなアプリケーションをコンテナとしてKubernetes上で扱うのも初めてでしたし、 監視、ログ運用周りも今回の対応と合わせて刷新したことで対応範囲が広くなり苦労した点も多くありました。
ここではいくつかピックアップして紹介したいと思います。

  • Solr/ZookeeperをKubernetes上に構築、運用した経験がない

    • Solrに関してはあまり構築事例もなく問題に遭遇した際の解析に難航
    • リソース設計、ログ周りなど、コンテナ/Kubernetesだからこそプラスαで考慮しなければ行けない点が多々あった
  • 監視、ログ運用基盤の検討

    • コンテナ/Kubernetesベースのシステムをどう監視すべきか?
    • ログはどう扱うべきか?
  • 検索APIの設計、開発

    • I/F仕様どうするか?
    • 開発しながらSolr/Zookeeper周りの設定や問題対応をするのが辛い
  • Solrバージョンアップによる未知の問題対応

    • indexing処理周りで問題多発
    • SolrCloudかつDIHで並列indexing処理を行うこと自体が事例がなく、色々とはまる

今後に向けて

システム更改により当初挙げていた課題感というのは概ね解決することが出来ました。
ただし今回のようなシステムを構築、運用したことでてきた新たな課題や、まだまだ改善が必要だなと思えるところもあります。

  • indexing処理などはクライアント側の処理と密になっている箇所がまだまだあり、今後もブラッシュアップが必要
  • Solrのような複雑かつstatefulなアプリケーションは運用がやはり大変。Kubernetes operatorを利用するなどして運用をもっと楽にしつつ、属人性もなくしていきたい。

さいごに

今回は検索のインフラ面を中心としたお話を紹介させていただきましたが、 弊社では検索のサービス向上(ex パーソナライズサーチなど)や自然言語処理機械学習を活用したサービス導入なども積極的に行っています。
今回技術的なところにはほぼ触れませんでしたが、ここどうなってるの?など少しでも興味、関心を持たれたら是非お気軽にお話だけでも聞きにいただければと思います。

株式会社エニグモ 正社員の求人一覧 hrmos.co