web-dev-qa-db-ja.com

Kafkaを(CQRS)イベントストアとして使用します。良いアイデア?

Kafka に出くわしたことがありますが、最近、Kafkaが CQRS として使用される可能性があることに気付きました。 イベントストア

Kafkaがサポートする主なポイントの1つ:

  • イベントのキャプチャ/保存、もちろんすべてのHA。
  • パブ/サブアーキテクチャ
  • 新しいサブスクライバーが事後にシステムに登録できるようにするイベントログを再生する機能。

確かに、私はCQRS /イベントソーシングに100%精通しているわけではありませんが、これはイベントストアがどうあるべきかにかなり近いようです。おもしろいことは、イベントストアとして使用されているKafkaについてはあまり見つけられないので、おそらく何かが足りないはずです。

それで、良いイベントストアになるためにKafkaに欠けているものはありますか?うまくいくでしょうか?本番を使用していますか?洞察、リンクなどに興味がある.

基本的にシステムの状態は、通常行われているシステムの現在の状態/スナップショットを保存するのではなく、システムがこれまでに受信したトランザクション/イベントに基づいて保存されます。 (会計の総勘定元帳として考えてください:すべてのトランザクションは最終的に最終状態になります)これにより、あらゆる種類のクールなことが可能になりますが、提供されたリンクを読んでください。

192
Geert-Jan

Kafkaは、イベントストアと多くの類似点を持っているメッセージングシステムであることを意図していますが、イントロを引用します。

Kafkaクラスターは、パブリッシュされたすべてのメッセージを、それらが消費されたかどうかにかかわらず、保持します-設定可能な期間。たとえば、保持期間が2日間に設定されている場合、メッセージが公開されてから2日間はメッセージを使用でき、その後メッセージは破棄されて領域が解放されます。 Kafkaのパフォーマンスはデータサイズに関して事実上一定であるため、大量のデータを保持することは問題になりません。

したがって、メッセージは無期限に保持される可能性がありますが、メッセージは削除されることが期待されます。これは、これをイベントストアとして使用できないことを意味するものではありませんが、他のものを使用する方が良い場合があります。代替手段については、 EventStore をご覧ください。

更新

Kafkaドキュメント

イベントソーシングは、状態の変化がレコードの時間順シーケンスとして記録されるアプリケーション設計のスタイルです。非常に大きな保存されたログデータに対するKafkaのサポートにより、このスタイルで構築されたアプリケーションの優れたバックエンドになります。

更新2

イベントソーシングにKafkaを使用する際の懸念事項の1つは、必要なトピックの数です。通常、イベントソーシングでは、エンティティ(ユーザー、製品など)ごとにイベントのストリーム(トピック)があります。このように、ストリーム内のすべてのイベントを再適用することにより、エンティティの現在の状態を再構成できます。各Kafkaトピックは1つ以上のパーティションで構成され、各パーティションはファイルシステム上のディレクトリとして保存されます。 znodeの数が増えると、ZooKeeperからのプレッシャーもあります。

104
eulerfx

私はカフカの原作者の一人です。 Kafkaは、イベントソーシングのログとして非常にうまく機能します。フォールトトレラントであり、膨大なデータサイズに対応し、パーティションモデルが組み込まれています。

LinkedInのこのフォームのいくつかのユースケースで使用します。たとえば、オープンソースのストリーム処理システムであるApache Samzaには、イベントソーシング用の 組み込みサポート が付属しています。

Kafkaが最も人気のあるコンシューマーWebスペースでは、イベントソーシングの用語があまり普及していないようであるため、イベントソーシングにKafkaを使用することについてあまり耳にしないと思います。 。

このスタイルのKafkaの使用法について少し説明しました here

261
Jay Kreps

このQAに戻ってきます。そして、私は既存の答えが十分に微妙であるとは思わなかったので、これを追加しています。

TL; DR。はいまたはいいえ、イベントソーシングの使用状況に応じて。

私が知っているイベントソースシステムには、主に2つの種類があります。

ダウンストリームイベントプロセッサ=はい

この種のシステムでは、イベントは現実の世界で発生し、事実として記録されます。製品のパレットを追跡する倉庫システムなど。基本的に競合するイベントはありません。たとえそれが間違っていたとしても、すべてがすでに起こっています。 (つまり、パレット123456はトラックAに置かれていますが、トラックBにスケジュールされていました。)その後、レポートメカニズムを介して例外の例外がチェックされます。 Kafkaは、この種の下流のイベント処理アプリケーションに適しているようです。

この文脈では、Kafkaの人々がイベントソーシングソリューションとしてそれを提唱している理由は理解できます。これは、たとえばクリックストリームで既に使用されている方法と非常に似ているためです。ただし、「ストリーム処理」ではなく「イベントソーシング」という用語を使用している人は、2番目の使用方法を指している可能性があります.

