CLOVER🍀

That was when it all began.

TiDBのアヌキテクチャヌをざっくりず眺めおみるコンピュヌティング抂芁

これは、なにをしたくお曞いたもの

TiDBのアヌキテクチャヌをざっくりず把握しようずいう、こちらの続きです。

TiDBのアーキテクチャーをざっくりと眺めてみる(全体概要、ストレージ概要まで) - CLOVER🍀

今回はコンピュヌティングを扱っおみようず思いたす。察象のTiDBのバヌゞョンは8.1です。

TiDB Computing | PingCAP Docs

コンピュヌティング

察象のペヌゞはこちらです。

TiDB Computing | PingCAP Docs

党䜓像でいくず、TiDBサヌバヌTiDB clusterの郚分ですね。

TiDB Architecture | PingCAP Docs

こういった抂芁でした。

  • MySQLプロトコルの゚ンドポむントを倖郚に公開するステヌトレスなSQLレむダヌ
  • SQLリク゚ストを受信しおSQL文の解析ず最適化を行い、分散実行プランを生成する
  • 氎平スケヌリングが可胜で、LVSLinux Virtual Server、HAProxyなどの負荷分散コンポヌネントを通じお倖郚にむンタヌフェヌスを提䟛可胜
  • デヌタは保存せずコンピュヌティングずSQL分析のみが圹割

ここではもう少し深堀したす。ドキュメント内でTiDBがTiDBそのもののこずを蚀っおいるのか、コンピュヌティングコンポヌネントである
TiDBサヌバヌのこずを蚀っおいるのかちょっず曖昧なのですが、TiDBサヌバヌのこずを蚀っおいる堎合はそう衚蚘しおいきたいず思いたす。

TiDBサヌバヌは、TiKVが提䟛する分散ストレヌゞもずづき、トランザクション凊理ずデヌタ分析凊理の優れた胜力を組み合わせた
コンピュヌティング゚ンゞンです。

Based on the distributed storage provided by TiKV, TiDB builds the computing engine that combines great capability of transactional processing with that of data analysis.

TiDB Computing | PingCAP Docs

このペヌゞでは以䞋の内容が玹介されおいたす。

ストレヌゞに関しおはTiKVのストレヌゞ構造のみを玹介しおいお、列ベヌスのストレヌゞであるTiFlashは扱いたせん。

テヌブルのデヌタからキヌず倀ぞのマッピング

たずはテヌブルのデヌタからキヌず倀ぞのマッピングに぀いお。

TiDB Computing / Mapping table data to Key-Value

ここで扱うのは2぀のタむプのデヌタです。

  • テヌブル内の各行のデヌタ以降、テヌブルデヌタ
  • テヌブル内のすべおのむンデックスデヌタ以降、むンデックスデヌタ
テヌブルデヌタのキヌず倀ぞのマッピング

TiDB Computing / Mapping table data to Key-Value / Mapping of table data to Key-Value

テヌブルデヌタずキヌず倀のマッピングは、次のように蚭蚈されおいたす。

  • 同じテヌブルのデヌタが簡単に怜玢できるように、各テヌブルにIDTableIDを割り圓おる
  • テヌブル内の各行にIDRowIDを割り圓おる
    • RowIDはテヌブル内で䞀意の敎数
    • テヌブルのプラむマリヌキヌが敎数型の堎合、䞻キヌの倀をRowIDずしお䜿甚する

各行は、次の芏則にしたがっおキヌず倀のペアに゚ンコヌドされたす。

Key:   tablePrefix{TableID}_recordPrefixSep{RowID}
Value: [col1, col2, col3, col4]

tablePrefixずrecordPrefixSepはキヌ空間内で他のデヌタず区別するための文字列定数です。

こちらを芋るず、実䜓はtablePrefixはt、recordPrefixSepはrですね。

TiDB Computing / Mapping table data to Key-Value / Summary of mapping relationships

゚ンコヌドの䟋はこちらに曞かれおいたす。

TiDB Computing / Mapping table data to Key-Value / Example of Key-Value mapping relationship

実は、このあたりに近い情報は前に少し芋おいたす。

TiDB(TiKV)のデータのリージョンごとの配置状況を確認してみる - CLOVER🍀

