GH GambleHub

メッセージ注文保証

1)何が「順序」であり、なぜそれが必要であるか

メッセージの順序は、1つのエンティティのイベント(order、 user、 wallet)またはストリーム全体の「前に処理すべきこと」の関係です。不変量には「、Bの前の状態A」「、書き込み前の残高」「、n+1の前のバージョンn」が重要です。
分散システムでは、グローバルなトータルオーダーは高価であり、まれに必要です。キーごとのローカル順序は通常十分です。


2)順序の保証のタイプ

1.パーティションごと(ログセクションのローカル順序)-Kafka:パーティー内の順序はパーティー間で保存されます-いいえ。
2.キーごと(キー/メッセージグループの順序)-1つのキーを持つすべてのメッセージは、処理の1つの「スレッド」にルーティングされます(Kafkaキー、SQS FIFO MessageGroupId、 Pub/Sub orderingキー)。
3.グローバル合計注文-システム全体で1つの注文(分散ジャーナル/シーケンサー)が表示されます。高価で、可用性とスループットを低下させます。
4.因果順序-「Aの後のイベントB if Bが効果を観察するA」メタデータ(バージョン、Lamport-times/vector clocks)を介してグローバルシーケンサーなしで到達可能。
5.最善の注文-ブローカーは注文を維持しようとしますが、失敗の場合、順列が可能です(多くの場合、NATS Core、 RabbitMQでは複数の消費者と一緒に)。


3)順序が故障するところ

同じキューの並列消費者(RabbitMQ:キューごとに複数の消費者→インターリーブ)。
再配達/再配達(少なくとも1回)、'ack'タイムアウト、再キューイング。
リバランス/フェイルオーバー(Kafka:パーティー/リーダー移動)。
DLQ/再処理-「毒」メッセージはDLQに行き、次のメッセージはさらに→論理的な休憩に進みます。
複数の領域とレプリケーション-異なる遅延→ずれ。


4)主な順序の設計

キーは「オーダーユニット」を形成します。"推奨事項:
  • 自然キー'order_id'、 'wallet_id'、 'aggregate_id'を使用します。
  • 「ホットキー」を見る-1つのキーはフローを「ブロック」することができます(ヘッド・オブ・ライン・ブロッキング)。必要に応じて、キーを分割します:'order_id#shard (0。。k-1)'シンク上の順序を決定的に再構築します。
  • Kafka-1つのキー→1つの部分では、順序はキー内に保存されます。
例(Kafka、 Java):
java producer.send(new ProducerRecord<>("orders", orderId, eventBytes));

(キー='orderId'はローカル注文を保証します。)


5)「順序対。帯域幅」

強力な保証は、スループットと可用性に矛盾することがよくあります:
  • キューごとに1人の消費者が順序を維持しますが、並行性を低下させます。
  • 少なくとも1回以上の並列処理でパフォーマンスが向上しますが、idempotencyや並べ替えが必要です。
  • Global Orderはシーケンサーにホップを追加します→→latentnostと失敗のリスク。

妥協:キーごとの順序、並列性=パーティー/グループの数、+idempotentあざ。


6)特定のブローカーの順序の制御

