CLOVER🍀

That was when it all began.

TiDBのアーキテクチャーをざっくりと眺めてみる(ストレージエンジン概要:TiKV編)

これは、なにをしたくて書いたもの?

TiDBのアーキテクチャーをざっくりと把握しようという、このあたりの続きです。
※最初のエントリーがこのシリーズのインデックスページにもなっています

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

TiDBのアーキテクチャーをざっくりと眺めてみる(コンピューティング概要) - CLOVER🍀

今回はストレージエンジンのひとつであるTiKVを見ていこうと思います。

TiKV Overview | TiDB Docs

対象のTiDBのバージョンは8.1です。

TiKV

TiKVについて書かれたページはこちら。

TiKV Overview | TiDB Docs

最初の文が、本当に概要ですね。

TiKV is a distributed and transactional key-value database, which provides transactional APIs with ACID compliance. With the implementation of the Raft consensus algorithm and consensus state stored in RocksDB, TiKV guarantees data consistency between multiple replicas and high availability. As the storage layer of the TiDB distributed database, TiKV provides the read and write service, and persist the written data from applications. It also stores the statistics data of the TiDB cluster.

  • TiKVは分散型で(ACID準拠のトランザクションAPIを提供する)トランザクショナルなKey-Valueデータベースである
  • Raftコンセンサスアルゴリズムの実装とRocksDBの保存されたコンセンサス(合意形成)の状態により、TiKVは複数のレプリカ間のデータの一貫性と高可用性を保証する
  • TiKVはTiDB分散データベースのストレージレイヤーとして、読み取り・書き込みサービスを提供し、アプリケーションから書き込まれたデータを永続化する

アーキテクチャーの概要

TiKVのアーキテクチャーの概要です。

TiKV Overview / Architecture Overview

  • Google Spannerの設計にもとづき、マルチRaftグループレプリカメカニズムを実装している
  • リージョンは移動できるKey-Valueデータの基本単位であり、ストア内でのデータの範囲を指している
  • 各リージョンは複数のノードに複製され、これら複数のレプリカがRaftグループを形成する
  • リージョンのレプリカはピアと呼ばれ、通常リージョンには3つのピアがある
    • そのうちひとつがリーダーで読み取り・書き込みサービスを提供する

こちらがそれを表した図ですね。リージョンのレプリカが3つ、3ノードに展開されRaftグループを形成していることを示しています。

このリージョンのバランスを調整するのはPDサーバーで、TiKVクラスター内のすべてのノード間で読み取りおよび書き込みのスループット
バランスが保たれるように調整します。

リージョンとRocksDB

リージョンとRocksDBについて。

TiKV Overview / Architecture Overview / Region and RocksDB

  • 各ストア内にはRocksDBデータベースがあり、ローカルディスクにデータを保存する
    • すべてのリージョンのデータは、各ストアの同じRocksDBインスタンスに保存される
  • Raftコンセンサスアルゴリズムに使用されるすべてのログは、各ストアのRocksDBインスタンスに保存される
    • これはシーケンシャルI/OのパフォーマンスがランダムI/Oより優れているため
  • Raftログとリージョンのデータは異なるRocksDBインスタンスに保存され、TiKVはRaftログとTiKVのリージョンへのすべてのデータ書き込み操作をひとつのI/O操作に統合してパフォーマンスを向上させる

RocksDBについてのさらに詳細は、こちらに書かれています。

RocksDB Overview | TiDB Docs

リージョンとRaftコンセンサスアルゴリズム

リージョンとRaftコンセンサスアルゴリズムについて。

TiKV Overview / Architecture Overview / Region and Raft Consensus Algorithm

  • リージョンのレプリカ間のデータの一貫性は、Raftコンセンサスアルゴリズムによって保証される
    • リージョンのリーダーのみが書き込みサービスを提供でき、リージョンのレプリカの過半数にデータが書き込まれた場合のみ書き込み操作が成功する
  • TiKVはクラスター内の各リージョンを適切なサイズに維持しようとする
    • リージョンのデフォルトのサイズは96MB
    • PDサーバーがTiKVクラスター内のノード間でリージョンのバランスをとる
    • あるリージョンのサイズがしきい値(デフォルトで144MB)を超えると、TiKVは2つ以上のリージョンに分割する
    • あるリージョンのサイズがしきい値(デフォルトで20MB)より小さくなると、TiKVは隣接する2つの小さなリージョンをひとつのリージョンに統合する
  • PDサーバーがレプリカをあるTiKVノードから別のTiKVノードに移動するフロー
    • まずターゲットノードにLearnerレプリカを追加する
    • Learnerレプリカのデータがリーダーレプリカのデータとほぼ同じになったら、PDサーバーはLearnerレプリカをフォロワーレプリカに変更する
    • 最後にPDサーバーはソースノードのフォロワーレプリカを削除する
  • PDサーバーがリーダーレプリカをあるTiKVノードから別のTiKVノードに移動するフロー
    • 基本的にはレプリカの移動と同じ
    • 違いは、Learnerレプリカがフォロワーレプリカになった後で、自らをリーダーレプリカとして選出するための選挙を積極に提案する「リーダー転送」操作が行われること
    • 最後に新しいリーダーレプリカがソースノード内の古いリーダーレプリカを削除する

レプリカの移動の際には、いったん投票件を持たないLearnerレプリカを作成してデータに追いついたらソースのレプリカを削除する
ということですね。

分散トランザクション

分散トランザクションについて。

TiKV Overview / Distributed Transaction

  • TiKVは分散トランザクションをサポートする
  • ユーザーまたはTiDBは、同じリージョンに属しているかどうかを気にすることなく複数のキーと値のペアを書き込むことができる
  • TiKVは2フェーズコミットを使用してACID制約を実現する

2フェーズコミットの詳細についてはこちら。

TiDB Optimistic Transaction Model | TiDB Docs

こういうフローになっているようです。

TiKVコプロセッサ

TiKVコプロセッサーについて。

TiKV Overview / TiKV Coprocessor

  • TiKVコプロセッサーは各リージョンの計算処理を行うもの
  • TiDBは一部のデータ計算ロジックをTiKVコプロセッサーにプッシュする
  • TiKVコプロセッサーに送信される各リクエストには、ひとつのリージョンのデータのみが含まれる

その他

Titanというキーと値を分離するRocksDBプラグインがあるようです。Titanを使用すると、大きな値が使用される場合にRocksDBの書き込みの
増加を軽減できるとされています。

Titan Overview | TiDB Docs

キーと値のペアのサイズが大きい場合(1KBまたは512Bより大きい)、書き込み、更新、ポイント読み取りのシナリオではTitanの方が
RocksDBよりパフォーマンスに優れているとされています。

一方でTitanはストレージスペースとRangeクエリーのパフォーマンスを犠牲にするのがトレードオフになっているようです。
このトレードオフSSDの価格が下がり続けるとより意味のあるものになると考えられているようです。

おわりに

TiDBのアーキテクチャー、TiKVストレージエンジンを見てみました。

リージョンやRaft、レプリカの話が簡潔にまとまっていて理解が進んだ気がします。