この記事はBASE Advent Calendar 2019 9日目の記事です。
こんにちは、BASE株式会社 ランニング部部長の元木です。
フルマラソンのサブスリー達成を目指して日々トレーニングに励む傍ら、Owners Marketingというチームでサーバーサイドエンジニアもやっております。
前書き
弊社が提供するネットショップ作成サービス「BASE」(以下「WEB」)とショッピングアプリ「BASE」(以下「アプリ」)では、Amazon CloudSearch(以下「CloudSearch」)を利用して商品の検索機能を提供しております。
当記事では、 CloudSearch のインデックスを更新する処理を、どのようにバッチからワーカーに置き換えたのかをご紹介させていただきます。
この記事は、「BASE Advent Calendar 2019」の9日目の記事です。
バッチの何が問題だったのか
商品データは、ショップオーナーさんや購入者のアクションによって刻々と変化していきます。
BASEのシステムは、その商品データの変化を捉えて CloudSearch のインデックスを更新していくこととなります。
CloudSearch のインデックスを更新するのは比較的時間がかかる処理であることと、 CloudSearch には
「更新の頻度が10秒に1回を超えると、スロットリングが発生する場合がある」
という制限があるため、BASE ではバッチプログラムを用いて、非同期でこの処理を実行しておりました。
しかし、バッチ処理には
- インデクシングが必要な商品数は日々増えていくが、処理をスケールできない
- DBへの負荷が高い
という問題がありました。
試験的に、アプリ側には Amazon SQS (以下「SQS」)をポーリングして CloudSearch のインデックスを更新するワーカーが導入されておりましたが、一部のアクション(商品の登録・更新・削除)しかカバーしておりませんでした。
以下が、切り替え前のシステム構成です。
弊社CTOの @dmnlk と話した結果、これを以下のような構成に変更することが決まりました。
- SQS の前段に Amazon SNS (以下「SNS」)を配置する。
- WEB用の SQS を新たに追加する- アプリ側、WEB側ともに、バッチをワーカーに完全に置き換える
以下が、目標とするシステム構成です。
ちなみにこの時の私の Amazon SNS に対する理解度は、こんな感じでした。
次からは、どのような段取りでシステム構成を切り替えていったのかをご説明します。
バッチからワーカーへ
手順1 : Amazon SNS の配置
まず、SQS の前段に SNS を配置し、商品データが更新された際の通知先を SQS から SNS に切り替えました。
アプリケーションの変更点としては、インデックスの更新が必要になるアクションが発生した際の通知先を SQS から SNS に切り替えるだけです。
手順2 : WEB用のワーカーとSQSの配置
次に、WEB用のワーカーと SQS を配置し、ポーリングを開始しました。
まだ、一部のアクションしか SNS に通知されない状況ですので、引き続きワーカーとバッチを並行稼動させています。
WEB用のワーカーを実装する際には、バッチとワーカーが同じ動作をすることを保証するために
- バッチのテストコードを書く(それまでは無かった)
- バッチのテストコードとワーカーのテストコードとでデータプロバイダーを共通化し、入力と出力が一致することを保証する
といった工夫も行ないました。
SNS と WEB用の SQS を連携させる際も、いきなり全てのイベントを通知させるのではなく、 SNS のメッセージ・フィルタ機能 を利用して通知するイベントを徐々に増やしていくようにしました。
手順3 : Amazon SNS に通知するアクションを増やしていく
次に、SNSに通知するアクションを徐々に増やしていき、最終的に CloudSearch のインデックスを更新する必要のある全てのアクションが SNS に通知されるようにしました。
ここでも、一気に全アクションを通知するよう変更するのではなく、段階的に通知するアクションを増やしていくようにしました。
実は、手順2, 3 を実施していく過程で何度かWEB用のワーカーに不具合が見つかり、改修を行なっております。 しかし、バッチとの並行稼動を続けていたことと、ワーカーの仕事量を少しずつ増やしていくようにしていたため、大きな問題に発展することはありませんでした。
手順4 : バッチの退役
全てのアクションが SNS に通知されるようになったところでバッチを退役させ、すべての作業が完了しました。
まとめ
サービスが成長していくにつれて、以前は問題なかったシステムから問題が生じるようになることは往々にしてありえます。
一方で、システム構成の変更は比較的リスクが高い上に(何か新しい機能を提供するわけではないため)地味な作業であるため、ついつい、問題が大きくなるまで放置してしまいがちです。
私としては、作業の段取りを工夫することでリスクを最小限に抑えつつ、サービスの成長に応えられるシステムを構築し続けていきたいと考えております。