$30 off During Our Annual Pro Sale. View Details »

Recap: Migrating 80 BILLION RECORDS From MySQL to Bigtable

Recap: Migrating 80 BILLION RECORDS From MySQL to Bigtable

Go 1.21 リリースパーティ & GopherCon 2023 報告会( https://gocon.connpass.com/event/299108/ )登壇資料です。
サンディエゴにて開催された、GopherCon2023に参加してきたのでそちらの報告で登壇させていただきました!

▼ Recapしたネタ元
https://www.gophercon.com/agenda/session/1158499

▼ 実装検証したリポジトリ
https://github.com/TakumaKurosawa/Migrating-80-BILLION-RECORDS-From-MySQL-to-Bigtable

Takuma Kurosawa

October 31, 2023
Tweet

More Decks by Takuma Kurosawa

Other Decks in Programming

Transcript

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

    View Slide

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

    View Slide

  3. 自己紹介

    View Slide

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

    View Slide

  5. Recap: Migrating 80 BILLION
    RECORDS From MySQL to
    Bigtable

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  12. 前提条件
    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

    View Slide

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

    View Slide

  14. 前提条件
    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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  19. 前提条件
    main()

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    Task1 Task2 Task3
    Task6
    TaskN
    Task4
    Task pool Worker 1 Worker 2 Worker 3
    Task3
    Task4
    Task5

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  30. データ移行プログラム
    改善③ チャネルを使用してワーカーパターンに
    = 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

    View Slide

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

    View Slide

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

    View Slide

  33. 本人に聞いてきました🎉

    View Slide

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

    View Slide

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

    View Slide

  36. 実装・検証

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  41. さいごに

    View Slide

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

    View Slide