TiDBをHadoop管理者視点でデータ基盤としての使い所を考えてみる

この記事は MicroAd Advent Calendar 2022Distributed computing (Apache Spark, Hadoop, Kafka, ...) Advent Calendar 2022 の25日目の記事です。

今年のアドカレも最終日になりました。
とは言え、Distributed computing Advent Calendar 2022 の方はエントリが結構残ってるので、引き続き空いてる枠への参加をお待ちしてます!

qiita.com

qiita.com

今回は、Hadoopクラスタ管理者の視点で、データ基盤としてTiDBの使い所について考えてみます。 また、データ基盤の規模感としては、ペタバイトレベルのクラスタ、1テーブルあたり最大100TBクラスを想定しています。

TiDBとは

TiDBをすーぱーざっくりに説明すると、NewSQLに分類されるペタバイトクラスまで水平スケール出来るらしいMySQL互換の分散SQLデータベース。SQLを解釈するTiDBとデータの永続化を担うTiKVを使って実現しています。また分析用途にも対応出来るように、TiDBからデータを列指向で同期して利用するTiFlushもあります。

今回は、TiDB自体については割愛します。
詳しくは、以下のPingCAPのドキュメントを参照ください。

もしくは、Cloud Native Database Meetup #51 での発表がひとまず一通り知るにはとても参考になります。

speakerdeck.com

youtu.be

他にもPingCAP社による以下の無料トレーニングのアーカイブを読むとさらに深掘りできます。

公式のドキュメントはこっち。

また、その他の動画やユーザ事例については、PingCAP社のYouTubeチャンネルが参考になります。

www.youtube.com

他にもDeNA社とDMM社のTiDBの検証記事も深掘りしていて、とても参考になりました。

engineering.dena.com

inside.dmm.com

前振りはこの辺にして、本題に入っていきます。

データ基盤として見たときにTiDBに求めるもの

TiDB(TiFlush)の売りとして、ペタバイトクラスまで扱え列指向で分析にも使えるという事で分析系クラスタとして扱えたりしないかなと考えました。
正直なところ、役割が違うので全ての要件を満たすとは考えてないのですが、考えられる要件は以下の通り。

  1. 構築する場合の運用しやすさ
  2. データの可用性について
  3. データベースやテーブルサイズに対する上限
  4. テーブルで利用できるデータ型について
  5. スキーマ進化出来るか(テーブル定義やパーティションの変更しやすさ)

以降で、1つずつ掘り下げていきます。

構築する場合の運用しやすさ

TiUPコマンドがとにかく便利

TiDBはTiUPという管理用のCLIが用意されています。

docs.pingcap.com

これが非常によく出来ています。

雰囲気は、 SUSE RancherのKubernetesクラスタを構築するCLI RKE と同じ感じで、クラスタの構成情報や設定を記載したYAML(topology.yaml)をクラスタ外の管理用ホストからtiupコマンドを実行するとクラスタが構築出来ます(ちゃんとコマンド補完も出来る2)。

利用の際にはSSH鍵でのパスワードなしログイン出来るようにしておくと楽です3。 また、sshpass が必要っぽく書いてたり、ドキュメントにinstanceがどうの書いていますが、ベアメタルサーバーでも構築出来ます。

また、構築前にクラスタとして必要な設定が実行済みかをチェックし、適用までやってくれます。

ざっくり、topology.yamlを作成後、以下の様にするとTiUPクラスタが利用できるようになります。

# サーバの設定を確認(ubuntuユーザでSSH鍵ログイン出来るようにしています)
$ tiup cluster check ./topology.yaml --user ubuntu

# 推奨設定を反映
$ tiup cluster check ./topology.yaml --apply --user ubuntu

# TiDB v6.4.0 でデプロイ
$ tiup cluster deploy tidb-test v6.4.0 ./topology.yaml --user ubuntu

# データベース tidb-test を初期化
$ tiup cluster start tidb-test --init

# TiDBの構成情報を確認
$ tiup cluster display tidb-test

# TiDBのIP(198.51.100.4)を指定してDBに接続
$ mysql -u root -h 198.51.100.4 -P 4000 -p

詳しくは以下を参照ください。

docs.pingcap.com

topology.yamlの設定については以下が参考になります。

docs.pingcap.com

以下のTiUPコマンドを見てもらうと分かりますが、クラスタの運用で必要になる様々な事がTiUPで完結します。

TiUP Cluster | PingCAP Docs

負荷テストやベンチ、Sandbox環境も簡単。TiUPならね。

さらにすごいのは、負荷テストにも使えるベンチマーク機能もあります。以下のようにするだけでTPC-Cベンチマーク取れます4TPC-Hも出来るよ)。

$ tiup install bench
$ tiup bench tpcc -H 198.51.100.4 -P 4000 -D tpcc --warehouses 1000 --threads 20 prepare

他にも、新しいバージョンでの動作確認や開発時のローカル端末での利用の際にシュッとお試し環境を構築できるtiup playgroundが便利。

docs.pingcap.com

利用者の事を分かってるなぁと思います。

KubernetesでのTiDB構築について

