クラウドの一貫性って

CAP定理というのは、

  • Consistency
  • Availability
  • Partitions

という状態の2つまでしか達成できない。3つすべてを達成することはできないという定理である。例えばConsistency(一貫性)とAvailability(可用性)を同時に満足させるとPartitions(分散)を達成するのをあきらめるしかない。可用性と分散性を同時に満足させるにはConsistency(一貫性)をあきらめる。すなわちEventually Consistentな状態を受け入れる。

そーゆー状態を受け入れるとスケーラビリティを達成できるようになるので、巨大なデータセンターの中に安いPCサーバーを大量においてCAPのCを若干犠牲にしつつ、高速なデータ処理を行う。そのような計算モデルである。

クラウド時代の計算パラダイムRDBMSが30年間研究開発していたACIDパラダイムからCAPパラダイムへ大きく舵を切ったという意味で面白い。ちょうどコンピュータアーキテクチャにおける、CISCパラダイムからRISCパラダイムへ変遷していったようなイメージと重なる。

http://d.hatena.ne.jp/hyoshiok/20090520#p1

クラウドはぐっと来ないというタイトルですが、クラウドのツボは抑えてあって参考になりました。
「可用性と分散性を同時に満足させるにはConsistency(一貫性)をあきらめる。すなわちEventually Consistentな状態を受け入れる。」私は質の変化に過ぎない*1と思っているのですが、諦めるという表現のほうが、パラダイムシフトにおいて、ACIDが何にこだわっていて、何を実現できなかったのか、そのうちの何かを諦めることによって、次へと向かうそういうニュアンスですね。なるほど。
ところで、CAP定理のPartitionは分散としてしまうと理解の妨げになるような気がします。「"分断"に対する耐性」のことで、頭文字をとる時に、〜〜に対する耐性というと都合が悪いので、キーワード的に分断の部分だけが使われているだけだったと思います。

例えば、銀行のトランザクションはACIDの世界が絶対必要だ、そりゃそうだ、自分のお金が大体あっていればいいなんて話は受け入れられない。

http://d.hatena.ne.jp/hyoshiok/20090520#p1

そうなんですか。お金が大体あっていればいいなんてことはないんで、一貫性が崩れるなんてことはあってはならないわけですが、ConsistentからEventually Consistentへの変化においては、一貫性が著しく損なわれると考えた方がいいんでしょうか。
よくわからないので、ちょっと思うところを書いてみたいと思います。
というのは、かつて紙ベースで処理されていた時代においては、銀行の支店間取引や証券業務は、Consistentではなく、Eventually Consistentだったんじゃないかと思います。
たとえば、株式の購入を申し込むと、証券会社が代行して取引を「成立」させますが、入金はその後4日間猶予されていました。つまり、その間は、取引そのものは不変で成立しているにもかかわらず、その処理はキューの中にあって、最終決済、つまりコミットされるまでに十分な猶予が置かれていたわけです。そこでの一貫性はまさに、Eventually Consistentであって、Consistentではなかったわけです。かといって、証券取引に金銭上の不具合が生じることはありませんし、処理は毎日継続して行われ行きます。無論、そういうシステム下においては、複数の証券会社を使って不正な取引を演出することも可能であったので、ルールで規制されるわけですが・・・
思うのは、ACID特性というのは、コンピューターの進化において"実現した方が合理的"な機能、整合性を保証するための工夫であったように思います。逆に言えばチューリングマシンにおいては整合性を保ちながら柔軟に実装する方がより困難と思われていた機能のうちのひとつであるように思えます。もしEventually Consistentで実装可能なのであれば、その方がより人間的と感じられます。
ただ、短くて長い歴史の中でACIDが当然という空気があると、Eventually Consistentがとてもいいかげんで頼りなげに見えてしまうのはやむを得ないのかもしれません。

Eventually Consistentについて、もう少しおさらい

Eventually Consistentとについての説明としては下記の記述がとてもしっくりきます。

