「いつでも使える(可用性)」と「いつでも正しい情報を参照できる(一貫性)」の両立
ご存知の方も多いかと思いますが、分散コンピュータシステムのノード間の情報保持における法則として、CAP定理というものがあります。下記引用します。
ノード間のデータ複製において、同時に次の3つの保証を提供することはできない。
一貫性(Consistency)
全てのデータ読み込みにおいて、最新の書き込みデータもしくはエラーのどちらかを受け取る。
可用性(Availability)
ノード障害により生存ノードの機能性は損なわれない。つまり、ダウンしていないノードが常に応答を返す。単一障害点が存在しないことが必要。
分断耐性(Partition-tolerance)
システムは任意の通信障害などによるメッセージ損失に対し、継続して動作を行う。通信可能なサーバーーが複数のグループに分断されるケース(ネットワーク分断)を指し、1つのハブに全てのサーバーがつながっている場合は、これは発生しない。ただし、そのような単一障害点のあるネットワーク設計は可用性が成立しない。
Eric Brewer氏は、2000年7月19日のPODC keynoteで、このCAP定理を発表しました。ぜひオリジナルのスライドもご覧ください。データベース(RDBMS)におけるトランザクションの特性であるACID[1]では厳密な一貫性を重んじるあまり可用性が損なわれていた点に着目し、大規模分散システムの特性として、BASE[2]という概念を提言しています。そして、ACID vs BASEは、On/Offの関係ではなく、情報システムは、ACIDからBASEまでの間のどこかの特性を持つと言っています。例えば、全体的にはBASE寄りのシステム設計だけど、この更新処理だけはACID寄り、という具合でしょうか。
"But I think it's a spectrum"というコメントが重要な気がしますね。
spectrumは「どちらか一方ではなく連続的な濃淡がある」というような解釈でいかがでしょうか
(引用元:https://people.eecs.berkeley.edu/~brewer/cs262b-2004/PODC-keynote.pdf)
このような文脈の中で、CAP定理は、「3つのうち同時に満たせるのは2つまで」という法則とともに説明されます。Eric Brewer氏は、CAP定理の本質的なアイデアについて、その続編となる記事を書き、「CAPと通信の遅延」というセクションにおいて「CAPの本質はタイムアウトが発生した時に現れます」とまとめました。プログラムは、「処理を中断して可用性を犠牲にする」のか「処理を進めて一貫性を犠牲にする」という2択を迫られるということです。
どちらの方法を選択するかはケースバイケースですが、「可能な限りユーザーの負担を軽減させたい」という観点に立って、この2つの方法を検討してみます。
あるWeb画面があり、情報を入力して更新ボタンをクリックするとします。「処理を中断して可用性を犠牲にする」という考え方で設計した場合、何らかの理由で情報が更新できなければ、すぐに「更新できませんでした。再度更新ボタンを押してください」というようなメッセージが表示されることになります。その場合、利用者は自分で再度更新ボタンをクリックしなければなりません。
一方、「処理を進めて一貫性を犠牲にする」考え方で設計された場合、再度更新ボタンをクリックすることなく情報の更新が完了します。一般的には後者の方が手間が少ないと感じることが多いでしょう。
この「処理を進めて一貫性を犠牲にする」パターンでの利用者は、更新ボタンを押したタイミングにおいて、情報を更新したつもりになっています。しかし、実際はまだ情報は更新されておらず、バックエンドのシステムが情報更新の再試行を自動で行っているのです。つまり、一貫性が損なわれている状況が発生しています。具体的には、利用者が更新ボタンを押した後、バックエンドシステムが情報更新を完了するまでに、データベースの情報を参照した場合、更新がまだ反映されていないため、古い情報が参照される可能性があります。
当該記事でも触れられているように、銀行のATMのような、厳密な一貫性を優先して設計されているように見えるサービスであっても、実際には一貫性よりも可用性が重視され、「処理を進めて一貫性を犠牲にする」方法がとられているケースが紹介されています。興味のある方はぜひ当該記事をご覧ください。
ここでご紹介したかったのは、ベストプラクティスというよりも、根本的な考え方です。ACID vs BASEの実装例において、「これがベストプラクティスだ! 」とご紹介できるような事例があれば簡便なのですが、実際には機能やシステム構成の制約などから「どういう濃淡をつけて実装するか」をその都度考える必要が出てきます。
本稿でこれからご紹介する設計手法は、こうした考え方が背景にあることを心に留めておいていただけると、より良く理解でき、より適切にご活用いただけると思います。
注
[1] ACIDとは、信頼性のあるトランザクションシステムの持つべき性質として1970年代後半にジム・グレイが定義した概念で、これ以上分解してはならないという意味の原子性(atomicity、不可分性)、一貫性(consistency)、独立性(isolation)、および永続性(durability)は、トランザクション処理の信頼性を保証するために求められる性質であるとする考え方である。
[2] BASEは、Basically Available, Soft-state, Eventual consistency の略。CAP定理同様、Eric Brewer氏による2000年7月19日 PODC keynoteで触れられた。
