【入門編】 負荷ベースの分割 – Cloud Spanner

こんにちは!Cloud Spannerの世界へようこそ。
チーフアーキテクトの私です。

「Cloud Spannerって、なんだかすごそうだけど難しそう……」
そんな風に思っていませんか?大丈夫、安心してください。今日ここでお話しする「負荷ベースの分割」さえマスターすれば、Spannerの本質が手に取るようにわかりますよ。ここをクリアすれば、あなたのCloud Spannerの基本理解はバッチリマスターできます!

難しい数式や小難しい専門用語はちょっと置いておいて、まずは私たちの身近な「ある光景」からお話を始めましょう。

—

人気のラーメン店で学ぶ「スプリット」の概念

想像してみてください。あなたが街で一番人気の、とっても美味しいラーメン店の店主だとします。

最初は小さなお店で、あなた一人で切り盛りしていました。お客さんが数人なら、注文を聞いて、麺を茹でて、配膳して……と、すべて一人で回せますよね。これが、データベースでいう「1台のサーバー」の状態です。

しかし、噂が噂を呼び、お店の外には大行列!
カウンターは満席、あなたは汗だくで目が回りそうです。この状態を、エンジニアの世界では「ホットスポット(特定の場所に負荷が集中している状態)」と呼びます。

さあ、どうしますか?

「もう無理!店を閉める!」……なんて言ったら大ひんしゅくですよね。
優秀なあなたなら、こう考えるはずです。

  • 「これ以上行列が長くなったら、隣の店舗スペースも借りよう」
  • 「厨房を2つに分けて、Aチームは醤油ラーメン担当、Bチームは味噌ラーメン担当にしよう」

この「お店(データ)をいい感じに区切って、複数のスタッフ(サーバー)で分担して作業する仕組み」こそが、Cloud Spannerの心臓部である「スプリット(分割)」の正体です。

—

Cloud Spannerの裏側:データはどうやってお引越しするの?

Cloud Spannerは、世界中にデータをばら撒いて超高速で処理してくれる、いわば「超絶優秀なメガチェーン店」のようなデータベースです。

Spannerの中では、データはいつもきれいに整理されて保管されています。例えば、ユーザーIDの順番に、本棚の辞書のようにデータが並んでいるとイメージしてください。

ここで、こんな事件が起きるとします。
「ある日突然、特定のインフルエンサーがあなたのサービスで爆買いを始めました。その人のデータ周辺にだけ、世界中からのアクセスが集中します!」

普通のデータベースなら、そのデータが置いてあるサーバーのCPUが悲鳴を上げ、フリーズしてしまうところです。しかし、そこは世界最高峰のSpanner。

Spannerの頭脳(監視システム)は、こう囁きます。
> 「おっと、本棚の『M〜P』のエリアにアクセスが集中して、担当のサーバー君が泣きそうになっているぞ。よし、今すぐそのエリアを真っ二つに分割して、隣のヒマそうなサーバー君に半分お引越しさせよう!」

これが、今回のテーマである「負荷ベースの分割(Load-based splitting)」です。

誰も手動で設定していません。Spannerが自分で「今、どこが混雑しているか?」を常に監視し、自動的にお店のレイアウトを変え、スタッフの仕事を割り振っているのです。

—

初学者が陥りがちな罠:ラーメン店の「行列の並び方」に注意!

ここまで聞いて、「なんだ、Spannerって全部自動でやってくれる魔法の箱なんだ!」と思いましたよね。

はい、半分はその通りです。でも、私たちプロのエンジニアには、「Spannerの自動お引越し機能がうまく働かないうっかりミス」を防ぐ知恵が必要です。

先ほどのラーメン店の例に戻りましょう。
もし、お客さんが全員「名前のアルファベット順」に、しかも「Aさん、Bさん、Cさん……」と、完全にきれいな順番でしか来店しなかったらどうなるでしょう?

実は、コンピュータの世界では、データを保存する際に「キー(目印)」を使います。よくある失敗が、このキーに「時間の経過とともに必ず増えるもの(例:現在時刻、連番のIDなど)」を使ってしまうケースです。

— 【アンチテーゼの例】常に増え続けるIDや時間をテーブルの先頭(主キー)にしてしまう
CREATE TABLE AccessLogs (
LogTime TIMESTAMP, — ★これがいけない!常に「今」の時間が書き込まれるため、最後のデータにしかアクセスが集中しない
UserId STRING(64),
Action STRING(256)
) PRIMARY KEY(LogTime, UserId);

これをやってしまうと、世界中からのアクセスが「今この瞬間のデータ」という、たった1つの一点(ホットスポット)に集中してしまいます。

Spannerは優秀なので、「うわっ、ここ混んでるな!分割しなきゃ!」と頑張るのですが、データが「常に一番後ろ(現在時刻)にしか追加されない」構造になっていると、うまく分割して他のサーバーに仕事を分散させることができません。まるで、一本の狭いレジに全員が並んでしまうようなものです。

—

華麗に解決!プロが教えるスマートなデータデザイン

じゃあ、どうすればいいのでしょうか?答えは簡単です。
「行列をいくつもの列に分散させればいい」のです。

例えば、データの先頭(主キー)に「ランダムな文字列(ハッシュ値など)」を少しだけ混ぜてあげます。

— 【模範解答の例】ランダムなプレフィックスを混ぜて、負荷を綺麗に散らす
CREATE TABLE AccessLogs (
ShardId INT64, — ★ここに「0〜9のランダムな数字」を入れる!
LogTime TIMESTAMP,
UserId STRING(64),
Action STRING(256)
) PRIMARY KEY(ShardId, LogTime, UserId);

こうすると、データが `ShardId = 0` のエリア、`1` のエリア、`2` のエリア……と、最初からパカーッと綺麗に散らばって保存されます。

アクセスが来ても、それぞれの担当サーバー(スプリット)に綺麗に負荷が分散されるため、Spannerの「負荷ベースの分割」機能が最高に力を発揮できるようになるのです。

—

まとめ:今日の復習

  • スプリットとは?:データ量やアクセスが集中したときに、自動でデータを分割して別々のサーバーにお引越しさせる機能。
  • 負荷ベースの分割:人間が指示しなくても、Spannerが勝手に混雑具合を見ていい感じにバランスを取ってくれるすごいやつ。
  • 気をつけること:アクセスが1箇所に固まりすぎるデザイン(現在時刻の連番など)を避け、綺麗にバラける工夫(ランダム化など)をしてあげると、Spannerは限界までパフォーマンスを発揮してくれる!

いかがでしたか?
「負荷ベースの分割」という言葉の裏にある、Spannerの優しくも頼もしい自動化の仕組みがイメージできたのではないでしょうか。

ここをクリアしたあなたなら、もうCloud Spannerのアーキテクチャの核心を理解したも同然です。
自信を持って、次のステップに進んでいきましょう!質問があれば、いつでもチーフアーキテクトの私に声をかけてくださいね。

コメント

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