キューイングシステムを深堀りたい
背景:
SidekiqワーカーがWebサーバーが入っているEC2に同居している状態。Railsモノリスから脱却し、疏結合化を進めることで、スケーラビリティを向上させたい。
現状分析:
- Railsモノリスの巨大な泥団子システム。
- 調べるとapp/model/concerns/hoge_enum.rbにワーカー呼び出しが集結
- app/worker配下にsidekiqのワーカー処理たちが書かれている
- gemのstateful_enumを使用してイベント駆動で状態遷移をするようになっている。
- イベントが発火したafterで色々なことをしていて、もしかしたら死んでるキューがあるかもしれない
問題:
- EC2にSidekiqが同居しているため、リソース競合が発生して、CPU負荷が高い
- メモリもジリジリと上昇していてサーバーダウン発生
- 結合度が高いため変更する時バグが入る可能性
解決方法
- SidekiqワーカーをWebサーバーから切り分けて独立したサーバーに設置
- メッセージキューを使用して非同期のイベント駆動型アーキテクチャを実現する
- CPU負荷特化のインスタンスファミリータイプを選び、最低限のリソース選択でコスト最適化
- 信頼性向上のためにDBで冪等性を確立する
- イベント記録をして二重実行を防止することで信頼性向上
移行時の注意
- 冪等性確保のための状態管理テーブル作成
- イベントが記録されてトランザクション追跡が可能
- 処理前、キューイング、処理後のステータスを管理
- 一意にレコードを特定できるよう、複合ユニーク制約などの設計
- DLQ(デッドレターキュー)・・・何度も失敗しているキューの処理
- リトライ処理5回以上のキューをDLQとして管理
- 手動で再実行
- 何かしらの失敗であれば良いが、永続的な失敗の場合はダッシュボードなどからの対処が必要だったりする
- 自動で再実行
- 永続的な失敗
- 自動で削除または処理ができるように設計
- 一時的な失敗
- ネットワーク障害などの一時的な失敗であれば、再度実行する仕組みでリトライ
- CI/CDの二重デプロイ
- Webサーバーとワーカーを分離
- 出品者商品情報のDB書き込みとメッセージキューの送信の整合性
- Outboxパターンを適用
- Outboxテーブルを個別用意。出品者のDB書き込みが発生したとき同一トランザクションでOutboxテーブルに書き込む。
- メッセージキューはOutboxテーブルを見て送信。
- 実質、「商品の状態=Outboxの状態」となり、冪等性を担保することでメッセージキューはDBとの整合性が保証される。
移行手順
- ストラングラーフィグパターンを実行
- ツルが木を巻きつけるようにして徐々に入れ替わる様からそう言われている
- 段階的に進めるにあたり、一部の処理からスタートしていき徐々に全体へと進める
- よくSIerはビッグバンリプレイスをするけど、DevOpsをしている会社はこちらを採用する方式になると思う
- フィーチャートグルスイッチ
- 外部コンフィグからON/OFFをして失敗時の復旧を外部から瞬時に戻すことができる
- ブランチバイアブストラクト
- カナリアリリース
- 何パーセントのユーザーにだけ新しいリリースの実行結果が行われるようインフラを構成
- メッセージキュー
- Amazon SQS・・・フルマネージドで運用の負荷は軽い
- RabbitMQなどOSS
- オンプレミスとかではこっちだけどクラウドで選ぶなら理由は自分たちで色々と実装をしたいとか?
- Kafka、Amazon Kinesisなどのイベントストリーム系
- シャーディングの仕組みなどでSQSよりも大幅なスループットが可能
- パーティションで区切り、処理を分けることが可能
- FIFOの先入先出し削除でデータ処理後に削除するのではなく、データの永続化が可能
- サーバー
- Webサーバーは継続してEC2だろうね。常時つけるから
- 問題はワーカーサーバー
- こっちはコンテナ化してみて部分的にECSを実現してみるとかいいんじゃないかな?
0 件のコメント:
コメントを投稿