アプリケーション制御の真実のソース=いいえ

この種のアプリケーションは、ビジネスロジックを通過するユーザーリクエストの結果として、独自のイベントを宣言します。この場合、Kafkaはうまく機能しません。主な理由は2つあります。

エンティティの分離の欠如

このシナリオには、特定のエンティティのイベントストリームをロードする機能が必要です。これの一般的な理由は、要求の処理に使用するビジネスロジックの一時的な書き込みモデルを構築することです。これを行うことは、Kafkaでは実用的ではありません。エンティティごとのトピックを使用すると、これが可能になる場合がありますが、これは数千または数百万のエンティティが存在する可能性がある場合の非スターターです。これは、Kafka/Zookeeperの技術的な制限によるものです。

このように一時的な書き込みモデルを使用する主な理由の1つは、ビジネスロジックの変更を安価で簡単に展開できるようにすることです。

Kafkaでは代わりにtopic-per-typeを使用することをお勧めしますが、単一のエンティティのイベントを取得するためだけに、そのタイプのすべてのエンティティのイベントを読み込む必要があります。どのイベントがどのエンティティに属しているかをログの位置で知ることができないためです。既知のログ位置から開始するために Snapshots を使用しても、これは大量のイベントである可能性があります。

競合検出の欠如

第二に、ユーザーは同じエンティティに対する同時リクエストにより競合状態を作成できます。競合するイベントを保存し、事後に解決することは非常に望ましくない場合があります。そのため、競合するイベントを防止できることが重要です。要求の負荷を調整するには、条件付き書き込み(最後のエンティティイベントが#xの場合のみ書き込み)を使用して書き込みの競合を防ぎながら、ステートレスサービスを使用するのが一般的です。別名楽観的並行性。 Kafkaは楽観的同時実行をサポートしていません。トピックレベルでサポートされていたとしても、効果を発揮するにはエンティティレベルに至るまで必要です。 Kafkaを使用してイベントの競合を防ぐには、アプリケーションレベルでステートフルなシリアル化されたライターを使用する必要があります。これは重要なアーキテクチャ要件/制限です。

詳細情報


コメントごとに更新

コメントは削除されましたが、質問は次のようなものでした:イベントストレージに人々は何を使用しますか?

ほとんどの人は、既存のデータベースの上に独自のイベントストレージ実装を展開しているようです。内部バックエンドやスタンドアロン製品などの非分散シナリオの場合、SQLベースのイベントストアを作成する方法は 詳細に文書化されています です。また、さまざまな種類のデータベースの上にライブラリがあります。 EventStore もあり、これはこの目的のために構築されています。

分散シナリオでは、いくつかの異なる実装を見てきました。 Jetの PantherプロジェクトはAzure CosmosDBを使用 、リスナーに通知するフィード変更機能を備えています。 AWSで聞いた同様の別の実装では、DynamoDBをストリーム機能とともに使用してリスナーに通知します。最適なデータ配信のために、おそらくパーティションキーはストリームIDである必要があります(オーバープロビジョニングの量を減らすため)。ただし、Dynamoのストリーム全体での完全な再生は高価です(読み取りとコストの面で)。したがって、この実装は、Dynamo StreamsがイベントをS3にダンプするためにもセットアップされました。新しいリスナーがオンラインになったとき、または既存のリスナーが完全な再生を必要とするとき、最初に追いつくためにS3を読み取ります。

私の現在のプロジェクトはマルチテナントシナリオであり、Postgresの上に自分のプロジェクトを展開しました。 Citusのようなものはスケーラビリティに適しているようで、テナント+ストリームで分割します。

Kafkaは依然として分散シナリオで非常に便利です。各サービスのイベントを他のサービスに公開することは簡単な問題ではありません。通常、イベントストアはそのために構築されませんが、Kafkaはまさにそれでうまくいきます。各サービスには独自の内部情報源(イベントストレージなど)がありますが、Kafkaをリッスンして、「外部」で何が起こっているのかを把握しています。サービスは、Kafkaにイベントを投稿して、サービスが行った興味深いことを「外部」に通知することもできます。

36
Kasey Speakman

Kafkaをイベントストアとして使用できますが、そうすることはお勧めしませんが、良い選択のように見えるかもしれません。

  • Kafkaは少なくとも1回の配信のみを保証し、イベントストアには削除できない重複があります。 更新:ここでは、Kafkaと、この動作を最終的に達成する方法に関する最新のニュースで、なぜそれが難しいのかを読むことができます。 https://www.confluent.io/blog/exactly-once-semantics-are-possible-heres-how-Apache-kafka-does-it/
  • 不変性のため、アプリケーションが進化し、イベントを変換する必要がある場合、イベントストアを操作する方法はありません(もちろん、アップキャストのようなメソッドがありますが...)。一度イベントを変換する必要はないと言うかもしれませんが、それは正しい仮定ではありません。元のバックアップを行うが、それらを最新バージョンにアップグレードする場合があります。これは、イベント駆動型アーキテクチャの有効な要件です。
  • エンティティ/集計のスナップショットを保持する場所はなく、再生はますます遅くなります。スナップショットの作成は、長期的な観点からイベントストアの機能である必要があります。
  • 与えられたKafkaパーティションは分散されており、データベースと比較して管理やバックアップが困難です。データベースは単純です:-)

