Google Cloud Spannerを使った際に感じた良かった点と注意点
みなさま、こんにちは!
システム開発部のK.Mです。
弊社でGoogle Cloud Spannerをデータベースに使用する機会がありましたので、開発・運用時に感じた良かった点・注意点を個人的な見解を交えて記載していきます。
- Google Cloud Spannerを使った際に感じた良かった点と注意点
- Google Cloud Spannerとは
- 良かった点
- 注意点
- 開発時、運用時に起きた他の事例
- その他、未確認事項
- まとめ
- 最後に
Google Cloud Spannerとは
Googleが開発した分散データベース
RDBMSとNoSQLの良い部分が合体したデータベース
良かった点
フルマネージドなので運営中に手がかからない
- 運営期間中は追加実装など他業務に集中出来る。
実際の運用時にspannerが落ちて繋がらなくなるということはありませんでした - イベントなどの負荷が上がりそうな時に事前にノード数を増やしたり、アクセス数が落ち着いてからノード数を減らすという作業しか行っていない
- それ以外だと1日1回GCPの管理画面からspannerのCPU負荷やレイテンシに問題が発生していないかを確認する程度の作業量でした
- 運営期間中は追加実装など他業務に集中出来る。
データの水平・垂直分割しなくてもspanner側で勝手にやってくれる
運用時にメンテナンスを入れずにスキーマー変更が可能
- 使用した案件では、本番環境にて動作確認をするためのメンテナンスを入れるという工程があったため、メンテナンス中にスキーマー更新を行っていたが、運営サイクルにてメンテナンスを無くすことを検討しているのであれば、魅力的な機能
配列型や構造体型でデータが持てる
- DBの設計がすっきりして、プログラム側での処理がしやすくなる
- 配列型の一例
ストーリーの第何話を読んだというのを単純に実装しようとして、ユーザーIDと読んだストーリーの話数を保存するテーブルを作った場合、下記のように読んだストーリー数分のレコードが作られてしまいデータが膨れ上がるし、selectやinsert、updateの速度にも影響が出てしまう。(インデックスを設定すればselect自体の速度は速くなるが、insertの速度がデータが増えていくたびにインデックスの更新も入り遅くなっていきますので通常は取りえない設計)
ユーザーID 読んだストーリーID 1 1 1 2 1 3 2 1 2 2 次に考えられるのが無駄にレコードが作られないように、読んだストーリー部分をカンマ区切りの文字列などで保存するという方法がある。こうすることで、ユーザー数分のレコードで済むのでデータ数は激減するが、プログラム側でDBからの読み込んだ際に、カンマで区切られた文字列をカンマ毎に分けて数字にしたり、DBに書き込む際に、数字をカンマで連結して文字列にしたりという処理が入ってきて、少し煩雑になってしまいます。
ユーザーID 読んだストーリーID 1 "1,2,3" 2 "1,2" そういった諸々を回避する方法として読んだストーリーIDをint型の配列型に設定することが可能になっています。配列型に設定出来る型自体は自由です。
ユーザーID 読んだストーリーID 1 [1,2,3] 2 [1,2] goの場合ですが、spannerから読み込んだ時点でint型のスライス(goでの配列のようなもの)として扱えるようになっているので、追加する場合は下記のように
append
するだけでデータが追加されます。
ストーリーテーブル.読んだストーリーID = append(ストーリーテーブル.読んだストーリーID, 4)
spannerの管理画面にて下記のような統計を表示するページがあり、クエリのCPU使用率や実行回数、レイテンシが見れるので調査のためにSQL(EXPLAINとか)を叩かなくてもブラウザ上で確認が出来るので調整が簡単に行える
GCP標準機能であるトレースにて、スタックトレースのようにspannerのコール順が分かるので、チューニング時にネックになっている箇所が分かりやすい。