丸山先生の資料から引用すると、「システム内に、一時的にConsistentでない状態が生まれても、ある期間の後には、Consistentな状態になるような性質を、Eventually Consistencyという。」とある。
...中略...
丸山先生の資料から引用する。

  • クラウド・システムがConsistencyにインパクトを与える状況というのは、基本的には、Availabilityを支える複数のレプリカ・ノードに同一のデータを送ろうとする時に生ずる
  • あるノードでは書き込みに成功しても、他のノードでなんらかの事情で書き込みに失敗すれ

ば、システム内に異なるデータの状態が併存し、Consistentでない状態が生まれる
...中略...
厳密なConsistentというのも、深く考えるとタイムラグが極小であるようなEventually Consistentでしかありえない

http://d.hatena.ne.jp/jyukutyo/20090430/1241174854

クラウドにおいても、CAP定理下で発生する一貫性問題は、ある期間の後に一貫性を復元できる仕組みを持たなかればなりません。それがEventually Consistentということになります。
では、Eventually Consistent下で銀行業務が成り立たない理由はなんでしょうか。シナリオとしては、

  • 関東と関西のネットワークが分断されたとする (partition)
  • それでも、関東の支店と関西の支店は営業を継続する (availability)

と仮定すると、ある口座の保持者は関東の支店と関西の支店の両方から口座の全額を別の口座に送金する処理を行ったとする。
分断中に、それぞれは受け取り側の口座からすべての金銭を受け取ることができる。すると、保持している金額の2倍の金銭を取得できてしまう!
Eventually Consistentの概念下では、ネットワークが復活すれば、送金処理が2回行われているので、口座の保持者の残高はマイナスになるわけで、いわば無条件ローンの設定がされることになります。そこで一貫性は復活するわけです!
つまり、Eventually Consistentでも一貫性は保たれるわけですが、銀行業務ではその時間のロスが許容しがたい結果を生んでしまうため、その時間のロスは無視できるぐらい小さい必要があるわけです。
じゃぁ、ネットワークがなかった時代はどうだったかというと、同時に分断された支店で処理をするツールがなかったんですねぇ。

Webでのバーター

クライアントが不整合を許容でるきるか否かはアプリケーションに依存する. 特によく知られたケースとして, ユーザに認知できる範囲で整合性があればいいウェブサイトのシナリオがある; 不整合ウィンドウは顧客が次ページに移動する時間の期待値より小さければいい. これは時ページのロードまでにシステム内で更新を広めればよいことを意味する.

http://www.hyuki.com/yukiwiki/wiki.cgi?EventuallyConsistent

まぁ、銀行システムを組むわけじゃないんで。クラウドを使うまでもなく、高可用性を保とうする試みでは、一貫性が崩れるのに目をつむるといいんですけど、クライアントさんに理解してもらうのはなかなか難しいです。
クラウドとは別次元の話ですが、バーターで失うものをちゃんと定量的に判断したいよね。って思うことがよくあります。
コメントラッシュ時など、更新と閲覧が頻発するようなバースト的な負荷のときは、サービスを落とさないために負荷をみてキャッシュを発動させますんで、一時的な遅延を受け入れてくださいという話をさせていただくんですが、なかなかこのバーターを理解してもらえないんですよね。特に、ファーム構成にして複数のフロントエンドを持ちながら高可用性を実現しようとすると、キャッシュするタイミングでコメント数とか最新コメントとかが変わって、リロード時にコメント総数が増減するとか、そんなことになってしまったりという・・・。データフィードを別に持てばそういう意味での高可用性をアップすることも可能なんですけど、最初から想定するのはさすがに難しい・・・そこで、数分の遅延を覚悟してシステムを組めば、数十倍の集中アクセスに耐えられるようになって結果的にサービス品質はいいと思うんですが、あぁ、まぁ、説明が下手というか、もう少しわかりやすいプレゼン資料を作ればいいんでしょうけど。

そういえば、最近のTw、Service Unavailableよりも遅延の方が増えたかな?

*1:というかそこが一番重要