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

TiUG #1 HBaseからTiDBへの移行を選んだ理由

nori
April 03, 2024

TiUG #1 HBaseからTiDBへの移行を選んだ理由

nori

April 03, 2024
Tweet

Other Decks in Technology

Transcript

  1. 大規模データ処理基盤 6 - DPUでは、2010年にリリースした大規模データ処理基盤 「Patriot」の開発・運用を行ってきた - 基盤全体がHadoopエコシステムに依存しており、 DBにHBaseを選択 - Patriotの運用を通じて様々な課題が見つかり、これらの

    課題を解決するため新たな大規模データ処理基盤の開 発に取り組んでいる - 既存の基盤ではHBaseがデータストアとして利用されてい たが、現在はその部分をTiDBに置き換える作業を行って いる 刷新後のデータ処理基盤
  2. Wide Column (key-key-value) NoSQL Databaseの一種 Region - データをkeyのRangeで論理的に分割したもの Region Server

    - Regionという単位でデータを管理して、クラ イアントにサービングする HMaster - Regionサーバーに対するRegion管理・割り当て Zookeeper - クラスタ全体の障害検知・メタデータ管理 Client - ZookeeperとHMasterと連携して直接Region Server からデータを読み込む TiKVはHBaseを元に開発されたためアーキテクチャが似ている HBaseとは? HBaseアーキテクチャ 8 TiKVのような役割 PDのような役割
  3. HBaseの課題 - 利用者 1. スキーマ管理が難しい スキーマの目的 - データの中身をドキュメント化 - 不正データ挿入防止

    - 無いとアプリ側の仕組みを理解する必要がある 自作する :https://github.com/CyberAgent/valor - 開発・管理が面倒 11 { “key1”: “aaaa”, “key2”: “bbb”, “value1”: “3”, “value2”: “12” } RowKey ColumnFamily Qualifier Value aaaa,bbb f 3,12 key1,key2はキー属性 アプリケーションデータ key-value クエリによって変換方法を適 切に決める必要がある
  4. HBaseの課題 - 利用者 1. スキーマ管理が難しい 2. アプリケーション側の負荷が高い - 複雑なクエリが実行できない -

    セカンダリインデックスがない - アプリケーション側で一貫性を保証する必要がある 12
  5. HBaseの課題 - 利用者 1. スキーマ管理が難しい 2. アプリケーション側の負荷が高い 3. 簡単な集計、検索するにはJavaを書く必要がある Hbase

    Shellはあるが機能は非常に限定的 ❌「昨日追加された行の数は?」 ❌「この列の値は何通りあるのか?」 Analytics外でも障害対応時とかデータ移行時にも必要 な情報である 13
  6. HBaseの課題 - 利用者 1. スキーマ管理が難しい 2. アプリケーション側の負荷が高い 3. 簡単な集計、検索するにはJavaを書く必要がある 4.

    利用メトリクスの可視化・費用計算が難しい ユーザの利用状況把握に必要なメトリクスが不足してい る 例 100行を3台のRegion Serverに書き込む → put数3 3行を3台のRegion Serverに書き込む → put数3 14
  7. HBaseの課題 - 運用者 1. スキーマ管理が難しい 2. アプリケーション側の負荷が高い 3. 簡単な集計、検索するにはJavaを書く必要がある 4.

    利用メトリクスの可視化・費用計算が難しい 5. RegionServerが停止すると長時間のダウンタイムが 発生する可能性がある TiDBと違いRegionは複数のRegionServerに複製され ない Memstoreにあったデータ(HDFSにフラッシュされて いないデータ)はWALから復元する必要がある データサイズによるが復旧に数分かかることがある 15 WAL HDFS HFile HFile HFile HFile RegionServer Region Memstore Memstore …
  8. HBaseの課題 - 運用者 1. スキーマ管理が難しい 2. アプリケーション側の負荷が高い 3. 簡単な集計、検索するにはJavaを書く必要がある 4.

    利用メトリクスの可視化・費用計算が難しい 5. RegionServerが停止すると長時間のダウンタイムが 発生する可能性がある 6. k8sではなく、VM上で運用しているため大変 部署内で運用しているシステムは基本的にk8s上で構築 されている DBもk8sで管理したいがHBaseはk8sで管理されるこ とが前提で作られていないため導入が大変 16
  9. マルチテナント運用:ユーザ管理機能 1. 他のユーザによる誤操作の防止 スキーマ毎に権限を付与したユーザを作成できる 2. 特定のユーザがリソースの使いすぎる事を防止 ユーザごとにリクエストユニット*1を管理できる 暴走クエリ*2を検知でき、負荷をかけているクエリをkillできる 3. 費用請求が容易にできる

    ユーザ毎に使用したリクエストユニットを把握できる*3 *1 リクエストの種類やどれくらい読み書きしたかでリソースの使用量がわかるもの(詳細) *2 ユーザが指定した実行時間を上回るクエリのこと(詳細) *3 v7.6よりmysql.request_unit_by_groupから取得可能(詳細) 22 v7.5.1からダッシュボー ドからステートメント毎の RU消費量がわかるように なった v7.6.0から日毎のRU消費 量がテーブルに保存される
  10. NewSQL比較 Spanner TiDB CockroachDB YugabyteDB Consensus Architecture - Percolator Spanner

    Spanner インターフェース GoogleSQL, PostgreSQL MySQL PostgreSQL PostgreSQL, CQL データモデル Relational, (Vector) Relational, (Vector) Relational Relational, Vector Isolation Level Serializable Snapshot, Read Committed Serializable, Read Committed Serializable, Snapshot Consistency Level Strict Strict Strong Partition Strong Partition Timestamp生成 分散時計:TrueTime (原子時計 + GPS) 集中時計:Timestamp Oracle 分散時計:HLC 分散時計:HLC パーティショニング Range Range Range Hash, Range compute, storage分離 ✅ ✅ ❌ ❌ HTAP ❌(他のGCPサービスと合わせれば可 能) ✅ TiFlash ❌ (Vectorized Execution) ❌ 地理的分散 ✅ ❌ 配置自体は可能だが性能はで ない ✅ ✅ OSS ❌ ✅ 一部の機能はEnterprise版専用( Chat2Queryなど) ✅ 一部の機能はEnterprise版専用 ✅ すべての機能がOSS プログラミング言語 ? TiDB: Go, TiKV: Rust Go C++ 24
  11. 1 - HBaseからTiDBへの移行 •概要 HBaseからTiDBへのデータ移行方法についての検証 Sparkを利用してHBaseテーブルのスナップショットからTiDBへ書き込む方法を選択 HBaseのスナップショットの読み取りにはTableSnapshotInputFormat、TiDBへの書き込みにはJDBC DataSourceを利用 他の書き込みの選択肢としてTiSparkやTiDB lightningがあるが利用していない

    TiSparkは利用しているHBaseとSparkのバージョン互換性の問題、同一k8sクラスタ内からしか実行できないなどあり断念 •目的 ダウンタイムなしで全てのデータを移行可能か 移行前後でデータの一貫性があるか 100GB程度のテーブルを移行可能か 27
  12. 1 - HBaseからTiDBへの移行 1.初期状態 2.移行先のTiDBテーブルを作成し、ダブルライトする 3.移行元のHBaseテーブルのスナップショットを作成し、Spark を利用して移行先のTiDBテーブルへ書き込む 4.最終状態:ダブルライトを終了しTiDBのみに書き込む HBase Source

    Table TiDB Target Table HBase Snapshot Table Spark Job スナップショットを作成 スナップショットを読んでTiDBのテーブルへ書き込む スナップショットを作成するのは元 のHBaseテーブルに負荷がかからな いようにするため 変換方法を記述するだけでSpark Jobを作成できるツールを作成 30
  13. 2 - 障害検証 • 概要 k8s上で稼働させるうえで、ノードに障害が発生したときの挙動や対応手順の確認が必要 各コンポーネント(pd, tikv, tidb)ごとにノード障害を再現し、影響や耐障害性について検証した •

    目的 1.サービス影響の確認 性能劣化やダウンタイムが発生するか、運用に支障をきたすようなサービス影響があるか 2.復旧手順の確認 復旧に必要な手順(自動/手動)を確認し、容易であるか、運用負担が多くないか検証 3.Automatic Failoverの挙動の確認 TiDB Operatorのautomatic failover機能により、障害発生によって不足したstatefulsetのPodを新たに作成してくれるか 33
  14. 2 - 障害検証:検証内容 • 検証手順(各コンポーネントごとに) 1. sysbenchでoltp_read_writeを実行(以後QPSを監視) 2. 各コンポーネント(pd, tidb,

    tikv)が1つ乗っているノードをシャットダウンする 3.(自動)Automatic failover機能により、新しいPodが追加で立ち上がる 4. ノードを起動する 5.(自動)復旧後、Automatic failover機能により、3.で追加されたPodが削除される コンポーネント replicas PD 3 TiKV 3 TiDB 3 34 • 実験環境 プライベートクラウドのk8s環境にTiDB Operator を使用して右記の構成でクラスタをデプロイ
  15. 2 - 障害検証:結果(補足) ① ② 35 Grafanaのダッシュボードから確認したQPS の推移(sysbench実行中) クラスタの設定: max-store-down-time

    = 30分 (tikvのstatusがdownとなるまでの時間) failoverPeriod= 5分 新しいpodが起動するまでの時間) TiDB PD TiKV コネクション切断 QPS低下 QPS低下
  16. 2 - 障害検証:結果 ※1 QPSの低下 次のリーダー選出にraft-base-tick-interval * raft-election-timeout-ticks 秒(デフォルトだと 1

    * 10秒)かかるため約10秒間QPSが低下 failoverやスケールイン時にtikv内のリージョンの移動が発生するため負荷がかかりQPSが低下する ※2 コネクションエラー DownしたTiDBと接続しているクライアントのコネクションは切断され、エラーとなる クライアントからの再接続で解消可能(障害でダウンした場合はTiProxyでは解消できない) 36 コンポーネント 1.サービス影響 2.復旧手順 3.Automatic Failover PD(Leader) 〇 問題なし 〇 特に不要 〇 期待通り動作 TiKV △ QPSの低下有※1 〇 復旧後にパッチを当て   るだけ 〇 期待通り動作 TiDB △ Down時にコネクショ   ンエラー発生※2 〇 特に不要 〇 期待通り動作 ・多少のサービス影響はあるが、概ね許容範囲 ・運用負担についてはHBaseよりも軽そう!
  17. 3 - 性能検証 どちらのワークロードも本番環境のデータを利用して検証 実行環境は障害検証と同様 • workload A:write heavy, データサイズ小さい

    write: 9600 ops/s read: 150 ops/s, ポイントセレクト データサイズ:300B • workload B:read heavy, データサイズ大きい write: 150 ops/s read: 300 ops/s, userテーブル1行 + entryテーブル50行読む データサイズ userテーブル: 5KB-80KB / row entryテーブル: 3KB / row 38
  18. 3 - 性能検証:QPS ⭕ 問題なし workload A workload B TiDBの方がレイテンシが悪いが並

    列数を上げることでHBase以上の QPSを達成 Hbase - Write Hbase - Read TiDB - Read TiDB - Write 39
  19. 3 - 性能検証:QPS ⭕ 問題なし workload A workload B 負荷を捌き切れた

    RUを考慮すると両方同時運用しても問題 ないはず TiDB - Read Hbase - Read 40
  20. 3 - 性能検証:レーテンシ ❌ 問題あり- read workload A workload B

    99%ile ~3x (1.27x/件) 🔺 50%ile ~5x (2.12x/件) 🔺 ※ パーセンタイル ~上昇率 -> いちリクエストのget行数を考慮した上昇率 TiDB - Read Hbase - Read 単純比較はできません! 1行 5行 3行 4行 41 2ms 5ms
  21. 3 - 性能検証:レーテンシ ❌ 問題あり workload A workload B 高負荷時

    99%ile ~ 2.7x 🔺 50%ile ~ 2.1x 🔺 ※TiDB版は負荷試験のデータ 50%ile 99%ile TiDB - Read Hbase - Read 42 20 ms 40 ms 60 ms
  22. 3 - 性能検証:その他の問題 workload A workload B • データサイズの大きいデータを一度に書き込むとslow TiKV

    nodeになる v7.5.1からタイムアウトが短くなり発生しやすくなった(raftstore.inspect-intervalのデフォルト値 が100msになった) Titanを導入すれば改善する? • 一度の書き込みサイズが大きいとTiDBのメモリ消費が多い TiDBでは、コミット前にすべての書き込みをTiDB メモリに保存するため BATCHステートメントやBulk DML (v8.0から追加) を利用すれば解決するかも 43