マイクロサービス間でのデータの変更イベントと同期 #のびしろウィーク
この記事は LayerXテックアドカレ2023 の39日目の記事です。
昨日の記事は、suguru さんのバクラク Enabling Team の課題とのびしろでした!
今日はバクラク事業部 Enabling Team エンジニアの @yyoshiki41(中川佳希)が担当します。
のびしろウィーク 👐
のびしろウィークは、LayerXの各チームメンバーがチームの伸びしろについて発信する期間です!
プロダクトや組織の成長過程で常に状況が変わるため、社内には解決されていない問題や整備されていない環境、いわば「のびしろ」がたくさんあります。
のびしろを読んでみて、「その課題、詳しく聞きたい!取り組んでみたい!」と少しでも思っていただけたら、ぜひ一度お話出来れば幸いです!
本記事のテーマは、バックエンドマイクロサービス間でのデータの変更イベントとデータ同期についてです。
複数プロダクトで利用されるデータ
バクラクでは多くのマイクロサービスが稼働しています。
ステートレスな(ここではデータストアを持たない)サービス、単一プロダクトでのみ利用されるデータを管理しているサービスもあれば、複数のプロダクトで利用されるデータを管理しているサービスもあります。
ステートフルなサービスをもつ場合、データが変更されたことをトリガに別のサービスに作用をもたらしたいこともあります。例えば、申請システム上で書類が承認されたら、書類を発行ステータスに更新してメール送付を行い、売上情報を入金待ちにするなどです。
上の図ではリソースオーナーであるサービスがデータの状態を変更したことを別のサービスに知らせる必要があります。(例えば、申請が承認されたとき)
このようなユースケースでサービス間を疎結合に保ちながらメッセージ通信を行うためのソフトウェアが、Apache Kafka に代表されるようなメッセージブローカーです。
Change Data Capture
ユーザーからのアクションは実態としては、データの状態変更イベントと言えます。そのようなケースでリソースオーナーが意図的に別のシステムに向けて作用を行わずに、データベースの変更をイベントとするアプローチが、Change Data Capture です。
現在試験的に動かしているのは、MySQLをソースとし Debezium を Kafka Connect として起動して、行レベルでの変更イベントをパブリッシュするというものです。
現段階では上記を実装していますが、以下のような“のびしろ”があります。
- Debezium Server or Embedded Engine のような kafkaless なアーキテクチャ
=> 運用コンポーネントを増やしたくない - Consumer 側で変更イベントを gRPCサービスにメッセージングする実装 (Push Subscriptions)
=> アプリ開発者により扱いやすいデータフォーマットで配信したい (protocol buffers) - Consumer 側でのテーブルスキーマの変更に強い実装
=> カラムのドロップやデータ型変更など、Breaking changes に相当する場合の安全なハンドリングをしたい
バッチでのデータ同期
イベントではなく、データベースとして他サービスのデータが欲しい場合もあります。境界づけられたコンテキストをデータがはみ出ることになってしまいますが、SQL上での結合を実現したい場合がその例です。
この場合に、必要なデータベースを複数のマイクロサービスで共有することは、「共通結合」と呼ばれる結合度の高いパターンとして認識されています。
より結合度が低くなるように、リソースオーナーが他のサービスに向けてデータストア(ここでは RDS に限らず、OpenSearch なども含む)をエンドポイントとして公開するアプローチもあります。
※ もともとは Reporting Database として、エンタープライズ向けのアプリケーションで正規化された業務用のデータベースでは困難な分析(例えば集計など)を行いたいケースに対応するために提案されました。集計用途以外でもマイクロサービスのデータベースをインターフェイスとして公開する際にも利用可能なアプローチです。
このアプローチはより広いユースケースで利用可能と考えており、例えばプロダクトのデータベースを機械学習チームが利用したい形に加工した形で提供することにも応用出来ます。
一度に大量のデータ書き込みが行われるソースもあり、CDC でのストリーミング形式とは別にバッチでのデータ同期が必要であることを想定しています。現段階では地道なデータ同期をアプリケーションコードとして実装しているため、以下のような“のびしろ”があります。
- Apache Beam のような汎用的なソフトウェアを導入する
- データ同期先は複数のデータソースに対応する (OpenSearch, BigQuery, DynamoDB)
- プログラミング言語でのデータ加工をサポートする (Mapping Engine)
このテーマについては、データチーム所属のスペシャリスト @civitaspo ともカジュアル面談 をすると盛り上がれると思います😉
おわりに
プロダクトが持つデータを社内のサービスやサブシステムに向けて提供することは、今後も求められる処理であり、よりスケーリングも出来る方法を模索中です。
アイデアを元に構想、実装しているフェーズですので、より良い選択肢やアプローチを一緒に考えたい方や実装したいという方をお待ちしています!
Discussion