こんにちは!Cloud Spannerの世界へようこそ。
チーフアーキテクトの私です。
「世界中のユーザーからの膨大なリクエストを、一瞬たりとも止まることなく処理し続けるデータベース」――。そんな夢のようなシステムを実現するのが、GoogleのCloud Spannerです。
その心臓部である「分散クエリの仕組み」は、一見すると難解なブラックボックスに思えるかもしれません。でも大丈夫。ここをクリアすれば、Cloud Spannerの基本はバッチリマスターできますよ。
今回は、専門用語をできるだけ封印し、私たちの日常にある「ある光景」に置き換えてその本質を解き明かしていきましょう。
—
1. 巨大な本棚と「スプリット」の概念
まず、Cloud Spannerがデータをどう持っているかを知る必要があります。
一般的なデータベースは、1台のパソコン(あるいはサーバー)の中にデータを詰め込みます。しかし、Spannerは違います。地球上に広がる数千、数万台のサーバーという「巨大な倉庫」にデータを分散させて保管しています。
ここで、Spannerのデータ管理の最小単位である「スプリット(Split)」が登場します。
> 日常の例え:超巨大な辞書
> 想像してください。5,000万語が載っている、世界で一番分厚い辞書をあなたが持っているとします。これを1人で最初から最後まで読んで「『Apple』を探して」と言われたらどうなりますか? 何日かかるかわかりませんよね。
> そこで、この辞書を「A〜C」「D〜F」……と、50冊の小冊子にバラして、50人のアルバイトスタッフに配りました。「私の担当は『M〜P』だから、その中から探すね!」と全員が一斉に作業を始めます。
Spannerにとっての「スプリット」とは、まさにこの「小冊子にバラされたデータの束」のことです。データが増えてくると、Spannerはこのスプリットを自動的に分割し、別のサーバーへお引越しさせます。データを無限にスケールさせられる秘密はここにあります。
—
2. オプティマイザの正体は「超優秀なプロジェクトマネージャー」
私たちがSpannerに対して「こういうデータが欲しい!」とSQLという言語で命令(クエリ)を投げたとき、裏側で何が起きているでしょうか?
ここで登場するのが「オプティマイザ(Optimizer)」です。
彼は、いわば「超優秀なプロジェクトマネージャー」です。
1冊の辞書ならまだしも、何万冊ものスプリット(小冊子)にデータが散らばっているとき、「どのスタッフに、どの範囲の調査を頼むか」「どうやって効率よく情報を集めるか」を指示しなければなりません。
オプティマイザの仕事は、私たちが投げた雑な命令を「最も速く、最も無駄のない、並列作業のスケジュール(実行プラン)」に翻訳することです。
—
3. クエリが複数のスプリットを駆け抜ける瞬間
では、オプティマイザが作る「実行プラン」が、どうやって分散クエリを実行しているのか見てみましょう。
例えば、「2023年に東京で発生した売上の中で、1万円以上のものをすべて集めて!」という命令を出したとします。
ステップ1:分解とバラマキ(分散)
プロジェクトマネージャー(オプティマイザ)は、データが格納されているすべてのスプリット(小冊子)に向けて、一斉にこう指示を出します。
「おい、お前の担当エリアの中から、『2023年』かつ『東京』かつ『1万円以上』のデータだけを抜き出して、私に報告してくれ!」
ステップ2:並列での局所作業(パラレル実行)
ここがCloud Spannerの真骨頂です。
世界中に散らばる何百、何千ものサーバーが、全く同時に(並列で)自分の担当エリアをスキャンし始めます。誰かがサボることも、順番待ちをすることもあり得ません。みんな一斉に作業します。
ステップ3:集約(マージ)
各サーバーから「うちのエリアには、該当するデータが3件ありました!」と報告が上がってきます。プロジェクトマネージャーはそれらをパズルのように素早くまとめ上げ、あなたに結果を返却します。
この一連の流れを、Spannerはわずか数ミリ秒の出来事としてやり遂げてしまうのです。
—
4. 実際にクエリの「設計図」をのぞいてみよう
Spannerでは、オプティマイザがどんなスケジュールを立てたのかを、`EXPLAIN`という命令でいつでものぞき見ることができます。
— 実際に実行する前に、オプティマイザの計画(プラン)を覗き見するコマンド
EXPLAIN
SELECT user_id, amount
FROM sales
WHERE store_location = ‘Tokyo’ AND amount >= 10000;
【実行計画のイメージ(頭の中の設計図)】
Distributed Union (分散して集約するよ)
+- Local Distributed Check (各スプリットでの並列フィルタリング)
+- Table Scan on sales (「sales」テーブルをスキャン)
この設計図の一番上にある `Distributed Union` という文字が見えますか?
これが、「お、今回は複数のスプリットに仕事を分担させて(分散)、最後に合体させる(ユニオン)賢い作戦で行くぞ!」という、オプティマイザの気概を表しています。
初心者のうちは、この実行計画の細かい記号をすべて覚える必要はありません。ただ、「ああ、今この瞬間も、Spannerのマネージャーが裏で綺麗に仕事を分割してくれているんだな」とイメージできれば、それだけで十分合格点です。
—
5. 先輩エンジニアからのアドバイス:Spannerを味方につけるために
Cloud Spannerの分散クエリを最高効率で動かすための極意。それは、「マネージャー(オプティマイザ)を迷わせないこと」です。
- データをきれいに並べておく(プライマリキーの設計)
辞書の例で言えば、バラバラの順番でページが混ざっていたら、スタッフも探しにくいですよね。検索条件になりやすい項目を主キーの先頭に配置してあげることで、オプティマイザは「あ、あのスプリットだけでいいや」と、不要なサーバーに声をかけなくて済みます(これを無駄なスキャンを避ける「プルーニング」と呼びます)。
Spannerは、私たちが余計な心配をしなくても、大部分の最適化を自動でやってくれる最高の相棒です。しかし、その裏側で「データを小さなスプリットに分け、優秀なマネージャーが並列のスケジュールを組んでいる」という原則を知っているだけで、書くSQLの質が劇的に変わります。
さあ、恐れることは何もありません。
今日からあなたも、Cloud Spannerの分散ワールドを自在に操るエンジニアの一員です!
コメント