Skip to main content
Spanner移行について
本気出して考えてみた
なるほど!ザ・GCP
自己紹介
髙橋 北斗(たかはし ほくと)
● 株式会社テクロス システム開発部マネージャー
● 経歴
○ インフラチームリーダー
■ ソーシャルゲームのインフラ基盤の開発・運用
■ 各種ツール、サービスの導入、管理
■ データ分析基盤の設計、導入
○ 現在はエンジニアマネージャー
About us
株式会社テクロス Techcross inc.
2009年 設立
2012年 ソーシャルゲーム開発開始
2018年~ UNITIA - 神託の使徒 × 終焉の女神 - リリース
2016年 神姫PROJECT リリース
宣伝:TECH x GAME COLLEGE
TECH x GAME COLLEGE(テック ゲーム カレッジ)は「渋
谷でちょっといい人呼んでゲーム勉強会」をテーマに、エン
ジニアのための活動しています。
今後もゲーム制作の現場で活躍しているエンジニアにとって
有益な情報を得られる場として、月に1~2回の勉強会を開催
予定です。
お題目
● Cloud Spannerへの移行検証の動機について
○ 現運用の課題
○ Cloud Spanner移行時の想定メリット
● Cloud Spannerへの移行検証
○ アプリで使用しているDBをCloud Spannerへ移行する
検証
○ 実際にタイトルで使用しているデータの移行検証
○ 運用を見据えたデータのバックアップ、リストア検証
お題目
● Cloud Spannerへの移行検証の動機について
○ 現運用の課題
○ Cloud Spanner移行時の想定メリット
● Cloud Spannerへの移行検証
○ アプリで使用しているDBをCloud Spannerへ移行する
検証
○ 実際にタイトルで使用しているデータの移行検証
○ 運用を見据えたデータのバックアップ、リストア検証
現運用の課題
● ソーシャルゲームのローンチ時の負荷は本当に読めない
○ ユーザが沢山来るかもしれない
○ 弊社事例でも想定の3倍のアクセスが来たことがある
● ローンチ時だけでなく、サービス運用中でも同じことが
ある
○ CMを始めとする広告による流入
○ ゲーム内の施策、ゲームバランスの変化など
現運用の課題
● Webサーバは動的にスケールアウト可能
● KVSもスケールアウトは比較的容易
● RDBの負荷対策は手間がかかる
RDBの負荷対策はいろいろあるが…
究極的にはDBを分割するしかない(垂直分割、水平分割)
現運用の課題
● 負荷に耐えるために事前にDBを分割しておく
● 最悪のケースを想定する→つまり大抵は過剰
● 縮退が必要になるが、たいていデータ移行が絡むので大
変
● モチベ的につらい
○ 沢山人が来て慌てて増やす→嬉しい悲鳴
○ 思ったより人が来ないor減ってきて縮退→ただ辛い
現運用の課題
現運用の課題
NoSQLを使うのは?
→ Cloud Bigtable、DynamoDBなどなど
確かに負荷に応じて書き込み性能はスケーリングするが…
データモデリング手法前提が大きく違う
アプリの開発初期から想定していないと対応が難しい
Cloud Spanner移行時の想定メリット
そこでCloud Spannerですよ!
Cloud Spanner移行時の想定メリット
● 動的にノードを増やしたり減らしたり簡単にできる
● リレーショナルデータベースの特徴を持つので移行コス
トは低い?
まさに夢のマネージドサービス!
とりあえず検証してみないと始まらないよね!
検証項目についてご紹介
● アプリで使用しているDBをCloud Spannerへ移行する検証
○ ひとまず動かしてみないと始まらない
○ 既存のゲームをCloud Spannerに合わせられるか
● 実際にタイトルで使用しているデータの移行検証
○ 実際にやるとなったら避けては通れない
○ データの変換、移行が現実的か試す
● 運用を見据えたデータのバックアップ、リストア検証
○ 移行して不便になったら意味がない
○ DBを扱う上で必ず出てくるバックアップ、リストア
問題を検証する
お題目
● Cloud Spannerへの移行検証の動機について
○ 現運用の課題
○ Cloud Spanner移行時の想定メリット
● Cloud Spannerへの移行検証
○ アプリで使用しているDBをCloud Spannerへ移行する
検証
○ 実際にタイトルで使用しているデータの移行検証
○ 運用を見据えたデータのバックアップ、リストア検証
弊社のシステム構成概略
本検証ではLaravelフレームワークの
Eloquentを用いて、透過的に利用する方針
ちょっとご紹介・・・
折良くコロプラさんがEloquent用ドライバを公開・・・
ありがたく使わせてもらいました!
https://github.com/colopl/laravel-spanner
ステップ1 - GCP利用環境の準備
何はともあれサービスを利用する準備は済ませます
● サービスアカウント作成/権限付与
● キーファイルの作成
● Cloud Spannerインスタンスの作成・・・など
簡単なドキュメントが提供されています!
参考:「PHP で Cloud Spanner を使ってみる」
ステップ2 - アプリケーション依存関係の解決
必要な依存関係をインストールします・・・
上記とは別にgrpc拡張機能も必要です!
ステップ3 - DBドライバの変更
DBドライバをmysqlからspannerに・・・
ホスト名/ポートでの記述がなくなります。
インスタンスIDでのサービス指定になる点に注意!
ステップ4 - DBドライバの変更
対象テーブルのマイグレーションファイルを修正・・・
● サロゲートキーをUUIDv4(string)に変更
● 主キーを明示的に指定
● *Incrementの記述はやめる(自動採番不可な為)
ステップ5 - 自動採番対応
自動採番の代わりにUUIDv4を採用する・・・
● PHP標準にはUUIDv4の生成関数は存在しない
● ramsey/uuidを有り難く使わせてもらいます
閑話休題
動かしてみた結果は・・・
Symfony¥Component¥Debug¥Exception¥FatalThrowableError: Type error:
Argument 1 passed to Carbon¥Carbon::instance() must be an instance of
DateTime, instance of DateTimeImmutable given, called in /var/repos/fencer-
back/vendor/colopl/laravel-spanner/src/Colopl/Spanner/Query/Processor.php
on line 39 in /var/repos/fencer-
back/vendor/nesbot/carbon/src/Carbon/Carbon.php:301
Laravelを微妙にバージョンアップ・・・
● googleapis/google-cloud-phpのTimestampは
DateTimeInterfaceを用いる新しめの実装
● 現在使っているLaravel 5.5.32に同梱のCarbonでは
DateTimeInterfaceを処理できなかった
● Laravel 5.5.45にアップデートし、Carbonを最新化してエ
ラーは解消!
ステップEx - 番外編
そして・・・
動かしてみた結果は・・・
動いてレコードもちゃんと入りました!
所感
● Laravel 5.5以降でEloquentに依存した実装になっており、
且つLaravel Spannerドライバを導入できるのであればコ
ード移行は比較的容易にできるかもしれません
● PDOを直で使っていたら・・・辛いかも
● 本検証はデータマイグレーションを行なっていないため、
自動採番列に対してはもう少しアプローチ必要そう(既
存値を元にしたハッシュ値にするなど)
お題目
● Cloud Spannerへの移行検証の動機について
○ 現運用の課題
○ Cloud Spanner移行時の想定メリット
● Cloud Spannerへの移行検証
○ アプリで使用しているDBをCloud Spannerへ移行する
検証
○ 実際にタイトルで使用しているデータの移行検証
○ 運用を見据えたデータのバックアップ、リストア検証
Cloud Spannerへのデータ移行検証前提
MySQLからの移行を想定
サービスで実際に使っているテーブルを移行検証
● accountsテーブル
○ ユーザ情報、約500万、データサイズ約1GB
● a_charactersテーブル
○ ユーザ所持キャラクター情報、約1億、データサイズ
約7GB
Cloud Spannerへのデータ移行検証前提
Cloud Spannerに他のRDBからレプリケーションを張る機能
は今の所ないので、レプリケーションを使ってデータを移行
する方法は使えない。
アプリケーション側に手を入れて、MySQLとCloud Spanner
に両方データを書き込む方法もあるが、大変なので今回は考
慮しない。
データ移行時間=ダウンタイム(事前準備除く)。
弊社実績だと、動作確認含めて24時間以内に終わればOK
想定構成
今回の構成
Embulkとは
● 並列データ転送ツール。Fluentdのバッチ版
● プラグインを入れることで様々な入力ソース、出力先、
フォーマットに対応できる
今回使用したプラグイン
● embulk-input-mysql
● embulk-formatter-avro
● embulk-output-gcs
Apache Avro
● スキーマ定義+バイナリエンコーディングであるデータ
交換フォーマット
● Spannerのバックアップデータの標準形式
● Embulkのformatterを使用する際、avscというスキーマフ
ァイルを準備する必要がある
Cloud Dataflowについて
● GCPのデータ変換パイプラインサービス
● フルマネージド&サーバレス&AutoScaling
● ApacheBeam形式で処理を記述して実行
● 使うのめっちゃ楽
備え付けのテンプレートに、Cloud Storageに置かれたAvro
形式のデータをCloud Spannerに入れる処理があるので、今
回それを使用
Cloud Spannerへデータ移行する上で考えないといけないこと
データ移行を行う上で、少なくとも
● テーブル定義の変更
● インターリーブを考慮する
● ホットスポットができないよう主キーを変更
について考える必要がある。
テーブル定義を変更
対応表をもとにテーブル定義を変更
インターリーブを考慮
インターリーブ化することで性能UP
主キー変更対応
主キー変更対応
主キーがAutoIncrementなサロゲートキーなので、変更しな
いといけない
元のMySQLのテーブルにNullableなカラム追加
バッチ処理で主キーをUUID5に変換し、カラムに入れていく
主キー変更対応
リレーションがあるテーブルはそれぞれ変換が必要
主キー変更対応
今回の検証ではGo言語でスクリプトを書いてデータを投入。
● 1億レコード入れるのに45分ほど。
● 実際にはサービス全体ではこの100倍程度のデータ量が存
在するので、4500分≒3日ほどかかる見込み。
○ 移行前に変換しておけばいいのでここは時間がかかっ
ても大丈夫。
通し検証!
データ移行を通して行きましょう!
手順の流れ
1. 事前準備としてカラム追加主キー対応
2. MySQL から、Embulk でデータをavro形式で抽出
3. Cloud Dataflow で Cloud Spannerにデータ投入
2.と3.が移行時のダウンタイムになる。
通し検証!
計測した実行時間:
accounts a_characters 備考
Embulk実行時間 5分 45分 16並列(MySQL 2コア、Embulk 16コ
アのインスタンス使用)
Cloud Dataflow実行
時間
13分 66分 Cloud Spannerのノード数3、Cloud
Dataflowのノード数自動(最大79ノー
ドまで上昇)
チューニング余地
Embulkでデータ抽出するところは、MySQLのリードレプリ
カの台数と、Embulkの台数を増やせば線形でスケールアウト
可能。10倍増やせば10倍早くなる。
Cloud Dataflow でのデータ投入も、Cloud Dataflowのノード
数と Cloud Spanner のノード数を増やせば線形でスケールア
ウトするはず。
通し検証からの想定時間
サービスのすべてのデータを移したらどうなるか?
● データ量は今回検証の100倍
● 各リソースの数を増やしていけば実行時間は10分の1
ざっくり、今回の検証の10倍位と想定
20時間ほどで終わる?
24時間以内には終わりそう・・・
データ移行検証まとめ
● データ移行そのものは楽
● 主キー対応が一番大変。根気があれば現実的な範疇か
な・・・?
● ダウンタイムがそこが許容できるなら移行は可能
Cloud Spannerに移行する準備として、MySQLの段階で主キ
ーの変更を行うなど、段階的な移行を検討したほうが良いか
もしれない。
お題目
● Cloud Spannerへの移行検証の動機について
○ 現運用の課題
○ Cloud Spanner移行時の想定メリット
● Cloud Spannerへの移行検証
○ アプリで使用しているDBをCloud Spannerへ移行する
検証
○ 実際にタイトルで使用しているデータの移行検証
○ 運用を見据えたデータのバックアップ、リストア検証
バックアップ、リストア運用について
現在のバックアップ、リストア運用
● 毎日定時にDBのスナップショットを取得
● 毎日スナップショットを元に自動リストア
アプリケーションの動作確認、バッチコマンドの時間計測、
不具合調査、KPIデータ取得など幅広い用途で使用している。
バックアップは他にもデータ変更があるメンテナンスのたび
に保険として取得している。
バックアップ、リストア運用について
できれば現状と同じような運用を行いたい。
● バックアップはできる限り早いほうがいい
● リストアもなるべく早いほうがいい
● 毎日やるものだから料金は安くしたい
ひとまず、毎日バックアップ&リストアするのが現実的な時
間で行えればOK。
Pontem
今回Pontem というツールを使用。
● GCP の公式OSS
● Cloud Spannerのバックアップ、リストア機能が存在
○ 内部では Cloud Dataflow が使われている
○ バックアップ→バックアップデータがavro形式で GCS
に保存される
○ リストア→ GCS に保存された avro ファイルを元にリ
ストア
バックアップ検証
Cloud Spannerをバックアップしてみた。18分ほどで完了。
リストア検証
リストアしてみた。1時間25分ほどで完了。
所要時間とコスト
Pontem公式ドキュメントより。
毎日バックアップを取りリストアする運用自体はできそう。
コストもそれなりに掛かりそう。
検証の総括
1. アプリで使用している DB の一部を Cloud Spannerに移行
する検証
コロプラさんのドライバのおかげもあり、ソースの修正は比
較的少なめで移行可能。
Laravel自体のアップデートの必要性などはあった。
検証の総括
2. 実際にタイトルで使用しているデータの移行検証
データ移行そのものの工数はそこまで大きくない。
主キーの変換が、準備も含めて比較的大変だが、現実的な範
囲なのではないか。
検証の総括
3. 運用を見据えたデータのバックアップ、リストアの検証
毎日バックアップを取りリストアする運用自体はできるが、
コストはそこそこ掛かりそう。
検証の総括
本講演がCloud Spannerの使用、移行を検討している方への
参考になれば幸いです。
参考資料、使用させていただいて頂いたプロダクト( 1/3 )
Cloud Spanner | 大規模な自動シャーディングとトランザクションの整合性
( https://cloud.google.com/spanner/?hl=ja )
GitHub - colopl/laravel-spanner: Laravel database driver for Google Cloud Spanner
( https://github.com/colopl/laravel-spanner )
PHP で Cloud Spanner を使ってみる | Cloud Spanner のドキュメント | Google Cloud
( https://cloud.google.com/spanner/docs/getting-started/php/?hl=ja )
ramsey/uuid: A PHP library for generating RFC 4122 version 1, 3, 4, and 5 universally unique identifiers (UUID).
( https://github.com/ramsey/uuid )
embulk/embulk: Embulk: Pluggable Bulk Data Loader.
( https://github.com/embulk/embulk )
参考資料、使用させていただいて頂いたプロダクト( 2/3 )
Embulk — Embulk 0.8 documentation
( https://www.embulk.org/docs/index.html )
第7章 Avroスキーマ
( https://docs.oracle.com/cd/E53557_01/html/GettingStartedGuide/avroschemas.html )
Cloud Dataflow - ストリームとバッチでのデータ処理 | Cloud Dataflow | Google Cloud
( https://cloud.google.com/dataflow/?hl=ja )
Migrating from MySQL to Cloud Spanner | Solutions | Google Cloud
( https://cloud.google.com/solutions/migrating-mysql-to-spanner )
Cloud Spanner のスキーマ設計の最適化 | Cloud Spanner のドキュメント | Google Cloud
( https://cloud.google.com/spanner/docs/whitepapers/optimizing-schema-design?hl=ja )
参考資料、使用させていただいて頂いたプロダクト( 3/3 )
スキーマとデータモデル | Cloud Spanner のドキュメント | Google Cloud
( https://cloud.google.com/spanner/docs/schema-and-data-model?hl=ja#choosing_a_primary_key )
GoogleCloudPlatform/pontem: Open source tools for Google Cloud Storage and Databases.
( https://github.com/GoogleCloudPlatform/pontem )
pontem/USAGE.md at dev · GoogleCloudPlatform/pontem
( https://github.com/GoogleCloudPlatform/pontem/blob/dev/CloudSpannerBackupRestore/USAGE.md )