MakingSenseofStreamProcessing / Transactions and Integrity Constraints


Transactions and Integrity Constraints

  • 一つの問題が残されています。ログのコンシューマはすべてデータストアを非同期的に更新するため、最終的に一貫しています。 たとえば、データベースの各ユーザー名が一意でなければならない場合や、ユーザが口座残高よりも多いお金を使えないおようにしたい場合などの、データが特定の制約を満たしていることを保証したい場合は、これでは不十分です。
  • この問題を解決する方法はいくつかあります。 1つはチェンジ・データ・キャプチャと呼ばれ、第3章で説明します。図2-31に、かなり簡単なアプローチのもう1つを示します。
  • ユーザー名が一意であることを確認したいとします。 ユーザーが登録しようとしたときにユーザー名がすでに取得されているかどうかを確認できますが、同じユーザー名を同じ時刻に要求しようとしている2人の競合状態が許可されます。 伝統的に、リレーショナルデータベースでは、これを防ぐために、トランザクションとユーザー名列に固有の制約を使用します。
  • ログに追加できるアーキテクチャを使用する場合、この問題は2段階のプロセスとして解決できます。 まず、ユーザーがユーザー名を要求したい場合は、「ユーザー名要求」ストリームにイベントを送信します。 このイベントは一意性をまだ保証していません。 それは単に主張の発注を確立するだけです。 (Kafkaのように分割ストリームを使用している場合は、同じユーザー名へのすべての要求が同じパーティションに移動するようにする必要があります。ユーザー名をKafkaパーティションキーとして使用することができます)。
  • ストリーム・プロセッサはこのストリームを消費し、一意性をデータベースでチェックし、新しいユーザー名をデータベースに書き込み、結果(別名「すでに登録済み」または「すでに登録済」)を別の「登録」イベント・ストリームに書き込みます。 この検証プロセッサは、一度に1つのイベントを単一スレッドの方法で処理できます。 より多くの並列性を得るには、それぞれが独立して処理されるKafkaパーティションを使用します。このアプローチは、毎秒何百万というイベントに拡張されます。 各パーティション内のメッセージは順次処理されるため、同時処理の問題はなく、競合する登録も確実に検出されます。
  • ユーザーはユーザー名の登録に成功したかどうかをどのように確認しますか? 1つの選択肢は、要求を提出したサーバーが「登録」ストリームを消費し、一意性検査の結果が報告されるのを待つことです。 Samzaのような高速ストリームプロセッサでは、これはほんの数ミリ秒かかるでしょう。
  • 競合が十分にまれである場合は、クレームが提出されるとすぐにユーザーに「ok」と伝えることが許容される場合もあります。 ごくまれに、登録に失敗した場合は、一時的なランダムなユーザー名を割り当て、謝罪するための電子メール通知を送信して、新しいユーザー名を選択するよう依頼することができます。
  • 同じアプローチを使用して、ユーザの口座残額をマイナスにしないようにすることができます。 より複雑な状況では、Microsoft ResearchのTangoプロジェクトなど、Kafkaの上にトランザクションプロトコルをレイヤーすることができます。

担当者のつぶやき

みんなの突っ込み