EIP / Resequencer


EIP

Resequencer

一言要約

要約

  • メッセージルーター(78)のせいで、メッセージごとの処理が分かれるため、処理にかかる時間がバラバラになる。しかし、メッセージの順序を正しくしてから処理しなければならないこともある。
  • 互いに関連はあるが、順序の異なるメッセージを正しい順序に並び替えるためにはどうすればよいか?
  • 順序がバラバラのメッセージを扱うためには、まず正しい順序にすればよい。物事を正しい順序にしておく方が、バラバラになったものを元に戻すよりも簡単だ。しかし、処理の中でメッセージの順序を正しく保つのは難しい。
  • 順序が狂ってしまうのは、メッセージによって別々の処理をする場合だ。たとえば、偶数のメッセージはなんらかの処理を行うが、奇数のメッセージは処理が不要、という場合、奇数のメッセージが先に、偶数のメッセージがその後に、ということになる。
  • メッセージの順序が狂ってしまうことを避けるためには、ループバック機構を導入して、一度に一つのメッセージしかシステムを通らないようにすることもできる。このやり方で問題は解決できるが、欠点が二つある。
    1. システムが著しく遅くなる:並行処理の意味が無くなる
    2. 処理ユニットに送られるメッセージを制御しなければならなくなる:しかし、バラバラになったメッセージを受け取ることも少なくない
  • アグリゲーター(268)を使えば、一連のメッセージを受け取って、関連するメッセージを識別し、数々の戦略に基づいてメッセージを集約することができる。この処理をしている間は、アグリゲーターは各メッセージがバラバラの順序で不定期に届くことに対応しなければならない。そのため、アグリゲーターはメッセージが揃うまでソートを続ける
  • リシーケンサーは、正しい順番とは限らないメッセージのストリームを受け取ることができる。順序がバラバラなメッセージを、すべて揃うまで内部バッファにため込み、適切な順序でチャネルに出力する。出力先のチャネルは順序を保たなければならない。また、リシーケンサーは通常メッセージの内容を変更しない。

シーケンスナンバー

  • リシーケンサーが機能するには、各メッセージには一意のシーケンスナンバーが振られていなければならない(メッセージシーケンス[170])。このシーケンスナンバーは、メッセージの識別子(identifier)やコリレーション識別子(163)とも異なる。メッセージ識別子は順序を制御するためには使えないことが多いし、コリレーション識別子も一意でありさえすればよい。
  • シーケンスナンバーを生成するためには、一意の識別子を生成するよりも時間がかかる。一意の識別子は個別に生成できるが、順序のある数字を生成するには、システムをまたがって数字を割り当てるカウンターが必要になる。

内部処理

  • シーケンスナンバーがあれば、リシーケンサーは順序がバラバラで届いたメッセージを検知できる。それでは、順序から外れたメッセージが届いた場合、リシーケンサーはどうすればよいだろうか?具体的には、大きい数字が小さい数字よりも先に届いてしまうことを意味する。リシーケンサーは、数字の大きいメッセージを、欠けているメッセージがすべて届くまで保持しなければならない。バッファ内にメッセージがすべて溜まったら、メッセージを正しい順序で出力して、バッファから削除する

バッファオーバーランを避ける

  • それでは、このバッファはどのくらい大きくしておけばよいだろうか?メッセージのストリームが長ければ、バッファは大きくなる可能性がある。しかも、処理ユニットが数多くあり、それぞれ個別の型のメッセージを扱っていることをおもえば、ある処理が失敗すれば、順序の狂ったメッセージが大量に生まれることになる。これでは、バッファオーバーランが起きることは確実になってしまう。場合によっては、処理中のメッセージを吸収するキューを使うこともできるが、これがうまくいくのは、メッセージングインフラに、キューの中から特定の条件でメッセージを読む機能が付いている場合だけだ。その場合なら、キューに対してポーリングをおこなって、欠けているメッセージが来ているかどうかを調べられる。
  • バッファオーバーランを避けるための確実な方法の一つは、アクティブな通知(acknowledgement)を使って、メッセージプロデューサーをスロットルすることだ。
  • 前述したように、一回に一つのメッセージだけを送信することは、きわめて非効率だ。もう少し効率的にするため、リシーケンサーが、プロデューサーに対して、バッファ内にあといくつ溜められるかを伝えることもできる。ただし、このためには、正しい順序のメッセージストリームにアクセスできなければならない。
  • このアプローチはTCP/IPに似ている。TCPプロトコルの主要な機能の一つは、ネットワークを通じたパケットのデリバリーを順序通りに行うことだ。
  • バッファオーバーランに対処するもう一つのやり方は、欠けているメッセージの代役を立てることだ。これがうまくいくのは、受け側がメッセージデータが「完璧でなくてもよい」ことを許容するか、正確さよりも速度の方が重要である場合である。たとえば、IPトランスミッション経由で声を伝えるのであれば、欠けているパケットを埋めてしまった方が、再送するよりもUXとしてはよいものになるだろう。
  • われわれアプリケーション開発者はネットワークを信用しがちだけど、メッセージングソリューションについて考える場合には、TCP/IPにも目を向けるとよいよ。