【入門編】 分散クエリ実行プラン – Cloud Spanner

こんにちは!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の分散ワールドを自在に操るエンジニアの一員です!

コメント

タイトルとURLをコピーしました