Slide 1

Slide 1 text

Recap: Migrating 80 BILLION RECORDS From MySQL to Bigtable 黒澤 拓磨 2023.Oct.31

Slide 2

Slide 2 text

1.自己紹介 2.Recap: Migrating 80 BILLION RECORDS From MySQL to Bigtable 3.実装・検証 4.さいごに

Slide 3

Slide 3 text

自己紹介

Slide 4

Slide 4 text

黒澤 拓磨 CyberAgent ‘21年新卒入社 AI事業本部配属後、新規事業立ち上げに従事。 今年(2023年)からハノイ開発センターの立ち上げに携わるた め、ベトナムへ移住。 Goとの馴れ初め CA Tech DojoにてGoの基礎やバックエンド開発の基礎を学んだ のがきっかけ。CyberAgentで携わってきたプロダクトは全てGoで 開発。 TakumaKurosawa

Slide 5

Slide 5 text

Recap: Migrating 80 BILLION RECORDS From MySQL to Bigtable

Slide 6

Slide 6 text

Migrating 80 BILLION RECORDS From MySQL to Bigtable https://www.gophercon.com/agenda/session/1158499

Slide 7

Slide 7 text

Bitlyについて サービス概要 URL短縮ツール QRコード生成 Analytics提供 サービス特徴 500,000 paying customers 5,700,000 MAU 256,000,000 links & QR created monthly https://bitly.com/

Slide 8

Slide 8 text

MySQL→Bigtable移行のモチベーション なぜMySQLではダメだったのか? 1. 運用面での問題 a. ソフトウェアおよびセキュリティアップデート b. DBホストプロビジョニング c. 100%利用可能な状態を維持しつつ実行すること 2. バックアップとリストアにかかるメンテコストが莫大だった a. 最大まる2人日必要 3. マルチリージョンやグローバルな配信での課題 a. 手作業でのMySQLシャーディングには限界がある 󰢃

Slide 9

Slide 9 text

MySQL→Bigtable移行のモチベーション Google Cloud Bigtableへの移行を決定した理由 ● 99.999% SLA ● 無制限のスケール ● 1桁msのレイテンシー ● ビルトインのモニタリングシステム ● マルチリージョンレベルのレプリケーション ● リージョン間のシームレスなレプリケーションにより、地理的分散が可能 ● コンピュートリソースとストレージのオンデマンドスケールに対応 ● Bitlyにおいて他のGoogleCloudサービスを利用しており、親和性が高い ● Bitlyの仕様上、NoSQLデータベースとの相性の良いデータセット形式であった

Slide 10

Slide 10 text

MySQL→Bigtable移行のモチベーション もっと詳しく知りたい方へ・・・ From MySQL to NoSQL: Bitly’s big move to Bigtable

Slide 11

Slide 11 text

MySQL→Bigtableマイグレーション計画 MySQL writes MySQL reads Bigtable writes Bigtable reads Start dual writes マイグレーション Bigtableに切り替え End dual writes

Slide 12

Slide 12 text

前提条件 Bitlyでのデータ管理(Before) hash_0 to hash_7 hashdb-1 hash_8 to hash_15 hashdb-2 hash_16 to hash_23 hashdb-3 hash_24 to hash_31 hashdb-4 hash_32 to hash_39 hashdb-5 hash_40 to hash_47 hashdb-6 hash_0 to hash_23 hash-archive-1 hash_24 to hash_47 hash-archive-2

Slide 13

Slide 13 text

前提条件 シャーディングのメリット 4,000,000件 1,000,000件 1,000,000件 1,000,000件 1,000,000件 ● 応答時間の改善 ● 単一障害点を無くせる ● スケーリングしやすくなる https://aws.amazon.com/jp/what-is/database-sharding/

Slide 14

Slide 14 text

前提条件 Bitlyでのデータ管理(Before) hash_0 to hash_7 hashdb-1 hash_8 to hash_15 hashdb-2 hash_16 to hash_23 hashdb-3 hash_24 to hash_31 hashdb-4 hash_32 to hash_39 hashdb-5 hash_40 to hash_47 hashdb-6 hash_0 to hash_23 hash-archive-1 hash_24 to hash_47 hash-archive-2

Slide 15

Slide 15 text

前提条件 マイグレーション対象のデータ形式 hash = Primary Key URL Login TimeStamp

Slide 16

Slide 16 text

前提条件 MySQLからレコードを取得する処理

Slide 17

Slide 17 text

前提条件 SQL Rowを処理する関数

Slide 18

Slide 18 text

前提条件 GetSqlRows()とMigrateRows()を組み合わせたメインロジック

Slide 19

Slide 19 text

前提条件 main()