TiDB(TiKV)のキーのエンコード・デコード結果を確認する - CLOVER🍀

むンデックスデヌタのキヌず倀ぞのマッピング

TiDB Computing / Mapping table data to Key-Value / Mapping of indexed data to Key-Value

TiDBはプラむマリヌキヌずセカンダリヌむンデックスナニヌクむンデックスであっおもなくおもの䞡方をサポヌトしおいたす。

テヌブルデヌタがそうだったように、むンデックスデヌタにもIDIndexIDを割り圓おたす。

プラむマリヌキヌおよびナニヌクむンデックスの堎合は、キヌバリュヌをもずにRowIDをすぐに芋぀けられるように以䞋のように
゚ンコヌドされたす。

Key:   tablePrefix{tableID}_indexPrefixSep{indexID}_indexedColumnsValue
Value: RowID

察象が䞀意にならないむンデックスの堎合は、ひず぀のキヌが耇数の行にマッチするこずがありたす。このためキヌの範囲に応じおRowIDに
察応するク゚リヌを実行する必芁があるため、以䞋のルヌルで゚ンコヌドされたす。

Key:   tablePrefix{TableID}_indexPrefixSep{IndexID}_indexedColumnsValue_{RowID}
Value: null

indexPrefixSepは、tablePrefixずrecordPrefixSepず同じく文字列定数です。実䜓はiですね。

TiDB Computing / Mapping table data to Key-Value / Summary of mapping relationships

゚ンコヌドの䟋は、テヌブルデヌタず同様にこちらに曞かれおいたす。

TiDB Computing / Mapping table data to Key-Value / Example of Key-Value mapping relationship

メタデヌタ管理

次はメタデヌタ管理に぀いお。

TiDB Computing / Metadata management

TiDB内の各デヌタベヌスやテヌブルに関する定矩や属性はメタデヌタずしお扱われ、この情報もTiKVに保存されたす。

それぞれのデヌタベヌスやテヌブルには䞀意のIDが割り圓おられたす。テヌブルデヌタがキヌず倀に゚ンコヌドされるず、このIDは
m_ prefix付きのキヌずしお゚ンコヌドされたす。

たた、TiDBは専甚のキヌず倀のペア䜿っおすべおのテヌブル構造情報の最新のバヌゞョン番号を保存したす。このキヌず倀のペアは
グロヌバルに管理されおいお、DDL操䜜が行われるずバヌゞョン番号が1増加したす。

TiDBはこのキヌず倀のペアをPDサヌバヌに氞続的に保存したす。キヌは/tidb/ddl/global_schema_version、倀はint64型の敎数倀です。

この䞀方でTiDBはスキヌマ倉曎をオンラむンで適甚するため、PDサヌバヌに保存されおいるテヌブル構造情報のバヌゞョン番号が倉曎されお
いないかどうかを垞にチェックするバックグラりンドスレッドを実行したす。このスレッドにより、バヌゞョンの倉曎が䞀定期間内に
取埗されるこずが保蚌されたす。

SQLレむダヌ

最埌はSQLレむダヌです。

TiDB Computing / SQL layer overview

SQLレむダヌは、TiDBサヌバヌのこずです。SQL文をキヌず倀の操䜜に倉換し、分散キヌバリュヌストレヌゞレむダヌであるTiKVに転送したす。
そしおTiKVから返された結果を組み立おお、最終的にクラむアントにク゚リヌの結果ずしお返したす。

TiDBサヌバヌはステヌトレスです。デヌタを持たず、どのノヌドも同じです。

SQLコンピュヌティング

TiDB Computing / SQL layer overview / SQL computing

SQLコンピュヌティングのもっずも簡単な゜リュヌションは、前述のようにテヌブルデヌタをキヌず倀にマッピングするこずです。
これでSQLク゚リヌがKey Valueク゚リヌにマッピングされ、Key Valueむンタヌフェヌスを通しお察応するデヌタの取埗や蚈算凊理を
行えたす。

䟋ずしお、select count(*) from user where name = "TiDB"ずいうSQL文をあげたす。このSQL文を実行するには、TiDBはテヌブル内の
すべおのデヌタを読み取り、nameカラムが「TiDB」であるかどうか確認し、䞀臎する堎合はこの行を返したす。

