こんにちは!Cloud Spannerの世界へようこそ。
世界最高峰のデータベースなんて聞くと、なんだか冷たくて難解な機械の要塞を想像しちゃうかもしれないけれど、本質を掴んでしまえば、意外と身近で美しい仕組みで動いているんだ。
今回は、Cloud Spannerの心臓部の一つであり、巨大なデータの世界を矛盾なくまとめ上げる魔法のような仕組み「2相コミット(2PC:Two-Phase Commit)」についてお話しするよ。
「分散データベースって難しそう……」「複数のデータにまたがる更新って、どうやってズレないようにしているの?」
そんな疑問を持っている君も、ここをクリアすればCloud Spannerの基本はバッチリマスターできますよ!
さあ、温かいコーヒーでも飲みながら、リラックスして読み進めていこう。
—
1. 日常で例えるなら? 〜文化祭の「巨大モザイク画」づくり〜
まずは専門用語を一切使わずに、イメージを膨らませてみよう。
学校の文化祭で、全校生徒で協力して「巨大なモザイク画」を作ることになったと想像してごらん。
キャンバスがあまりに大きすぎるので、全校生徒をクラスごとのグループ(ここでは「スプリット」と呼ぶよ)に分けて、それぞれのグループがキャンバスの「担当エリア」を分担して描くことになったんだ。
さて、ここで問題発生。
「全体のデザインを一部変更することになった!」
もし、Aクラスのエリアだけを変えて、BクラスやCクラスのエリアを変え忘れたらどうなる? 全体で見たら絵がめちゃくちゃになっちゃうよね。
「全員が一斉に、同じタイミングで新しいデザインに変える」
これを確実に行うには、どうすればいいだろう?
ここに、リーダー役(コーディネーター)が登場する。
リーダーは、全員に向けてこう言うんだ。
「今からデザインを変えるよ! みんな、新しい絵を描く準備はいいかい?」
これが、Cloud Spannerが裏側で行っている「2相コミット(2PC)」の原型なんだよ。
—
2. Cloud Spannerの世界での「スプリット」と「トランザクション」
Cloud Spannerは、テラバイト、ペタバイト級のデータを管理するために、データを小さな断片(スプリット)に分割して、世界中のたくさんのサーバー(ノード)にバラバラに配置している。
普段、1つのスプリットの中だけで完結するデータ更新なら話は簡単なんだけど、現実のシステムでは「Aさんの口座からお金を引いて、Bさんの口座に足す」といったように、複数のスプリットにまたがるデータを一網打尽で更新したい場面がたくさんあるよね。これを分散トランザクションと呼ぶ。
ここでSpannerが絶対に守らなければならない鉄則が 「原子性(Atomicity)」。
つまり、「全部成功するか、全部なかったこと(ロールバック)になるか、そのどちらかしか許さない」 というルールだ。途中で片方だけ成功して電源が落ちました、なんてことは絶対に許されない。
その保証をするのが、これから解説する2つのステップ(2フェーズ)なんだ。
—
3. 2相コミット(2PC)の舞台裏:2つのステップ
では、Spannerのエンジンルームのなかを覗いてみよう。
複数のスプリットにまたがる書き込みが発生したとき、Spannerは内部で次のような「2段階の儀式」を厳粛に行っているんだ。
第1フェーズ:準備フェーズ(Prepare Phase)
リーダー役のサーバーが、関係するすべてのスプリット(担当チーム)にこう呼びかける。
- 「いいかい、これからこのデータを書き換えるよ。君たちの担当エリア、ロックをかけて、いつでも書き込めるように準備しておいてくれ!」
各スプリットは、自分のエリアに他の人が触れないように鍵をかけ(ロック)、ストレージの準備が整ったら、リーダーにこう返事をする。
- 「準備OKだよ!いつでもいける!」(これを「Vote: Yes」と呼ぶ)
もし、ここで「ストレージがいっぱいで書き込めないよ!」とか「別の処理で忙しくて無理!」というスが1つでもあれば、準備は失敗になる。
第2フェーズ:コミットフェーズ(Commit Phase)
すべてのスプリットから「準備OK!」の返事をもらったことを確認したら、リーダーは最終的なGOサインを出す。
- 「よし、全員準備できたね! それじゃあ、一斉にその変更を確定(コミット)してくれ!」
各スプリットは一斉にデータを書き換え、永久に記録する。そして、リーダーに「完了したよ」と伝える。これで、世界中のどこにあるデータであっても、完全に息を合わせた一貫性のある更新が完了するんだ。
—
4. なぜこれが「世界最高峰」のすごさなのか?
ここまで聞いて、「なんだ、当たり前のことをやっているだけじゃないか」と思ったかもしれない。その通り、概念自体はシンプルなんだ。
しかし、これを「世界中に何千台もあるサーバー」で、「数ミリ秒という圧倒的なスピード」で、しかも「止まることなく(高可用性)」やり遂げるのが、Cloud Spannerの恐ろしいところ。
さらにSpannerには、TrueTimeという極上の時計(誤差がほとんどない世界共通の時計)の仕組みがある。この2PCとTrueTimeが組み合わさることで、世界中のユーザーが同時にアクセスしても、矛盾のない「完璧な現在地」を保証できるんだ。これが、他のデータベースには真似できないSpannerの真髄なのさ。
—
まとめ
- スプリット:巨大なデータを分割して管理する、いわば担当チームのエリア。
- 分散トランザクション:複数のスプリットにまたがるデータ更新のこと。
- 2相コミット(2PC):「準備(Prepare)」と「実行(Commit)」の2つのステップを踏むことで、複数のエリアの更新を完全に同期させるプロトコル。
「複数の場所を同時に書き換えるときは、まず全員に準備をさせて、OKが揃ってから一斉に実行する」
この大原則さえ頭に入れておけば、Cloud Spannerの分散アーキテクチャの本質はもう君のものです。
基礎の土台がしっかり固まったね。この調子で、Spannerの広大な世界をもっと深く冒険していこう! 次のステップも、私と一緒に楽しくマスターしていこうね。
コメント