カフカ(Kafka

パーティー内で注文。
マックスを観察しろ。中に入っています。フライトだ。お問い合わせ。per。 connection ≤ 5''を有効にします。idempotence=true'で、プロデューサーのリトレイが順序を変更しないようにします。
消費者グループ:1人のパーティー→1人の労働者。繰り返し配信が可能→ビジネスレイヤーでシーケンス/バージョンを保持します。
Read-process-writeトランザクションは、read/write/crumbオフセットの整合性を維持しますが、グローバルな順序は作成しません。

生産最小(生産者。プロパティ):
properties enable.idempotence=true acks=all retries=2147483647 max.in.flight.requests.per.connection=5

RabbitMQ (AMQP)

注文は1つのコンサマーに対して1つのキューで保証されます。メッセージのいくつかの消費者と「混合」来ることができます。
注文の場合:完了時に1つのコンサマーまたはprefetch=1+ack。並行性の場合は、キーごとにキューを分離します(sharding exchange/consistent-hash exchange)。

NATS/JetStream

NATS Core-最善の努力、低遅延、注文が妨げられる可能性があります。
JetStream:ストリーム/シーケンス内の順序;再配送中は、コンソール上の再配置が可能です→シーケンスとリカバリバッファを使用します。

SQS FIFO

MessageGroupId内の正確に一度の処理(重複除外による)と順序。並行-ヘッド・オブ・ライン・グループ内のグループの数。

Google Pub/Sub

順序キーはキーの内の順序を与えます;エラーの場合、パブリッシングは復元されるまでブロックされます。バックプレッシャーに注意してください。


7)順序の保存および回復のパターン

7.1シーケンス/バージョン管理

各イベントには'seq'/'version'があります。コンサマー:
  • 'seq=last_seq+1'の場合にのみイベントを取得します。
  • それ以外の場合-欠落している('last_seq+1')の到着前にwaitバッファを入れます。
擬似コード:
pseudo if seq == last+1: apply(); last++
else if seq > last+1: buffer[seq] = ev else: skip // дубль/повтор

7.2バッファとウィンドウ(ストリーム処理)

Time-window+watermark:ウィンドウ内でのオーダーを受け付けます。ウォーターマークに従ってウィンドウを「閉じる」して整理します。
許容遅延:遅着のチャンネル(再計算/無視)。

7.3キーによる粘着ルーティング

hash (key)% shardsハッシュルーティングは、すべてのキーイベントを単一のワーカーに送信します。
Kubernetesでは、L4 HTTPバランサーではなく、キュー/sherdsレベルでセッション(sticky)を維持します。

7.4アクターモデル/」キーごとに1ストリーム「

クリティカルアグリゲート(ウォレット)の場合:アクターは順番に処理し、残りの並列性-アクターの数。

7.5 Idempotence+並べ替え

秩序を回復しても、繰り返しが可能です。キー+バージョンと受信トレイでUPSERTを組み合わせる(正確に1回vs少なくとも1回)。


8)「毒」メッセージ(毒薬)を使用する)

順序を維持することは、「1つのメッセージが処理されない場合にどのように生きるか」というタスクに直面しています?"

厳密な順序:主フローブロッキング(SQS FIFO:グループ全体)。解決策はby-key DLQです。問題のキー/グループだけを別のキュー/手動解析に転送します。
適用範囲が広い順序:私達はスキップ/補償を許可します;私たちはログを記録し続けます(財務/重要な集計ではありません)。
リトレイポリシー:制限された'max-delivery'+backoff+avidempotentエフェクト。


9)複数の地域および全体的なシステム

クラスタ・リンク/レプリケーション(Kafka)は、地域間のグローバル・オーダーを保証するものではありません。局所的なキーごとの順序と特異な打撲を優先します。
真のグローバル注文の場合は、シーケンサー(中央ログ)を使用しますが、これは可用性に影響します(ネットワークブレイクの場合はCAP:マイナスA)。
代替:いくつかのドメイン(カウンタ、セット)の因果順序+CRDT-厳密な順序は必要ありません。


10)順序の観察可能性

'out_of_order_total'、 'reordered_in_window_total'、 'late_events_total'、 'buffer_size_current'、 'blocked_keys_total'、 'fifo_group_backlog'。

'key'、 'seq'、 'expected_seq'、 'action=applyバッファスキップするdlq'。
トレース:'order_key'、 'partition'、 'offset'、 'seq'にまたがる属性。

11)アンチパターン

