TiDBの「Partitionated Raft KV」内部
※このブログは2023年2月25日に公開された英語ブログ「Inside TiDB’s “Partitioned Raft KV”」の拙訳です。
著者:Qi Xu
前回の記事では、TiDB 6.6の実験的な新機能で、パフォーマンスとスケーラビリティが大きく向上したことを紹介しました。今回は、なぜそのような利点を備えているのか、その理由を深掘りしていきましょう。
アーキテクチャ
以下は、TiKVのアーキテクチャです。

図1:TiKVアーキテクチャ – 論理的データパーティション
TiKVクラスタは、多くのデータ区分 (リージョン) によって構成されています。各リージョンは、開始キーと終了キーの範囲によって決定される、データの特定の部分を担当します。そして、異なるTiKVノード上に3つ以上のレプリカを持ち、それらはRaftプロトコルによって同期されます。旧来のRaftエンジンでは、物理的にTiKVごとに1つのRocksDBインスタンスがあり、全リージョンのデータを保存していました。Partitionated Raft KV機能では、新たに物理的データレイアウトが導入され、各リージョンは独自のRocksDBインスタンスを持ちます。

図2:物理データレイアウトの比較
旧Raft KVエンジンの課題
「リージョン」はTiKVの論理的なスケール単位です。データアクセスや負荷分散、スケールアウト、スケールインのような管理者の操作は、すべてリージョンによって分割されます。しかし、現在のアーキテクチャでは、リージョンは純粋な論理的概念であり、物理的にリージョン間の境界は明確ではありません。これはつまり以下を指します:
- あるリージョンのデータをあるTiKVから別のTiKVに移動する必要がある場合 (別名リージョンバランス) 、TiKVはそのリージョンデータを取得するためだけに巨大なRocksDBインスタンスでスキャンする必要があります。これは、読み出しの増幅をもたらします。
- 複数のリージョンで大量の書き込みがあった場合、そのキー範囲が分散していると、RocksDBで他のアイドルリージョンのデータも含めた大きなコンパクションが発生する可能性があります。これにより、読み込みと書き込みの両方が増幅されます。例えば、SST11は1MBサイズのSSTで、リージョン1のデータしか持っていませんが、かなり大きなキー範囲で構成されています。SST11がL2にマージされる場合、SST21、SST22、SST23はコンパクションに参加し、リージョン2、3、4のデータを含んでいます。TiKVのサイズが大きいほど、読み書きの増幅も大きくなります。

図3:異なるリージョンのデータ間コンパクション
- リージョン間の隔離がないため、一部のホットリージョンが全リージョンのパフォーマンスを低下させる可能性があります。
その結果、旧RaftKVエンジンでは、次のような問題が発生する可能性があります。
- ノードのスケールアウトやスケールインは、データのスキャンを何度も行う必要があるため、時間がかかります。
- RocksDBの書き込みグループによるシングルスレッド書き込みのため、書き込みスループットが制限されます。
- 時折発生するコンパクションにより、RocksDBのデータサイズが大きい場合、ユーザートラフィックのレイテンシは安定しません。
Partitionated Raft KVエンジンがどのように課題を解決するか
- 各リージョンのデータは専用のRocksDBインスタンスなので、RocksDBをまるごとコピーするだけでリージョンバランスを行うことができます。読み出し増幅はしません。
- ホットリージョンの書き込みトラフィックは、自身のRocksDBのコンパクションを誘発するだけで、他のリージョンのデータを巻き込むことはありません。そのため、読み込みと書き込みの増幅を抑えることができます。
- RocksDBにデータを書き込む際には、各スレッドが異なるRocksDBインスタンスを書き込むため、同期やロック競合が発生せず、書き込みのボトルネックが解消されます。また、WALログがないため、RocksDBへの書き込みはメモリ操作となります。
- あるRocksDBが遅くても他のリージョンに影響することはありません。リージョンのパフォーマンスはストレージレイヤーで分離されているのです。
- 各リージョンのサイズは、デフォルトで15GBと大きくなりました。96MBのリージョンサイズと比較して、ハートビートなどのリージョンのオーバーヘッドとメモリフットプリントを最大99%削減することができます。
その結果、Partitionated Raft KVでは、TiDBはデータのスケールアウトやスケールインが約5倍速くなり、コンパクションへの影響が非常に少なくなったため、全体的にパフォーマンスが安定するようになりました。
トレードオフ
これまでのところ、全て順調に見えます。しかし、1つ問題があります。なぜなら、RocksDBのインスタンスが増えたので、そのmemtableのメモリ消費量が多くなってしまったからです。メモリ消費量とパフォーマンスのバランスを取るには、5GB~10GBは必要でしょう。そのため、メモリリソースが非常に逼迫している場合は、一般的にこの機能をオンにすることは推奨されません。しかし、TiKVに余分なメモリがあり、スケーラビリティと書き込み性能を気にする場合、この機能は役に立ちます。
最後に
TiDBは今のバージョンで十分だというお客様もいらっしゃるでしょう。新しい機能は重要ではない方もいるようです。しかし、1つのクラスタを複数のワークロードに利用し、それぞれのワークロードを適切に分離してQoSを保証できるとしたらどうでしょう。これが、現在開発中の「マルチテナント」と呼ばれる機能です。「Partitionated Raft KV」は、ハードウェアの性能を最大限に引き出すための機能です。また「マルチテナント」によって、複数のワークロードを1つのクラスタに統合することで、ハードウェアをフル活用し、コストを削減することができます。
TiDBを体験するには、コミュニティエディションまたはTiDB Cloud無料トライアルをお試しください。日本語ドキュメントのTiDBクイックスタートガイド、またはTiDB Cloudワークショップガイドのご利用をお勧めします。ご不明な点などございましたら、お問い合わせフォームよりご連絡ください。