🌲

マイクロサービス間でのデータの変更イベントと同期 #のびしろウィーク

2023/12/19に公開

この記事は LayerXテックアドカレ2023 の39日目の記事です。

昨日の記事は、suguru さんのバクラク Enabling Team の課題とのびしろでした!
今日はバクラク事業部 Enabling Team エンジニアの @yyoshiki41(中川佳希)が担当します。

のびしろウィーク 👐

のびしろウィークは、LayerXの各チームメンバーがチームの伸びしろについて発信する期間です!
プロダクトや組織の成長過程で常に状況が変わるため、社内には解決されていない問題や整備されていない環境、いわば「のびしろ」がたくさんあります。
のびしろを読んでみて、「その課題、詳しく聞きたい!取り組んでみたい!」と少しでも思っていただけたら、ぜひ一度お話出来れば幸いです!

本記事のテーマは、バックエンドマイクロサービス間でのデータの変更イベントとデータ同期についてです。

複数プロダクトで利用されるデータ

バクラクでは多くのマイクロサービスが稼働しています。
ステートレスな(ここではデータストアを持たない)サービス、単一プロダクトでのみ利用されるデータを管理しているサービスもあれば、複数のプロダクトで利用されるデータを管理しているサービスもあります。
ステートフルなサービスをもつ場合、データが変更されたことをトリガに別のサービスに作用をもたらしたいこともあります。例えば、申請システム上で書類が承認されたら、書類を発行ステータスに更新してメール送付を行い、売上情報を入金待ちにするなどです。

上の図ではリソースオーナーであるサービスがデータの状態を変更したことを別のサービスに知らせる必要があります。(例えば、申請が承認されたとき)
このようなユースケースでサービス間を疎結合に保ちながらメッセージ通信を行うためのソフトウェアが、Apache Kafka に代表されるようなメッセージブローカーです。

Change Data Capture

ユーザーからのアクションは実態としては、データの状態変更イベントと言えます。そのようなケースでリソースオーナーが意図的に別のシステムに向けて作用を行わずに、データベースの変更をイベントとするアプローチが、Change Data Capture です。
現在試験的に動かしているのは、MySQLをソースとし Debezium を Kafka Connect として起動して、行レベルでの変更イベントをパブリッシュするというものです。

現段階では上記を実装していますが、以下のような“のびしろ”があります。

  1. Debezium Server or Embedded Engine のような kafkaless なアーキテクチャ
    => 運用コンポーネントを増やしたくない
  2. Consumer 側で変更イベントを gRPCサービスにメッセージングする実装 (Push Subscriptions)
    => アプリ開発者により扱いやすいデータフォーマットで配信したい (protocol buffers)
  3. Consumer 側でのテーブルスキーマの変更に強い実装
    => カラムのドロップやデータ型変更など、Breaking changes に相当する場合の安全なハンドリングをしたい

バッチでのデータ同期

イベントではなく、データベースとして他サービスのデータが欲しい場合もあります。境界づけられたコンテキストをデータがはみ出ることになってしまいますが、SQL上での結合を実現したい場合がその例です。
この場合に、必要なデータベースを複数のマイクロサービスで共有することは、「共通結合」と呼ばれる結合度の高いパターンとして認識されています。

より結合度が低くなるように、リソースオーナーが他のサービスに向けてデータストア(ここでは RDS に限らず、OpenSearch なども含む)をエンドポイントとして公開するアプローチもあります。

※ もともとは Reporting Database として、エンタープライズ向けのアプリケーションで正規化された業務用のデータベースでは困難な分析(例えば集計など)を行いたいケースに対応するために提案されました。集計用途以外でもマイクロサービスのデータベースをインターフェイスとして公開する際にも利用可能なアプローチです。

このアプローチはより広いユースケースで利用可能と考えており、例えばプロダクトのデータベースを機械学習チームが利用したい形に加工した形で提供することにも応用出来ます。

一度に大量のデータ書き込みが行われるソースもあり、CDC でのストリーミング形式とは別にバッチでのデータ同期が必要であることを想定しています。現段階では地道なデータ同期をアプリケーションコードとして実装しているため、以下のような“のびしろ”があります。

  • Apache Beam のような汎用的なソフトウェアを導入する
  • データ同期先は複数のデータソースに対応する (OpenSearch, BigQuery, DynamoDB)
  • プログラミング言語でのデータ加工をサポートする (Mapping Engine)

このテーマについては、データチーム所属のスペシャリスト @civitaspo ともカジュアル面談 をすると盛り上がれると思います😉

おわりに

プロダクトが持つデータを社内のサービスやサブシステムに向けて提供することは、今後も求められる処理であり、よりスケーリングも出来る方法を模索中です。
アイデアを元に構想、実装しているフェーズですので、より良い選択肢やアプローチを一緒に考えたい方や実装したいという方をお待ちしています!

https://jobs.layerx.co.jp/casual-night
https://jobs.layerx.co.jp/opendoor
https://jobs.layerx.co.jp/ef513e68e1dd424ca1cf82f79780c03d

LayerX

Discussion