検索 Suggest サーバーをコンテナ化しました


 こんにちは。弁護士ドットコム SRE 室のテイです。
 当社の検索 Suggest サーバーのコンテナ化をご紹介させていただきます。

Suggest について

Suggest とは?

 検索 Suggest とは、検索フォームに検索ワードを入力した際に、その入力に基づいて他の検索ワードをおすすめする仕組みです。

どのように機能するか

 当社の Suggest サーバーは以下のような機能があります。

  1. 検索ログから検索語部分を抽出
  2. DB (SQLite or MySQL) にその検索語が何回検索されたかを記録
  3. 一定回数(4)以上検索されている検索語を、検索回数が多い順に取り出し、接尾辞配列の索引を作成
  4. あるキーワードを含む検索語を出力

なぜコンテナ化するか

 当社の Suggest サーバーはコンテナ化する前は EC2 インスタンスで動かしていました。
 このインスタンスは DB 更新をするにはスペックが低く処理時間が長くかかるため、担当者のローカル環境である MacBook Pro で手動更新していました。具体的には下の図のような構成になっていました。

  • Solr ログ保管用 S3 から、すべての検索ログをローカルにダウンロードします
  • ローカルで検索ログから Suggest DB を再作成します
  • 最新の DB を Suggest サーバーへ転送します


 この不合理な運用のため、たくさんの問題がありました。

  • DB の更新があまり行われないので、最近の検索キーワードが出てこない可能性があります。
  • 担当者の端末の環境などに依存し、更新処理が属人化していました。
  • EC2 インスタンスにはオートスケーリング等の設定がされておらず、障害が発生した場合には復旧時間がかかり、サービス影響が出てしまいます。

 そのため、 Suggest サーバーをコンテナ化し、合わせて DB 更新も自動化しました。

コンテナ化した後

 当社は AWS のマネジードサービス Fargate を採用しました。コンテナ化した後の構成は下図のようです。

 詳細について、説明します。

 Code シリーズの CodeBuild を使って Suggest DB を最新化して、Docker イメージをビルドします。
 まずは、前日分の Solr ログと Suggest DB を それぞれの S3 バケットから CodeBuild のインスタンスにコピーします。

# 前日の日付
YEAR=`date +%Y -d '1 days ago'`
MONTH=`date +%m -d '1 days ago'`
YESTERDAY=`date +%d -d '1 days ago'`

# S3 から前日分の DB と solr ログを CodeBuild のインスタンスにコピーする
aws s3 cp s3://<db-backup-bucket名>/suggest/<サービス名>.db ./
aws s3 cp s3://<logs-backup-bucket名>/solr/${YEAR}/${MONTH}/<サービス名>-solr.${YEAR}-${MONTH}-${YESTERDAY}.log.gz ./

 その後、CodeBuild インスタンスにコピーした Solr ログと Suggest DB を使って、最新の Suggest DB の作成処理を DockerFile で定義し、Docker イメージをビルドします。

# DB コピー
COPY --chown=www-data:www-data <サービス名>.db /var/www/suggest/<サービス名>.db

# 検索ログからDBへ
ARG year
ARG month
ARG yesterday
COPY --chown=www-data:www-data <サービス名>-solr.${year}-${month}-${yesterday}.log.gz /var/www/go/src/suggest/solrlog/
RUN cd /var/www/go/src/suggest/ && \
    suggest log2db サービス名.conf solrlog/<サービス名>-solr.${year}-${month}-${yesterday}.log.gz

 イメージをビルドする時に、日付のパラメータを渡します。

docker build -t <サービス名>-suggest:latest --build-arg year="${YEAR}" --build-arg month="${MONTH}" --build-arg yesterday="${YESTERDAY}" .

 CodeBuild でビルドした Docker イメージを ECR へプッシュし、脆弱性のスキャン結果を Slack へ通知するようにしています。

 その後、CodePipeline を利用して、Fargate にデプロイします。
 Fargate が起動した後、最新化された Suggest DB を S3 へアップロードして、翌日に利用します。

aws s3 cp /var/www/suggest/<サービス名>.db s3://<db-backup-bucket名>/suggest/

 EventBridge を利用して、 CodePipeline を実行し、 DB の更新を自動化しています。

 また、当社はソースコード管理には GitLab を利用していますが、 CodeBuild 等で使用するものについてはリポジトリを CodeCommit にミラーリングしています。
 Suggest に関する設定変更がありまして、修正したソースを Gitlab のブランチにプッシュしましたら、CodeCommit へ同期して、CodePipeline を動かして、CI / CD の自動化も実現できます。

 以上、当社の Suggest サーバーのコンテナ化を紹介しました。