キーをシャーリングせずに1つのキュー+多くの消費者-注文はすぐに故障します。
同一のキューで再公開されたレトライは、偶発性なしで2倍になります。
グローバルな「just in case」 orderは、真の利益を伴わないレイテンシーと価値の爆発です。
SQS FIFOすべてのための1つのグループ-フルヘッドオブライン。キーごとにMessageGroupIdを使用します。
「ホットキー」を無視する-1つの「ウォレット」はすべてを遅くします。可能な限り、キーをサブキーに分割します。
同じキュー/グループ内の重要なストリームとバルクストリームの混合-相互の影響と順序の喪失。


12)実装チェックリスト

  • キーごと/パーティションごと/因果/グローバル?
  • シーケンシングキーとアンチホットキー戦略を設計。
  • ルータが設定されました:partitioning/MessageGroupId/orderingキー。
  • コンソールはキー(sticky-routing、 shard-workers)によって隔離されます。
  • Idempotencyおよび/またはInbox/UPSERTの打撲傷が含まれています。
  • シーケンス/バージョンと並べ替えバッファを実装(必要に応じて)。
  • キーポリシーとバックオフリトレイによるDLQ。
  • アウトオブオーダー、blocked_keys、 late_eventsオーダー、アラートメトリック。
  • ゲームの日:リバランス、ノードの損失、有毒なメッセージ、ネットワークの遅延。
  • ドキュメント:order invariants、 window bounds、 SLAへの影響。

13)構成例

13.1カフカ消費者(注文違反の最小化)

properties max.poll.records=500 enable.auto.commit=false  # коммит после успешной обработки батча isolation.level=read_committed
💡 1人の労働者が当事者全体を処理し、あなたの業務が偶然であることを確認してください。

13.2 RabbitMQ(並行価格による注文)

キューごとに1人の消費者+'基本。qos (prefetch=1)'

並行性の場合-複数のキューとハッシュ交換:
bash rabbitmq-plugins enable rabbitmq_consistent_hash_exchange публикуем с хедером/ключом для консистентного хеша

13.3 SQS FIFO

MessageGroupId=keyを設定します。並行=グループの数。
重複からの保護のためのMessageDeduplicationId(プロバイダウィンドウ内)。

13.4 NATS JetStream(オーダーコンシューマー、スケッチ)

bash nats consumer add ORDERS ORD-KEY-42 --filter "orders.42.>" --deliver pull \
--ack explicit --max-deliver 6

key>アプリケーションの'sequence'とバッファの並べ替えを監視します。


14) FAQ

Q:私は全体的な順序を必要としますか?
A:ほとんどありません。ほとんどの場合、キーごとに十分です。世界的な注文は高価であり、手頃な価格です。

Q:厳密な順序の下で「有毒な」メッセージについての何か?
A:彼のキー/グループだけをDLQに転送します。残りは続行します。

Q:順序およびスケールを同時に得ることができますか?
A:はい、キー順序+多くのキー/部品+idempotent操作および必要に応じてバッファを並べ替えます。

Q:どれがより重要です:順序または丁度一度か?
A:ほとんどのドメイン-キー順序+正確に一度の効果(idempotency/UPSERT)。輸送は少なくとも1回は可能です。


15)合計

注文は、ビジネスキーの周りのローカル保証であり、高価なグローバル規律ではありません。キーとパーティーを設計し、ホットキーを制限し、idempotenceを使用し、必要に応じてシーケンス+並べ替えバッファを使用します。アウト・オブ・オーダーやブロックされたキーのメトリクス、テスト・クラッシュに注意してください。パフォーマンスや可用性を犠牲にすることなく、予測可能な処理を得ることができます。

Contact

お問い合わせ

ご質問やサポートが必要な場合はお気軽にご連絡ください。いつでもお手伝いします!

統合を開始

Email は 必須。Telegram または WhatsApp は 任意

お名前 任意
Email 任意
件名 任意
メッセージ 任意
Telegram 任意
@
Telegram を入力いただいた場合、Email に加えてそちらにもご連絡します。
WhatsApp 任意
形式:+国番号と電話番号(例:+81XXXXXXXXX)。

ボタンを押すことで、データ処理に同意したものとみなされます。