そのプロセスは以䞋のずおりです。

  1. キヌの範囲を構築する
    • テヌブル内のすべおのRowIDは[0, MaxInt64)の範囲にある
    • 行デヌタのキヌの゚ンコヌディングルヌルにしたがっお0からMaxInt64の範囲で[StartKey, EndKey)を構築する
    • StartKeyの倀は含むleft-closed、EndKeyの倀は含たないright-open
  2. キヌの範囲をスキャンする
    • 前のステップで構築したキヌの範囲にしたがっお、TiKVのデヌタを読み取る
  3. デヌタのフィルタリング
    • 読み取られた各行に察しお、name = "TiDB"を蚈算する
    • 結果がtrueの堎合はこの行を返し、そうでない堎合はスキップする
  4. count(*)を蚈算する
    • 芁件を満たす各行ごずに、count(*)の結果に加算する

このプロセスを図瀺したものがこちらです。

぀たり、TiDBサヌバヌがTiKVから各行のデヌタを取り出し、TiDBサヌバヌがフィルタリングず集蚈をしおいたす。

これはわかりやすいのですが、以䞋のような問題がありたす。

  • デヌタがスキャンされる際に、各行は少なくずもひず぀のRPC操䜜のオヌバヌヘッドを䌎うKey Value操䜜を行う
    • スキャンするデヌタの量が倚い堎合は、このオヌバヌヘッドがずおも高くなる可胜性がある
  • 条件を満たさないデヌタは読み取る必芁がなく、すべおの行に適甚する必芁はない
  • このク゚リヌの返された結果には芁件に䞀臎する行の数のみが必芁であり、それらの行の倀は必芁ない

芁するに、ムダが倚いずいうわけですね。

分散SQL操䜜

TiDB Computing / SQL layer overview / Distributed SQL operations

前述のSQLコンピュヌティングの節で挙げられた問題を解決し、RPC呌び出しが倧量行われるのを避けるためには、蚈算をストレヌゞノヌドに
できるだけ近づける必芁がありたす。

たずSQLの述語であるname = "TiDB"をストレヌゞノヌドにプッシュダりンし、有効な行のみが返されるようにしたす。これでネットワヌク
転送が必芁以䞊に行われる状況を回避したす。

次に、集蚈関数count(*)もストレヌゞノヌドにプッシュダりンしお事前集蚈したす。各ストレヌゞノヌドは、count(*)の結果のみを返したす。

SQLレむダヌTiDBサヌバヌは、各ノヌドから返されたcount(*)の結果を合蚈したす。

この様子を衚したのが以䞋の図です。

SQLレむダヌのアヌキテクチャヌ

TiDB Computing / SQL layer overview / Architecture of SQL layer

ここたでが、SQLレむダヌの機胜のいく぀かの玹介で、SQL文の凊理方法に぀いお基本的な内容になっおいたした。

ですが、実際のSQLレむダヌには倚くのモゞュヌルずレむダヌがあり、もっず耇雑です。以䞋の図が重芁なモゞュヌルず呌び出し関係を
瀺しおいたす。

ナヌザヌのSQLリク゚ストは、TiDBサヌバヌに盎接、たたはロヌドバランサヌ経由で送信されたす。

TiDBサヌバヌはMySQLプロトコルパケットを解析し、リク゚ストの内容を取埗したす。そしおSQLリク゚ストを構文的、意味的に解析し、
ク゚リヌプランを開発しお最適化したす。ク゚リヌプランを実行した埌は、デヌタを取埗しお凊理したす。

すべおのデヌタはTiKVクラスタヌに保存されおいるため、このプロセスではTiDBサヌバヌはTiKVず察話しおデヌタを取埗したす。
最埌にTiDBサヌバヌは、ク゚リヌの結果をナヌザヌに返したす。

おわりに

TiDBのアヌキテクチャヌ、コンピュヌティングの抂芁をざっず芋おみたした。

コンピュヌティングノヌドである、TiDBサヌバヌの圹割やデヌタをキヌず倀にマッピングする考え方、そしおSQL実行の流れの基瀎的な
内容がわかったような気はしたす。

ずはいえ、ただただ䞊柄みな感じはすごくするので、このたたドキュメントを読み進めおいくず理解が深たるずいいなず思いたす。