概要
GCPのCloud Spannerについて調べて動かしてみた話
やったこと
- Cloud Spannerの調査
- GAEからCloud Spannerを叩く
アウトプット
github: https://github.com/y-ohgi/gcp-practice
GAE(Google App Engine)
- GCPのPaaS
- 勝手にスケールするし負荷分散もしてくれる凄いやつ
- 今回はGAE FEでランタイムはnodejsを使用。
- Cloud Spannerのライブラリが存在する言語で、僕がサクッと書けるのがRubyとNode.jsだけだった
- なのでNode.jsでExpressを採用するためにGAE FEを採用
Cloud Spanner
概要
Googleが作成し、もともとGoogle社内で使用されてきたRDB。
水平スケールが可能で、CAP定理の3つを(ほぼ)選択できる唯一のエンタープライズDB。
インターフェイスはRDBだが、裏側のストレージはKVS
メンテナンスウィンドウが無いため、マイクロサービスのコアな部分に必要なRDBとして扱うことができそう
水平スケール
例えば従来のMySQLやPostgreSQLなどは読み込みはリードレプリカを横に増やすことで水平スケール(インスタンス台数を増やす。)させる事が可能。
書き込みはその限りではなく、垂直スケール(インスタンスサイズを上げる。)でのみしか対応ができない。
Cloud Spannerは従来のマスター・スレーブ形式とは異なり、全てのノードがReadとWriteを行うことが可能、これにより水平スケールが可能に。
Paxosという合意アルゴリズムと原子時計を用いてトランザクションを管理している
CAP定理
分散システムにおいて、3つの要素のうち2つしか同時に満たすことができないというもの。
大事なのが「分散システム」という文脈。
- C: Consistency
- A: Availability
- 可用性
- 読み込みと書き込みの両方で、100%の可用性が担保されている
- データが壊れたり、ロック待ちの状態にならないこと
- P: Tolerance to Network Partions
- ネットワーク分断耐性
- 1つのサーバーに障害が発生したりデータの破損があったとしても問題なく使用できること
Cloud Spannerはこの3つを、業務遂行上要求されるであろう非機能要件レベルで満たすことが可能。
お値段
- $1.17/h
- 91,400円/月 = $1.17 * 105円 * 24h * 31day
- クラスター化されてるとはいえ3台がベストプラクティスらしいので。
- 274,200/月 = 91,400円/月 * 3台
- 隣の席の人月より安い!!
DBの設計時に気をつける点
- PKをサロゲートキーにすることがアンチパターン
- インターリーブというSpanner独自のFKを用いる
- PKにインデックスが張られない
- 明示的にインデックスを貼る必要あり
- 元OracleMasterPlatinumがCloudSpanner触ってみた
Cloud Spannerを叩く
DDL
テーブル作成用DDL
VARCHARではなくSTRINGになっていたり、よく見るSQLとは少し違う
CREATE TABLE blogs ( blog_id STRING(36), title STRING(150), body STRING(MAX), created_at TIMESTAMP ) PRIMARY KEY(blog_id); CREATE TABLE comments ( comment_id STRING(36), blog_id STRING(36), name STRING(50), body STRING(MAX), created_at TIMESTAMP ) PRIMARY KEY(blog_id, comment_id), INTERLEAVE IN PARENT blogs ON DELETE CASCADE; # インターリーブの設定。
SELECT
ANSI規格準拠のSELECT文を使用可能
const query = { sql: `SELECT * FROM blogs WHERE blog_id = @id`, params: { id: id } } database() .run(query) .then(res => { // console.log(res) })
INSERT
データの挿入にはSQL文(INSERT文)は使用不可。
SDKを介してリクエストを送信することでのみ挿入が行える(ここらへんNoSQLっぽい)。
const values = [ { blog_id: uuid(), title: 'title', created_at: new Date() // TIMESTAMP型はUTCである必要あり } ] tables('blogs') .insert(values) .then(data => console.log(data))
動かして得た知見
GAE
- DockerfileがGAEの起動ファイルである app.yaml ど同じ階層にいるとランタイムを custom にしろと言われてエラー
- 仰せのままにcustomにしたら動いた。
- Docker上でgcloudコマンド叩く必要が出てきたためDockerを途中で切り捨てた。
- GAEへ渡す環境変数をリポジトリ上から隠す
Spanner
- Spannerはローカルで起動できない
- ローカルからSpanner(クラウド上の。)を叩くとレスポンスが著しく遅い。
- 体感2秒ほど待つと帰ってくる。遅い。
- 高い。
- やっぱり高い。課金が1時間100円ちょっとなので無料枠がゴリゴリ減る。
雑記
諸々調べてるとCAP定理を語るのは古いとかなんとか書かれてたり。ちゃんと自分で調べて答えを出す必要を感じる。
あと、サーバーに乗せるところまでやらないと見えてこないものがあるなと今日このごろ。今回だとGAE x Spannerのレイテンシが遅かったりとか(GAEからSpannerはgRPCではなくHTTPっぽい)。
というかデプロイしないとクラウドで遊べないのが問題。
参考
- 超実践 Cloud Spanner 設計講座
- googleの人のスライド。これを見れば一通りわかる
- スキーマとデータモデル | Cloud Spanner のドキュメント | Google Cloud Platform
- Spannerの特徴「インターリーブ」についての公式ドキュメント。
- 元OracleMasterPlatinumがCloudSpanner触ってみた
- Write性能のベンチマーク。
- DBが水平にスケールしてる。。。
- Spannerに関する技術メモ
- Spannerのトランザクションの仕組みについて
- Google Spannerまとめ - Togetter
- 分散技術の偉い人達がSpannerについて物申す系のアレ
- Paxos
- ミリシタを支える GAE/Go
- クラスタに3ノード必要な理由 - Qiita