Your Coffee Shop Doesn't Use Two-Phase Commit(2005)
March 12, 2023非同期処理を、スターバックスの注文からコーヒーの提供までの流れにたとえたアネクドートである。 注文をうけたレジの店員は、どの客の注文か分かる目印をコーヒーカップに書き、カップをエスプレッソマシンの上にならべる。 客はバリスタのいるカウンターに移動し、レジの店員は次の顧客の注文をうけつける。 バリスタは、ならべられたカップをとり、コーヒーを注ぎ、客に提供する。
レジの店員とバリスタは非同期にはたらいている。 バリスタのコーヒーの提供が滞っても、レジの店員は注文をうけることができる。 カップの列が長くなれば、バリスタの人数を増やせば、レジの店員に影響することなく、より速くコーヒーを提供できる。 それはキューで通信するプロデューサーとコンシューマーのようである。
スターバックスが採用していない2相コミット(Two-Phase Commit)は、複数のノードが参加するトランザクション処理をアトミックにするためのアルゴリズムである。 2相と呼ばれるのは、複数ノードが各自のデータベースにデータを書き込んだあと、2つのフェーズをかけてトランザクションを終了するからである。 フェーズ1では、ノードの状態を管理するコーディネータが各ノードにコミット可能か問い合わせる。 すべてのノードがコミット可能であれば、フェーズ2でコーディネータは、各ノードにコミットをリクエストする。
2相コミットをスターバックスにたとえるなら、注文をうけた客はコーヒーを受けとるまでレジの前に立ち、コーヒーができあがるとお金とコーヒーを交換するものである。 店員が非同期に働くときにくらべて、単位時間に対応できる顧客の数は減る。
非同期処理によってスループットを上げられるが、同時に、エラー処理が難しくなる。 プロデューサとコンシューマが疎結合になると、コンシューマーで起きたエラーをプロデューサに伝達することが難しくなる。 注文した後に客がお金がないことに気づいた場合や、エスプレッソマシンが故障する場合、同期的な接客時よりも対応が難しい。
スターバックスは、conversation patternのたとえでもある。 conversation patternは短時間の同期的なインタラクションと長期間の非同期なインタラクションからなる通信である。 客はレジの店員と同期的に会話し、会話より長い時間バリスタのいるカウンターでコーヒーを待つ。 Amazonで商品を注文し、品物が届くまでのシステムの処理もconversation patternといえる。
店員にとってスターバックスの経験は非同期であるが、客はコーヒーを受けとるまで店を出られないので、客の経験は同期的である。 また、ユーザーからみて同期的なシステムの実装が非同期処理であることがある。 Half-sync, Half-asyncパターンは、非同期に動くシステムがバッファに出力し、同期的な振る舞いを期待する側がバッファから出力を受けとらせることで、この非対称性を解決する。 まるで、バリスタが出来あがったコーヒーをカウンタに置くように。
論文のリンク
雑記
非同期処理をソフトウェア開発者以外に説明するときに便利かもしれない。