Slide 20

Slide 20 text

データ移行プログラム 1シャードずつ逐次実行するプログラム

Slide 21

Slide 21 text

データ移行プログラム 1シャードずつ逐次実行するプログラム = sum( 予測総時間 time(shard_a) , time(shard_b) , … , time(shard_n) )

Slide 22

Slide 22 text

データ移行プログラム 1シャードずつ逐次実行するプログラム 397 days…😱

Slide 23

Slide 23 text

データ移行プログラム 改善① GroutineとWaitGroupを使ってshardsを並列実行に

Slide 24

Slide 24 text

データ移行プログラム 改善① GroutineとWaitGroupを使ってshardsを並列実行に = max( 予測総時間 time(shard_a) , time(shard_b) , … , time(shard_n) )

Slide 25

Slide 25 text

データ移行プログラム 改善① GroutineとWaitGroupを使ってshardsを並列実行に 56 days 😕

Slide 26

Slide 26 text

データ移行プログラム 改善③ チャネルを使用してワーカーパターンに Task 1 Task2 ・・ ・ Task1 Task2 Task3 Task6 TaskN Task4 Task pool Worker 1 Worker 2 Worker 3 Task3 Task4 Task5

Slide 27

Slide 27 text

データ移行プログラム 改善③ チャネルを使用してワーカーパターンに

Slide 28

Slide 28 text

データ移行プログラム 改善③ チャネルを使用してワーカーパターンに チャネルにRecordが 入ってくる度にforが1回走る

Slide 29

Slide 29 text

データ移行プログラム 改善③ チャネルを使用してワーカーパターンに Bigtableの書き込み制限に対応 するため、Workerの数を制御

Slide 30

Slide 30 text

データ移行プログラム 改善③ チャネルを使用してワーカーパターンに = max( 予測総時間 time(shard_a) , time(shard_b) , … , time(shard_n) ) SELECT * FROM tableName … SELECT * FROM tableName … ・・ ・ Insert Insert Insert Insert Insert Insert MigrateRows() Worker 1 Worker 2 Worker 3

Slide 31

Slide 31 text

データ移行プログラム 改善③ チャネルを使用してワーカーパターンに 6 days 😎

Slide 32

Slide 32 text

すごい速くなった!けど・・・ なんでBulk insertにしないの? 🤔

Slide 33

Slide 33 text

本人に聞いてきました🎉

Slide 34

Slide 34 text

📩 メールの内容 Hashキーの特性とホットスポット回避 ● MySQLに保存していたHashデータは時系列順に並ぶようなキーになっていた ○ 言及されていないが、恐らくULID? ● MySQLのデータをそのままBigtableに入れると、ホットスポットになる ○ Bigtableの仕様上、行キーはアルファベット順でソートされる ● ホットスポットを回避するために、HashをReverseするようにした Bulk insertにしなかった理由 ● Bigtableの仕様上、バルクインサートする対象のデータリストが互いに近い位置に配 置されるようなデータ構造でない場合は並列処理されずに順次実行されてしまう ● どうせBigtableの仕様で順次実行になるのであれば、実装が楽な1件ずつinsertしよう と思った

Slide 35

Slide 35 text

📩 メールの内容 Bigtableドキュメント bigtable/docs/schema-design#general-concepts bigtable/docs/writes#not-batch

Slide 36

Slide 36 text

実装・検証

Slide 37

Slide 37 text

用意した環境 Docker compose ● MySQL ● DynamoDB MySQL ● hashdb-1 ~ 6 テーブル ● 10,000件 / table ● データ構造は一緒 DynamoDB ● Hash(String):PartitionKey ● amazon/dynamodb-local イメージを使用

Slide 38

Slide 38 text

検証結果 逐次実行 vs. シャードごとに並列化 vs. ワーカーパターン

Slide 39

Slide 39 text

検証結果 シャードごとに並列化 vs. ワーカーパターン

Slide 40

Slide 40 text

実際に動かしたりコードが読みたい方へ Migrating-80-BILLION-RECORDS-From-MySQL-to-Bigtable

Slide 41

Slide 41 text

さいごに

Slide 42

Slide 42 text

Special thanks 現地で交流して下さったみなさん tenntennさん、nsegaさん、komatsuさん、チームメルカリの皆さん スライドレビュー・検証にご協力いただいたみなさん tenntennさん、sivchariさん、nghialvさん、hoangndさん、quangさん この機会を提供して下さったみなさん 株式会社メルカリ(会場および配信)、GopherCon2023、Zoe McCormickさん(GopherCon登壇者) 株式会社サイバーエージェント(海外カンファレンス出張制度) Gopher sticker: github.com/tenntenn/gopher-stickers