Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Google Cloud Spannerの基礎知識@Gunma.web#49

Google Cloud Spannerの基礎知識@Gunma.web#49

周東拓哉

June 03, 2023
Tweet

Other Decks in Technology

Transcript

  1. ⾃⼰紹介 周東 拓哉(しゅうとう たくや) - エンジニア3年⽬ - 前橋市出⾝ - 群⾺⾼専通ってました

    IPAマニアになりつつある AP・DB・SC → 次はPM! Unipos株式会社 - バックエンドエンジニア(役職) Scala・Go・SQLを書いて⽣活してます ・NoSQLからNewSQLへのDB移⾏を担当 ・Cloud Spannerが⼤好きです 最近社内ハッカソン優勝しました UniposのAI投稿シミュレータ 1
  2. Cloud Spannerの特徴 リレーショナルデータベース 分散データベース(NewSQL) × ・SQL ・関係スキーマ ・正規化 ・ACID特性 ・⽔平スケール

    ・CAP定理の克服 ・強整合性の実現 ・99.99%のSLA ・スプリットによるデータ分散 通常のRDBとは異なるハマりどころがあり、初⾒ではパフォーマンスチューニングが難しい 特に、データアクセス・結合の仕組みを意識しないと使いこなすことが難しい 2
  3. ホットスポット UserAccessLog(LastAccess, UserId, …) ×単調増加するキーが主キーの先頭 保存されるスプリットはキーの範囲で決定 https://cloud.google.com/spanner/docs/schema-design?hl=ja [1230219000000000, 001930]までのデータ →

    スプリットAへ格納 [1230219000001000, 001519]からのデータ → スプリットBへ格納 同時に追加されるデータの書き込みが特定のスプリットへ集中し、ホットスポットが発⽣ → 書き込み性能の低下・コンピューティングリソースの占有 8
  4. 主キー設計: ホットスポットの回避 UserAccessLog(UserId, LastAccess, …) ◯ ランダムな値が主キーの先頭 キー範囲がランダムに格納先スプリットが分散 推奨される対策 ・UUIDv4を主キーに利⽤

    ・ShardIdを主キーの先頭に付与 ・ShardId = hash(LastAccess and UserId) % N → N個の論理シャードに分割する https://cloud.google.com/spanner/docs/schema-design?hl=ja 9
  5. 索引設計: 分散結合の発⽣ インデックス MemberByDepartmentID ベーステーブル Member SELECT ID, Name, EmailAddress

    FROM Member@{FORCE_INDEX=MemberByDepartmentID} CREATE INDEX MemberByDepartmentID ON Member(DepartmentID); 部署IDでメンバーを検索するための索引 ⽇本 ブラジル Spannerは世界規模の分散DBで、 データセンタ間の物理的な距離が遠い ケースもある Hit! Hit! Hit! → 遠隔地のデータを伝送・結合する処理が発⽣ dept01 dept01 dept01 dept02 dept02 dept02 索引検索後, 対応する主キーを持つレコードから Name, EmailAddressを引こうとする。 10
  6. 索引設計: STORINGによる分散結合対策 SELECT ID, Name, EmailAddress, FROM Member@{FORCE_INDEX=MemberByDepartmentID} CREATE INDEX

    MemberByDepartmentID ON Member(DepartmentID) STORING (Name, EmailAddress); 索引にクエリ時に⼀緒に取得したいカラムを格納できる Hit! Hit! Hit! STORINGは索引の並び順に影響を与えない インデックス MemberByDepartmentID dept01 dept01 dept01 dept02 dept02 dept02 STORING KEY TANAKA, … YAMADA, … NONAKA, … SATOU, … NOJIMA, … KOJIMA, … 分散結合を回避できるため、クエリが⾼速になる 11
  7. テーブル設計: INTERLEAVE CREATE TABLE Singers( SingerId INT64 NOT NULL, FirstName

    STRING(256), LastName STRING(256), SingerInfo BYTES(MAX), ) PRIMARY KEY (SingerId); CREATE TABLE Albums ( SingerId INT64 NOT NULL, AlbumId INT64 NOT NULL, AlbumTitle STRING(256), ) PRIMARY KEY (SingerId, AlbumId), INTERLEAVE IN PARENT Singers ON DELETE CASCADE; SELECT s.*, ARRAY( SELECT AS STRUCT a.* FROM Albums a WHERE a.SingerId = s.SingerId ) Albums, FROM Singers s WHERE s.SingerId = @SingerId 物理的に⼀緒に格納 ⼀緒に取得する場合、JOINコストがなく⾼速 https://cloud.google.com/spanner/docs/schema-and-data-model?hl=ja ARRAY(サブクエリで取得) 13