TiDBはKubernetesOperatorもあるのでKubernetesでの構築も出来ます。

ただ、個人的には頻繁に構成を変えたいとかないのなら、ある程度の規模のKubernetes運用経験や環境が無いならTiUPでの運用が安全で楽だと考えます。特にストレージ層となるTiKVのPodに割り当てるVolumeは、レプリカ分もあるので最低でも論理サイズ5の3倍必要になり大量に必要ですので運用がメンドイです(Kubernetesで利用するストレージは高価になりがちなので費用も辛くなりそう)。

また、データベースとして要求されがちなパフォーマンス面もベアメタルサーバーやVMインスタンスのDisk直読みの方が速いです。

これだけ運用しやすいTiUPコマンドあるので、個人的にはKubernetesでのTiDB運用は規模がでかくなればなるほどメリットを感じません。

データの可用性について

TiKV は、Google Spanner の設計に基づいたマルチラフト グループ レプリカ メカニズムを取っているそうです。

データ自体は、リージョンという単位で格納し、複数のレプリカでRaftグループを形成しています。また、レプリカはピアと呼ばれ、通常3つで構成します。そして、ノード内のデータは、RocksDBを使って格納しています。

詳細は以下のドキュメントまたは無料トレーニングのアーカイブを参照ください。

docs.pingcap.com

pingcap.co.jp

また、RocksDB自体はRocksDBのWikiを参照ください。

github.com

データベースやテーブルサイズに対する上限

確認したい以下の項目をTiDB Limitations から確認していきます。

  1. 1テーブルあたり論理サイズで100TBクラスを扱えるか
  2. 1テーブルあたる数十億レコードクラスを扱えるのか
  3. 1万パーティションくらいは作成出来るか

テーブルサイズや行数について

無制限となっていました。
ただし、以下の通り、TiKVの1ノードあたりのDiskの上限が2TB未満ということでした。

docs.pingcap.com

It is recommended to keep the size of TiKV hard disk within 2 TB if you are using PCIe SSDs or within 1.5 TB if you are using regular SSDs.

これは結構問題です。 TiKVの1ノードあたりDiskが2TB未満ということは、レプリカを考慮するとデフォルトでピアは3つになるので、1ノードあたりの論理サイズは2TBの3分の1(0.67TB)になってしまいます。

つまり、TiDBクラスタとしてペタバイト並の論理サイズのクラスタを構築するには、TiKVだけで1,000台以上必要になってしまいます。

この1ノードあたりの上限にいては、TiKVのアーキテクチャからくるもののようです。つまり、TiKVノードの管理するリージョン数が多くなりすぎるとリージョンごとのステータス管理のためのPDとのハートビートなどに問題が発生する可能性があるので2TB未満としていると、TiDBコミュニティのSlackで教えていただきました。

また、将来的にはこの制限を緩和出来るように、Dynamic size regionといった機能をTiKVに実装して、リージョンサイズを大きくすることで同じデータ量に対するTiKVノードあたりのリージョン数を減らすことで1ノードあたりのDiskサイズの制限を緩やかにする事が可能になっていくそうです。

Dynamic size regionについては、以下のTiKVのRFCを参照ください。

github.com

パーティションについて

1テーブルあたり8192までだそうです。
hourlyでパーティションを考えた場合は、341日で1年弱なので許容出来そうですが、ただ、特定キー×hourylyでパーティションした場合では不足しそう。Hiveテーブルだと1万パーティションとか普通にあるので、もう少し増えて欲しいところです。

テーブルのデータ型やデータ操作について

TiDBで扱えるデータ型は以下のドキュメントの通り。

docs.pingcap.com

MySQL互換というだけあって、この互換性はすごいですね。

ただ、HiveテーブルにあるComplex(arrray/map/struct)型6はもちろん無いのでそこがネックです。 TiDBにはJSON型があるのでそれで代用出来そうですが、変換コストが大きいです。

以下のMySQLの互換性のドキュメントを確認して分かったのは、UDFが未対応という点はつらいです。

docs.pingcap.com

Complex型をJSON型に構造を変更するとしても、UDFが無いとETLの処理や参照時に困ります。 MySQLで出来る分としてJSON Functionsがあるのである程度の操作はやりやすいですが、UDFが無いのは辛いところ。

スキーマ進化出来るか(テーブル定義やパーティションの変更しやすさ)

MySQL互換ということで、Hiveテーブルの様なスキーマ進化は出来ない。これが一番つらい。

HiveなどHadoopエコシステムで扱うSQLエンジンは、Schema-On-Read を前提としています。つまり、データの読み取り時にスキーマを適用することを意味します。それによりスキーマの変更時にテーブルデータを再投入する必要がありません。

例えば、Hiveテーブルの場合、以下のドキュメントを見ると分かりますが、テーブル名の変更、カラムの追加・リネーム、パーティション操作などのSQL構文が用意されています。

cwiki.apache.org

さらに今となっては、Data WarehouseやDaka Lakeのいいとこ取りをしたData Lakehouseなんてものも登場して昔のHiveしか知らない人がみたら驚く進化をしているので運用負荷がさらに下がっています7

