Mais conteúdo relacionado Semelhante a アプリ開発者、DB 管理者視点での Cloud Spanner 活用方法 | 第 10 回 Google Cloud INSIDE Games & Apps Online (20) Mais de Google Cloud Platform - Japan (20) アプリ開発者、DB 管理者視点での Cloud Spanner 活用方法 | 第 10 回 Google Cloud INSIDE Games & Apps Online2. 自己紹介
佐藤 貴彦 / Sato, Takahiko
Data Management Specialist
これまで複数の製品ベンダーにて、ネットワークやデータベースを中心としたインフラ周りの支援
に従事。Google Cloud では、お客様が GCP 上のデータベース系サービスをうまく活用できるよ
う、お客様の話を聞き一緒に議論していくことが仕事。
専門分野
データベース及びデータ処理全般( RDBMS、NoSQL、DWH、Hadoop )
ネットワーク
趣味
クライミング、ボルダリング
3. ● Cloud Spanner 超概要
● Cloud Spanner 新機能紹介
● Cloud Spanner ツール紹介
● 新機能 & ツールデモ
● RDBMS の延長で考える Cloud Spanner
○ テーブルのしくみ
○ インデックスのしくみ
○ 外部キー制約のしくみ
○ 自動シャーディングのしくみ
本日のアジェンダ
RDBMS
5. GCP のデータベース / データストア関連サービス
Cloud
Storage
Cloud
Memorystore
BigQuery
リレーショナル非リレーショナル オブジェクト
データ
ウェアハウス
オブジェク
ストア
マネージド
Redis & memcached
Cloud Datastore /
Cloud Firestore
サーバーレスで
スケーラブルな
ドキュメントストア
Cloud
Bigtable
低レイテンシで
スケーラブルな
ワイドカラムストア
Cloud
SQL
マネージド
MySQL &
PostgreSQL &
SQL Server
Cloud
Spanner
スケーラブルで
可用性の高い
ミッションクリティカ
ル
RDBMS
サーバーレスで
スケーラブルな
エンタープライズ
DWH
インメモリ
今回のテーマ
6. Cloud Spanner とは、リレーショナル データベースの
構造の利点と、非リレーショナルのスケーラビリティを
組み合わせた、新しいデータベース
● スキーマ、ACID トランザクション、
SQL をサポート
● スケールアウト / インが任意に実施可能
● フルマネージドなデータベース
● 非常に高い可用性を提供
○ SLA 99.99 % 〜 99.999 % を提供
○ メンテナンス ダウンタイム無し
Cloud Spanner の特徴
性能
スケーラビリティ
SQL
運用管理
8. Cloud Spanner の裏は 1 ノードをゾーンごとに配置 1
ゾーン a ゾーン b ゾーン c
node1 node1 node1
Cloud Spanner
インスタンス
1 ノード
1 ノード立てるとゾーンごとに 1 つずつ起動しており、
1 ノード構成であっても可用性を保つ設計になっている。
東京リージョン (asia-northeast1)
9. Cloud Spanner の裏は 1 ノードをゾーンごとに配置 2
東京リージョン (asia-northeast1)
ゾーン a ゾーン b ゾーン c
Cloud Spanner
インスタンス
1 ノード
node1 node1 node1
分散ストレージ
(Colossus)
分散ストレージ
(Colossus)
分散ストレージ
(Colossus)
実際のデータは分散ストレージである Colossus に保存されるため、
仮にノードで障害が起こっても、データへ影響は無し。
10. Cloud Spanner の裏は 1 ノードをゾーンごとに配置 3
ゾーン a ゾーン b ゾーン c
Cloud Spanner
インスタンス
1 ノード
node1 node1 node1
分散ストレージ
(Colossus)
分散ストレージ
(Colossus)
分散ストレージ
(Colossus)
コンピュート
ストレージ
コンピュート ノードとストレージは切り離されており、
それぞれ独立して性能と可能性を担保。
東京リージョン (asia-northeast1)
11. ノード追加はコンピュート ノードが起動するだけ
node1
ゾーン a ゾーン b ゾーン c
node2 node1 node2 node1 node2
2 ノード目追加
数秒で起動完了
Cloud Spanner
インスタンス
2 ノード
東京リージョン (asia-northeast1)
分散ストレージ
(Colossus)
分散ストレージ
(Colossus)
分散ストレージ
(Colossus)
データは分散ストレージ経由で共有されているため、ノードの
追加と削除は速やかに完了する。
コンピュート
ストレージ
12. ユーザーはインスタンスの内側を意識することなく利用
Cloud Spanner API
の Front End
ユーザー
アプリケーション
ユーザー
アプリケーション
オンプレミスのデータセンタ
ユーザー
アプリケーションVPN
Cloud Spanner への接続は、Cloud Spanner API 用の Front End へ接続するだけ。
DNS の設定や接続先ゾーン、接続先ノードを意識する必要は一切なし。
東京リージョン (asia-northeast1)
クライアント
分散ストレージ
node1 node2
13. ● Cloud Spanner は、RDBMS が提供しているように、 SQL によるクエリ
及びトランザクション処理が可能
● Cloud Spanner の提供するトランザクション分離レベルと整合性
○ Serializable(シリアライザブル) + External Consistency (外部整合性)
○ ユーザーが明示的にロック取らなくてもアノマリーは発生しないし、トランザク
ション間の時間の順序は入れ替わらない
● Cloud Spanner はロックの粒度を可能な限り最小限にしている
○ InnoDB が取得するロックを例にすると、Cloud Spanner ではギャップロック
相当は行うが、ネクストキー ロック相当のものは取得しない
○ 行ロックではなくてセル単位でのロック
Cloud Spanner が提供するトランザクションとロック概要
15. 外部キー制約(Foreign Keys)が 追加
特徴
● 外部キー制約が DDL で定義できるようになった
● 非キー列や複数テーブル間で外部キー制約を実現
○ 補足:これまでは Cloud Spanner のインターリーブ機能(後述)
を利用して、外部キー制約に似たことを実現していた
player_items
PK player_id STRING(32)
PK, FK item_id INT64
quantity INT64
items
PK item_id INT64
name STRING(255)
price INT64
16. マネージド バックアップ リストア
特徴
● インスタンス内の DB 単位でバックアップ取得
可能
● バックアップは、インスタンスに紐付いた専用領
域に保管され、最大 1 年間保持可能
● 同一インスタンス及び、同一リージョンの別の
インスタンスに対してリストア可能
● リストア時間は非常に高速
18. 注意点
● 現在まだベータ版
○ 現時点でサポートされるクライアント ライブラリは Java、Go、C++
○ 外部キー制約やパーティション DML など一部の機能は未対応
● エミュレータと実機との動作の違い
○ Cloud Spanner エミュレーターでは内部的なロックの取り方が異なるため、
トランザクションの競合をテストするような用途には向かない
○ エラーメッセージの出方が異なる場合がある
Cloud Spanner エミュレーターベータ
の注意点
21. ● 対話形式で Cloud Spanner に対して SQL を実
行できるツール
○ https://github.com/cloudspannerecosy
stem/spanner-cli
● MySQLの mysql コマンド、PostgreSQL の
psql コマンドに似たもの
● Cloud Spanner が直接提供しているツールで
はなく、Cloud Spanner Ecosystem という
Cloud Spanner のユーザーコミュニティで公開
されている
各種検証に便利な spanner-cli
27. ゲームの DB を想定し 3 つのテーブルを用意
players: ゲームのプレイヤー情報
player_items: 各プレイヤーが保持するアイテム
items: 各アイテムのマスター情報
本資料で利用するサンプルスキーマ
players
PK player_id STRING(32)
name STRING(256)
level INT64
money INT64
player_items
PK player_id STRING(32)
PK, FK item_id INT64
quantity INT64
items
PK item_id INT64
name STRING(255)
price INT64last_used TIMESTAMP
29. データベースにおいて、テーブル(表)は様々なデータ構
造で保存されている。
どのような形で保存されているかは、RDBMS によっても
異なる。また Cloud Spanner (以降 Spanner と省略) は
典型的な RDBMS とは異なる手法で保存している。
データベースは様々な構造を使ってデータを保持する
player_id name level money
1 bob 1 100
2 alice 2 0
5 carol 1 50
10 steve 2 10000
15 oscar 2 1000
20 dave 3 700
players
CREATE TABLE players (
player_id STRING(36) NOT NULL,
name STRING(256) NOT NULL,
level INT64 NOT NULL,
money INT64 NOT NULL
) PRIMARY KEY (player_id);
players テーブルの DDL の例
テーブルに入っているデータのイメージ 実際にはどのように保存されてる?
RDBMS
30. ● PK 列(主キー列)を1 つ持つテーブル
● RDBMS であれば PK 列は B+Tree のデータ構造になっ
ている
● B+Tree では PK 列でソートされた構造
● 例えば Write 時は B+Tree をたどった先のブロックを読み
出して該当レコードを修正し書き戻す
RDBMS のテーブルは B+Tree 構造
PK PK PK PK
record
record
record
record
1
2
10
5
一般的な RDBMS における
PK と各行のつながり
物理的な配置は分断している
可能性ありランダム I/O
player_id name level money
1 bob 1 100
2 alice 2 0
5 carol 1 50
10 steve 2 10000
15 oscar 2 1000
20 dave 3 700
players
15
PK
record
1 2 5 10 15
リーフをたどると
PK がソートされている
RDBMS
31. ● レコードを PK の B+Tree と物理的に同じ場所に配置している構造もある
○ クラスタ化インデックス- Clustered Index
○ InnoDB はこの仕組みでPK と行を格納している
○ RDBMS によってはこの構造での保存を指定するオプションもある
● クラスタ化(Clustered)とは、まとめて配置すること
補足:RDBMS も実装によって異なるテーブル構造
クラスタ化インデックス
な PK とレコード
record
record
record
record
PK PK PK PKPK PK PK PK
record
record
record
record
PK
record
PK とレコード
MySQL
(InnoDB)
PostgreSQL
32. Spanner のテーブルは LSM Tree と Sorted-String 構造
record
PK record
PK record
PK record
PK record
ソートされているため、どのブ
ロックにデータが入ってるか容
易に特定できる
1 record
2 record
5 record
10 record
15 record
20 record
30 record
35 record
PK
・・・
物理的にPK 順に
ソートして保存 過去に更新されたデータほど
下の階層にマージされていく
merge
merge
record
PK record
50 record
PK
write
flushmemory
disk
player_id = 5 はどこ?
● Spanner のテーブルは PK 列で物理的にソートされた状態で格納される
○ 一般的には Sorted-String Table (SSTable) と呼ばれる種類のデータ構造
● Log Structured Merge Tree (LSM Tree) という階層構造と組み合わせて保持
○ Write 時は元のデータ(を含むブロック)を直接変更せず、一旦別で書き出したあとバッ
クグラウンドでマージしていく
33. ● 典型的な RDBMS は、PK 列で論理的にソートされた状態で保存している
● Spanner では、PK 列で「物理的にソート」された状態で保存している
○ テーブル全体を B+Tree ではなく LSM Tree という構造で保持
Spanner のテーブルは常に PK で物理的にソート
player_id name level money
1 bob 1 100
2 alice 2 0
5 carol 1 50
10 steve 2 10000
15 oscar 2 1000
20 dave 3 700
players
Spanner では
一定のレンジスキャンは
比較的得意
Spanner では書き込みの
スループットを稼ぎやすい
💡メモ
上位○○件や下位○○件
といった、必要な処理も対
応しやすい
35. ● 一般に RDBMS では、非キー列(PK 列以外の列)はバラバラに格納されているので、非キー
列の値で検索する場合、全件取り出して調べることになる
● 検索対象の列からPK 列を逆引きできるようにするのがセカンダリインデックス
● 単にインデックスと呼ばれることも多い(以下インデックスと略)
データベースにおける(セカンダリ)インデックスとは
player_id name level money
1 bob 1 100
2 alice 2 0
5 carol 1 50
10 steve 2 10000
15 oscar 2 1000
20 dave 3 700
players
player_idname
1bob
2alice
5carol
10steve
15oscar
20dave
idx_players_name インデックスが無い場
合、全ての行を調べる
必要がある
対象列 PK を逆引きする
インデックス
例)name が ‘steve’ の人
の money を調べたい
インデックスをたどれば簡
単に探せる
36. 実はインデックスもテーブルも同じ構造。
RDBMS ではどちらも B+Tree ベースの構造。
Spanner ではどちらも物理的にソートされた構造。
RDBMS と Spanner におけるインデックスの構造
1
2
5
10 10000
15
alice
bob
carol
oscar
steve
2
1
5
15
10
Spanner の インデックス Spanner のテーブル
1 2 5 10
10000
15
alice bob carol oscar steve
2 1 5 15 10
RDBMS のインデックス
RDBMS のテーブル
idx_players_name
players
playersidx_players_name
RDBMS
37. ● Spanner のインデックスは Spanner のテーブルと同じ構造
○ RDBMS でイメージしがちな B+Tree の構造ではない
● Spanner でインデックスを 1 つ作ると、1 行の書き込みで 2 テーブルへの同時書
き込みが発生するのと同義
● 更新負荷が増えるという観点は RDBMS のインデックスも同じ
セカンダリ インデックスとテーブルは同じ構造
1
2
5
10
15
alice
bob
carol
oscar
steve
2
1
5
15
10
playersidx_players_name
20 dave, ..dave 20
INSERT INTO players …
values (20, dave, ...);
💡メモ
40. ● Spanner で外部キー制約を作成すると、暗黙のインデックスが作成される
● 参照先のテーブルは PK 経由でチェックができるため、通常は参照先から参照元
を逆向きにたどるためのインデックスが 1 つ作られる
Spanner で外部キー制約を利用した際のデータ構造
record
record
record
1
2
3
1 record
1 record
1 record
1 record
1
2
3
Spanner の外部キー用の
セカンダリ インデックス
player_items
外部キーによる参照
INSERT時のチェック
1
2
3
4
1
1
1
1
2
3
4
items
DELETE 時のチェック
暗黙idx
41. ● Spanner で外部キー制約を作ると 暗黙のインデックス が作成される
● 外部キー制約の参照元のテーブルを更新すると、1 行の書き込みで 2 テーブル
への同時書き込みが発生することになる
● 暗黙のインデックスが作成されるのは RDBMS も Spanner も同じ
外部キー制約には インデックスが生成される💡メモ
Spanner の Information Schema で確認できる暗黙のインデックス
50. 分散 DB の利便性とトレードオフ - ノードをまたがる処理
1
2
5
スプリットA1
10
20
25
スプリットA2
30
35
40
スプリットA3
Spanner は分散データベースであり、異なるノード間でテーブルの
JOIN やアトミックな更新が可能だが、ある程度のオーバーヘッドが発生
してしまう。JOIN したいテーブルなどでも、そのままではあちこちに散ら
ばってしまう可能性がある。
node1 node2
1
2
5
10
20
25
30
35
40
42
43
45
1 1
1 2
1 3
2 1
2 2
2 3
5 1
5 2
5 3
10 1
10 2
10 3
1 1
1 2
1 3
2 1
2 2
2 3
5 1
5 2
スプリットB1 スプリットB2
players
player_items
player_id = 2 のデータが
散らばっている様子
52. ● Spanner のインターリーブとは、異なるテーブルを、正規化を保ったまま物理的
に同じ場所に配置する仕組み
● インターリーブ(Interleave)は英語で「綴じ込む」という意味
Spanner のインターリーブとデータ構造
player_id name level money
1 bob 1 100
2 alice 2 0
5 carol 1 50
players
player_id item_id quantity
1 1 10
1 2 2
1 3 1
2 1 8
2 2 2
2 3 3
INTERLEAVE
INTERLEAVE
JOIN して利用するテーブル同士
でインターリーブが使えると、必ず
物理的に連続しているので、IO効
率が良い
1
2
1 1
1 2
1 3
2 1
2 2
2 3
last_used
player_items
54. INTERLEAVE
インデックスもテーブルなのでインターリーブ可能
idx_players_name
PK name STRING(256)
PK player_id STRING(32)
(name) 列に対するインデックスは
インターリーブ不可
players
PK player_id STRING(32)
name STRING(256)
level INT64
money INT64
player_items
PK player_id STRING(32)
PK, FK item_id INT64
quantity INT64
親テーブル
子テーブル
last_used TIMESTAMP
idx_player_items_last_used
PK player_id STRING(32)
PK last_used TIMESTAMP
(player_id, last_used) 列に対するインデックスは
インターリーブ可能
特定の要素( 例えば特定の player_id )内でイン
デックスを作成するのであれば、インターリーブ
すれば IO コストの削減可能
この例の名前検索の様に、テーブルの全要素から
探すようなインデックスはインターリーブできない
(一緒に配置できる対象が無い)
PK item_id INT64
💡メモ
INTERLEAVE
index 作成
複合 index 作成
56. ● RDBMS と Cloud Spanner は、テーブル構造に違いがあるだけで、考え方は
シャーディングしている RDBMS に通ずるところが多い
● Cloud Spanner は自動シャーディングが可能な分散 DB であり、スケールアウト
とスケールインが簡単にできるメリットがある
● Cloud Spanner のデータ構造を簡単にまとめると
○ テーブルの PK が自動シャーディングのシャードキーを兼ねている
○ テーブルの PK 列は物理的にソートされて保存されている
○ インデックスはテーブルと同じ構造
● 一緒に使うデータは同じシャードに入れるのと同じように、インターリーブで配置
をうまく指定してあげれば、性能向上が見込める
RDBMS と Cloud Spanner は共通する考え方も多い
59. Google Cloud トレーニング無料提供 キャンペーンのご案内
Qwiklabs、Pluralsight(英語のみ)、対象 のCoursera のコースを1 か月間無料でご提供
お申込み期限は、5 月 20 日まで
(Pluralsight のみ 4 月 30 日まで)
goo.gle/TrainingOffer
詳細・お申込みはこちら ↑