だから、あなたがあなたの選択をする前に、あなたは二度考える。アプリケーションレイヤーインターフェイス(監視と管理)、SQL/NoSQLストア、およびKafkaの組み合わせとしてのイベントストアは、Kafkaの両方の役割を処理して完全な機能フルソリューションを作成するよりも良い選択です。

イベントストアは、イベントソーシング、CQRS、Sagasおよびその他のパタ​​ーンをイベント駆動型アーキテクチャに適用し、高いパフォーマンスを維持することに真剣に取り組む場合、Kafkaが提供できる以上のものを必要とする複雑なサービスです。

自由に答えに挑戦してください!多くの重複する機能を持つお気に入りのブローカーについて私が言うことを好まないかもしれませんが、それでも、Kafkaは、イベントストアとして設計されたのではなく、たとえば、高速プロデューサーと低速コンシューマのシナリオを処理するための高性能ブローカーおよびバッファーとして設計されました。

Eventuate.ioマイクロサービスのオープンソースフレームワークを参照して、潜在的な問題について詳しく調べてください。 http://eventuate.io/

2018年2月8日現在の更新

私はコメントから新しい情報を取り入れませんが、それらの側面のいくつかに同意します。この更新は、マイクロサービスイベント駆動型プラットフォームに関するいくつかの推奨事項に関するものです。一般的にマイクロサービスの堅牢な設計と最高のパフォーマンスを真剣に考えているなら、あなたが興味を持つかもしれないいくつかのヒントを提供します。

  1. Springは使用しないでください-それは素晴らしい(私は自分で多く使用します)が、同時に重くて遅いです。そして、それはマイクロサービスプラットフォームではありません。それは、あなたがそれを実装するのを助ける「ただの」フレームワークです(これの背後にある多くの仕事。他のフレームワークは、「ちょうど」軽量のRESTまたはJPAまたは異なる焦点のフレームワークです。おそらくJavaの純粋なルートに戻ってくる、クラス最高のオープンソースの完全なマイクロサービスプラットフォームをお勧めします。 https://github.com/networknt

パフォーマンスについて疑問がある場合は、既存のベンチマークスイートと比較できます。 https://github.com/networknt/microservices-framework-benchmark

  1. Kafkaを使用しないでください:-))これは半分の冗談です。 Kafkaは素晴らしいですが、別のブローカー中心のシステムです。将来はブローカーレスのメッセージングシステムにあると思います。驚くかもしれませんが、Kafkaシステムよりも高速です:-)、もちろん、より低いレベルに降りる必要があります。クロニクルを見てください。

  2. イベントストアの場合、TimescaleDBと呼ばれる優れたPostgresql拡張機能をお勧めします。これは、大量の高性能時系列データ処理(イベントは時系列です)に焦点を当てています。もちろん、CQRS、イベントソーシング(リプレイなどの機能)は、Light4jフレームワークに組み込まれており、Postgresを低ストレージとして使用します。

  3. メッセージングについては、クロニクルキュー、マップ、エンジン、ネットワークを確認してください。つまり、この昔ながらのブローカー中心のソリューションを取り除き、マイクロメッセージングシステム(組み込み)を使用します。クロニクルキューは、実際にはKafkaよりも高速です。しかし、私はそれがすべて1つのソリューションではなく、いくつかの開発を行う必要があることに同意します。そうでなければ、エンタープライズ版(有料版)を購入します。最後に、Kafkaクラスターを維持する負担を取り除くことで、Chronicleから独自のメッセージングレイヤーを構築する努力が払われます。

14
kensai

はい、Kafkaをイベントストアとして使用できます。特に Kafka Streams を導入すると、うまく機能します。これは、イベントを処理して累積 クエリ可能な状態 にするKafkaネイティブの方法を提供します。

に関して:

新しいサブスクライバーが事後にシステムに登録できるようにするイベントログを再生する機能。

これには注意が必要です。詳細はこちらで説明しました: https://stackoverflow.com/a/48482974/74197

7