ここまでスキーマ進化にこだわるのは、データ基盤で扱うデータサイズが1テーブルで数TBはあたりまえで、大きいものだと100TB以上になるのも珍しくありません。また、利用する過程でカラムの追加やカラム名の変更やカラム位置の移動8が割りと発生します。そのため、データの洗替えが毎回発生し利用するまで数時間・数日掛かってしまってはビジネスインパクトが無視できません。

使い所を考える

Data LakeやData Warehouseとしては考えるのは無理がありました(そもそも欲しがり過ぎ)。

ただ、MySQLを水平スケールする点に着目した場合、使いどころがありました。Hiveを運用する際、テーブルのメタデータをHive Metasore(以降、HMS)を利用するのですが、HMSのデータはMySQLに格納します。

ここで問題になるのは、HDFSファイル数が多くなり、パーション数がデカくなると、パーティションをガツッと削除するとメタデータの更新でMySQLが詰まる問題があります。そこで、このMySQLをTiDBで置き換えられないか?と言う点です。

探してみたらHiveのWikiに記載がありました。みんな考えることは同じですね。

cwiki.apache.org

PingCAPのユースケースの紹介としても記事がありました。

www.pingcap.com

どうやらMySQLの代わりとし使えそうです。Hive2系までなら本番環境でも確認していて、3系でもテストはしているそうです。

もう1点、BIとしてRedash使ってる場合、QueryResultは便利なのですが、RedashのデータベースにJSON型で格納するのでQueryResultを多用するとデータベース側のDiskを圧迫するので考えものです。

ただ、RedashのデータベースはPostgreSQLしかサポートしないようなので諦め。残念。

discuss.redash.io

一方でPingCAPのBigData向けの取り組みは、TiFlash以外にもありました。

1つ目がTiSparkです。

docs.pingcap.com

SparkSQLの実行をTiKV・PDと連携して実行するものらしいです。TiFlashも合わせて利用することも出来るらしい。
トランザクションのACID特性が保証され、DataFrameも使えて複数テーブルへの書き込みも出来る。また、TiSparkはTPC-HのLINEITEMデータ6000万行を8分以内に書き込むことができるそうです。

詳しくは以下のPingCAPのブログを参照ください。

www.pingcap.com

2つ目はFlink/Hive/Trino・Prestoとの連携するTiBigDataです。

github.com

想定しているユースケースや事例などは以下のPingCAPのブログ記事がとてもおもしろいです。 例えば、Xiaohongshu社のユースケースが面白いです。TiCDCクラスタでTiDBのリアルタイムな変更データを抽出し、変更ログをKafkaに送信します。 それをFlinkはKafkaから変更ログを読み込み、集計・結合などを実行します。そして、Flinkはその結果をTiDBのワイドテーブルに書き込んで分析に利用するそうです。

www.pingcap.com

さいごに

現状のところはデータ基盤としてのTiDBの利用は限定的になりそうですが、TiSparkやTiBigdataなど、データ基盤の一部で利用できそうなものが出てきていて、今後が非常に楽しみです。また、本来の用途であるデータベースとして見た場合、MySQLとの互換性(やTiDB特有の制限事項)を受け入れ可能なら水平スケール可能なMySQLとしてとても素晴らしいプロダクトだと考えます。

また、TiDBはプロダクトだけでなくドキュメントの充実ぶりも素晴らしいのですが、動画コンテンツもしっかり用意していて導入しやすそうです。

更に、PingCAP社はコミュニティへも積極的に関わっていて、Slack でも積極的に情報発信をしています。そして、日本語チャンネル #tidb-japan もあるのでとてもありがたいです。

引き続き、TiDBについてはウォッチしていくので、なにかの機会にまた記事を書こうかと思います。

以上、MicroAd Advent Calendar 2022Distributed computing (Apache Spark, Hadoop, Kafka, ...) Advent Calendar 2022 の25日目の記事でした。


  1. Cloud Native Database Meetup #5 情報
    イベントページ / アーカイブ動画
  2. tiup completion | PingCAP Docs
  3. パスワードなしで SSH 相互信頼と sudo を手動で構成する
  4. 詳しくはこちら。Stress Test TiDB Using TiUP Bench Component | PingCAP Docs
  5. 論理サイズとはレプリカ数を考慮して実施にシステムとして利用できるサイズとします。
    反対に物理サイズは実際に必要になるDiskのサイズとします。
  6. Hiveで利用できる型。具体的には以下の3つ。
    arrays: ARRAY<data_type>
    maps: MAP<primitive_type, data_type>
    structs: STRUCT<col_name : data_type [COMMENT col_comment], ...>
    union: UNIONTYPE<data_type, data_type, ...>
    cf. LanguageManual Types - Apache Hive - Apache Software Foundation
  7. Data Lakehouseとして代表的なのは、DeltaLakeIceberg があります。また、Data Lakehouseの登場の背景については、Databricksの記事が分かりやすいです。
    データウェアハウスでよくある問題をデータレイクスで解決する方法 - The Databricks Blog
  8. データ基盤のテーブルのカラム数は数百となるので、分かりやすい位置にカラムを移動したいと言う要望は割りとあります。