by shigemk2

当面は技術的なことしか書かない

memo ChatWorkがデータマイグレーションに使った技術の話 #datamigrationnight

atnd.org

マイグレーションしたらsparkの処理速度が3倍になった

チャットワークとは

  • 説明不要
  • 国内最大手

データマイグレーション

  • システムマイグレーションに付随

    • メッセージングシステム部分の大刷新
    • 並列分散システム化
    • トランザクションに依存しない
    • HBase(RDBMS to NoSQL)
    • ScalaMatsuriでシステムマイグレーションのお話をした
  • アーキテクチャ

    • akka(spallowforwarder readAPI writeAPI updater)
    • kafka
    • HBase
  • 今回の話は、AuroraからHBaseへのマイグレーション

  • 17億メッセージデータ

  • 新たに「ルームで何番目の発言か」をフィールド上で算出(計算)
  • 工数書けない

  • Spark

    • MR
    • エキスパートの存在と安定性が理由でSparkをとった
    • SparkからHBaseへのバルクロードが可能
    • 大量データアップロードはバルクロード一択
  • EMR
    • Spark実行環境
    • 試験用環境
    • Auroraのバイナリログを読むためのmysql-binlog-connector-java
  • concourse
    • jenkinsみたいなもの

柔軟で安全なマイグレーションのために

戦略

  • 基本マイグレーション
    • 全件のマイグレーション
  • 差分マイグレーション
    • 前回以後の差分をマイグレーション
  • 基本 + 差分のコンボ

  • Spark

    • HBase-Sparkで書き込み
    • binlogからメッセージテーブルへ
      • 直接イベントとして取得する
  • 定期 or 手動でスナップショットをとる
  • 復元してマイグレーションと差分検証する。Productionへの負荷はない
  • Auroraのbinlogを使うときは復元するときにrotateする
  • rotate以外にも本番とその復元DBとでやりたいことに差がでないか検証する
  • EMRを使うと、スケールアップ/スケールアウトが簡単 札束で殴ればなんとかなる

安心安全なマイグレーションのために

  • メトリクスをしっかりとる
    • DBの急激な変化に気をつける
    • マイグレーションできてもDBの異常は検知する

Sparkアプリケーションの高速化

  • Sparkの仕様への理解
    • shuffleは高コストなので避ける
    • RDDのPartitionを意識する
      • Custom Partitioner
      • RDD#mapPartitionsメソッド
      • Partionerの保持
      • RDDでゴリゴリやるのが適してた

データの特性の把握

  • 基本マイグレーションPartition戦略最適化
    • データがどのノードにあるのかを意識する
    • ナイーブな実装 one Partition one Room
      • データのソートとカウントすればRoom単位の処理になる
      • 粒度が細かい→Auroraの読み込みスループットが上がらない
    • one partition n room
      • 複数のルームがはいる
      • roomIdでgroup byするとシャッフルが発生する→無駄
    • one partition n room
      • ソートとカウントしたあとで、データをregion単位でrepartitionする
      • HBaseContext.scala:791 repartitionAndSortWithinPartitions
      • 分散配置のルールに従って移動する必要がある
      • SparkのパーティショニングをHBaseと揃える
      • 1ノードにつき1RegionServer
      • 1 partitionあたり1 regionにするとshuffleするけど軽い
      • (RDDの型がPair型じゃないといけないので、Valueに適当なダミーを割り当てる必要がある)
  • 負荷の偏りをかいけつする

    • 基本マイグレーションの高速化はそれなりでよい
    • データ分布に基づくケアでバランスを取る
  • 事前パーティショニングが検証時に活躍

    • HBase/Auroraの突き合わせ
    • Aurora HBaseのデータが同じパーティションに配置されるようなCustomPartitionerを最適化
  • そのほかこまいこと

    • HBaseはpre-splitしていること
    • Region数が少ないとSparkクラスタサイズを大きく出来ない
    • ルーム分布のケースなので必ずしも汎用的じゃない

まとめ

  • Shuffleを減らす or 軽くする
    • Partitionの単位を工夫
    • Custom Partitionerの全体ロジックを検討
  • 各ワーカーの負荷を均等に

  • binlogによるストリーミングマイグレーションとかはやりたかった

トラブル

  • copyがタイムアウトでひたすらリトライ→権限付与で解決
  • HBaseのレアなバグ
    • 大きいデータを使うと踏む
    • 1.2.1で修正されていたバグ