MySQL 互換の NewDB として最近気になっている TiDB について調査すべく、クラスタを手元で簡単にセットアップ可能な tiup playgroud
コマンドを使って触ってみます。
気になったきっかけは PingCAP さんの Webinar でした。過去分が YouTube で公開されおり、TiDB について詳しく紹介されているため、興味のある方は見ていただくのが良いかと思います。
TiDB は MySQL 互換 (100% ではない) の NewSQL で PingCAP 社がオープンソース (GitHub) として開発しており TiDB Cloud というサービスも提供されています。Aurora では Write の性能が足りないといった場合に選択肢となるのではないでしょうか。
(PingCAP さんといえば Chaos Mesh もそうですね)
アーキテクチャ
TiDB は次の図のような構成となっています。(画像は公式ドキュメントより)

- SQL Layer にある TiDB がクライアントからの接続を受けて処理を行う
- TiDB はデータを持たないため、1台以上の任意の台数にスケール可能 (クエリ処理の CPU が足りないと思ったらここを増やす)
- データはトランザクション対応の分散 Key-value ストアである TiKV に保存される
- アクセスしたいデータがどこにあるかは Placemant Driver が持っている
- TiKV 内のデータは Region (デフォルトでは96MB) という単位で分割されています
- Region ごとに3つもしくは5つのコピーを持つ (これを node の label で別の AZ に保存されるように調整可能)
- 各 Region は Raft でクラスタ化されており、Leader が IO のリクエストを受ける
- node の負荷が偏らないように Leader を自動で切り替えたりする
- Region は Primary Key などの Range で分けられているが、収まらなくなると分割される
- TiFlash はオプションだが、列指向のデータ構造で Table 単位でデータを同期させることができ、TiDB のオプティマイザが TiKV と TiFlash のどちらを使うかを判断して使い分ける (HTAP が謳われているのはこの TiFlash があるため)
TiKV の詳細については Deep Dive というドキュメントで詳しく説明されているようです。
playground で動かしてみる
TiDB のインストール用コマンドである tiup には playground という localhost でクラスタ一式を簡単に実行するための機能があるのでこれを試してみる
tiup コマンドのインストール
ドキュメントの通りだと次のようになります。(ちょっと指定が冗長ですかね)
curl --proto '=https' --tlsv1.2 -sSf https://tiup-mirrors.pingcap.com/install.sh | sh
install.sh の中では S3 から tarball を取得して tiup バイナリを $HOME/.tiup/bin/tiup
にインストールして tiup mirror set
コマンドを実行している。
tiup mirror set https://tiup-mirrors.pingcap.com
インストール先はデフォルトでは $HOME/.tiup
となっており、 TIUP_HOME
という環境変数で指定することも可能。ここではデフォルトのまま進める。
tiup playground の実行
次のように実行するだけでクラスタができる。モニタリング関連もコミコミ。
tiup playground
必要なコンポーネントを全てダウンロードしてくれて、$HOME/.tiup
ディレクトリ下にデータなども保存される。
デフォルトでは最新バージョンがインストールされますが、引数でバージョンを指定することも可能らしい。
If you'd like to use a TiDB version other than v6.2.0, cancel and retry with the following arguments:
Specify version manually: tiup playground <version>
Specify version range: tiup playground ^5
The nightly version: tiup playground nightly
起動すると次のように表示され、MySQL クライアントから接続できるようになる。
CLUSTER START SUCCESSFULLY, Enjoy it ^-^
To connect TiDB: mysql --comments --host 127.0.0.1 --port 4000 -u root -p (no password)
To view the dashboard: http://127.0.0.1:2379/dashboard
PD client endpoints: [127.0.0.1:2379]
To view the Prometheus: http://127.0.0.1:9090
To view the Grafana: http://127.0.0.1:3000
tiup playground
は foreground で動いており、Ctrl-C で停止するとデータディレクトリごと削除されてしまいます。なのでこの後の操作は、background に移してから実行するか、別の terminal から行う。
TiDB への接続
mysql クライアントコマンドがなくても tiup client
コマンドを実行するとクライアントコマンドをダウンロードしてくれる。
$ tiup client
tiup is checking updates for component client ...
A new version of client is available:
The latest version: v1.10.3
Local installed version:
Update current component: tiup update client
Update all components: tiup update --all
The component `client` version is not installed; downloading from repository.
download https://tiup-mirrors.pingcap.com/client-v1.10.3-linux-amd64.tar.gz 4.37 MiB / 4.37 MiB 100.00% 8.48 MiB/s
Starting component `client`: /home/teraoka/.tiup/components/client/v1.10.3/tiup-client
Connected with driver mysql (5.7.25-TiDB-v6.2.0)
Type "help" for help.
my:root@127.0.0.1:4000=> show databases;
Database
--------------------
INFORMATION_SCHEMA
METRICS_SCHEMA
PERFORMANCE_SCHEMA
mysql
test
(5 rows)
my:root@127.0.0.1:4000=>
コンポーネントの確認
tiup playground display
コマンドで現在起動しているコンポーネントが確認できます。Prometheus や Grafana などのモニタリング系のプロセスは表示されない。
$ tiup playground display
tiup is checking updates for component playground ...
Starting component `playground`: /home/teraoka/.tiup/components/playground/v1.10.3/tiup-playground display
Pid Role Uptime
--- ---- ------
884 pd 8m20.111776675s
895 tikv 8m8.637417703s
1034 tidb 8m4.338608284s
1102 tiflash 7m35.750738423s
ps コマンドなどで実行されているプロセスを確認してみると次のプロセスが起動されていました。
- tiup-playground
- pd-server
- tikv-server
- tidb-server
- tiflash
- prometheus
- ng-monitoring-server
- grafana-server
Placement Driver (PD) サーバーは etcd を内包しており 2379 port で etcd としても機能しますが /dashboard
ではクラスタ全体の状況を確認できる Dashboard をブラウザで確認することができますし、/pd/
path 配下は PD としての独自の機能を持っていそうです。
$ curl -s http://127.0.0.1:2379/version | jq
{
"etcdserver": "3.4.19",
"etcdcluster": "3.4.0"
}
次のような etcd の endpoint にもアクセス可能で、/v2/keys
で key-value ストアとして PUT, GET もできるが
次のような endpoint もありました。
- http://localhost:2379/pd/api/v1/ping
- http://localhost:2379/pd/api/v1/health
- http://localhost:2379/pd/api/v1/members
- http://localhost:2379/pd/api/v1/status
- http://localhost:2379/pd/api/v1/stores
- http://localhost:2379/pd/api/v1/config
Dashboard を確認
起動時に表示されたように http://127.0.0.1:2379/dashboard にブラウザでアクセスすることで Dashboard が確認できます。かなり便利そうです。
To view the dashboard: http://127.0.0.1:2379/dashboard
多すぎるのでここには載せませんが、Grafana の Dashboard もかなり整備されています。
スケールアウトを試す
tiup playground scale-out
コマンドを使うことで各コンポーネントのスケールアウト(追加)も可能になっている。
TiDB を増やしてみる
増やす前 tidb は1プロセスしかいない。
$ tiup playground display
tiup is checking updates for component playground ...
Starting component `playground`: /home/teraoka/.tiup/components/playground/v1.10.3/tiup-playground display
Pid Role Uptime
--- ---- ------
884 pd 1h23m43.888388462s
895 tikv 1h23m32.414024691s
1034 tidb 1h23m28.115208718s
1102 tiflash 1h22m59.527339355s
tiup playground scale-out --db 2
を実行。
$ tiup playground scale-out --db 2
tiup is checking updates for component playground ...
Starting component `playground`: /home/teraoka/.tiup/components/playground/v1.10.3/tiup-playground scale-out --db 2
To connect new added TiDB: mysql --comments --host 127.0.0.1 --port 36087 -u root -p (no password)
To connect new added TiDB: mysql --comments --host 127.0.0.1 --port 41867 -u root -p (no password)
1 → 2 に増やすと思って実行したけど実際は +2 でした。
$ tiup playground display
tiup is checking updates for component playground ...
Starting component `playground`: /home/teraoka/.tiup/components/playground/v1.10.3/tiup-playground display
Pid Role Uptime
--- ---- ------
884 pd 1h24m6.602635957s
895 tikv 1h23m55.128275408s
1034 tidb 1h23m50.829461771s
57302 tidb 13.803597012s
57315 tidb 12.78547016s
1102 tiflash 1h23m22.241609485s
当然ですが、新しいプロセスの 36087, 41867 port でも接続できますし、同じデータが確認できました。
TiKV を増やしてみる
今回は +1 してみる。
$ tiup playground scale-out --kv 1
tiup is checking updates for component playground ...
Starting component `playground`: /home/teraoka/.tiup/components/playground/v1.10.3/tiup-playground scale-out --kv 1
+1 されました。
$ tiup playground display
tiup is checking updates for component playground ...
Starting component `playground`: /home/teraoka/.tiup/components/playground/v1.10.3/tiup-playground display
Pid Role Uptime
--- ---- ------
884 pd 1h30m6.988179523s
895 tikv 1h29m55.513827062s
58110 tikv 11.743457155s
1034 tidb 1h29m51.215037697s
57302 tidb 6m14.189175641s
57315 tidb 6m13.171052432s
1102 tiflash 1h29m22.627218731s
Dashboard でも確認することができます。

PD を増やしてみる
PD は奇数にしておくべきだろうということで +2 します。
$ tiup playground scale-out --pd 2
tiup is checking updates for component playground ...
Starting component `playground`: /home/teraoka/.tiup/components/playground/v1.10.3/tiup-playground scale-out --pd 2
増えま... あれ? 1つ exit status 1
でコケてる
$ tiup playground display
tiup is checking updates for component playground ...
Starting component `playground`: /home/teraoka/.tiup/components/playground/v1.10.3/tiup-playground display
Pid Role Uptime
--- ---- ------
884 pd 1h33m37.156008357s
58343 pd 5.987212106s
58353 pd exit status 1
895 tikv 1h33m25.681663993s
58110 tikv 3m41.911283186s
1034 tidb 1h33m21.382858975s
57302 tidb 9m44.356996604s
57315 tidb 9m43.338867983s
1102 tiflash 1h32m52.795006356s
receive command: scale-out
Start pd instance:v6.2.0
pd quit: exit status 1
[2022/09/04 11:41:13.321 +00:00] [INFO] [util.go:41] ["Welcome to Placement Driver (PD)"]
[2022/09/04 11:41:13.321 +00:00] [INFO] [util.go:42] [PD] [release-version=v6.2.0]
[2022/09/04 11:41:13.321 +00:00] [INFO] [util.go:43] [PD] [edition=Community]
[2022/09/04 11:41:13.321 +00:00] [INFO] [util.go:44] [PD] [git-hash=db465fee5548bf747b0a82b821d01c4c72b34b4f]
[2022/09/04 11:41:13.322 +00:00] [INFO] [util.go:45] [PD] [git-branch=heads/refs/tags/v6.2.0]
[2022/09/04 11:41:13.322 +00:00] [INFO] [util.go:46] [PD] [utc-build-time="2022-08-11 01:48:01"]
[2022/09/04 11:41:13.322 +00:00] [INFO] [metricutil.go:83] ["disable Prometheus push client"]
[2022/09/04 11:41:13.322 +00:00] [INFO] [join.go:217] ["failed to open directory, maybe start for the first time"] [error="open /home/teraoka/.tiup/data/TGSUtPb/pd-2/data/member: no such file or directory"]
[2022/09/04 11:41:13.322 +00:00] [FATAL] [main.go:91] ["join meet error"] [error="there is a member that has not joined successfully"] [stack="main.main\n\t/home/jenkins/agent/workspace/build-common/go/src/github.com/pingcap/pd/cmd/pd-server/main.go:91\nruntime.main\n\t/usr/local/go/src/runtime/proc.go:250"]
...
check detail log from: /home/teraoka/.tiup/data/TGSUtPb/pd-2/pd.log
次の項で scale-in を試そうと思っていたけど、ここでコケた pd をいないものとするため scale-in コマンドを使います。
$ tiup playground scale-in --pid 58353
tiup is checking updates for component playground ...
Starting component `playground`: /home/teraoka/.tiup/components/playground/v1.10.3/tiup-playground scale-in --pid 58353
no such process
消えました。
$ tiup playground display
tiup is checking updates for component playground ...
Starting component `playground`: /home/teraoka/.tiup/components/playground/v1.10.3/tiup-playground display
Pid Role Uptime
--- ---- ------
884 pd 1h40m23.2050935s
58343 pd 6m52.036294413s
895 tikv 1h40m11.730736319s
58110 tikv 10m27.960352843s
1034 tidb 1h40m7.431923397s
57302 tidb 16m30.406056264s
57315 tidb 16m29.387926604s
1102 tiflash 1h39m38.844062689s
再度 scale-out で +1 を実行。
$ tiup playground scale-out --pd 1
tiup is checking updates for component playground ...
Starting component `playground`: /home/teraoka/.tiup/components/playground/v1.10.3/tiup-playground scale-out --pd 1
増えました。
$ tiup playground display
tiup is checking updates for component playground ...
Starting component `playground`: /home/teraoka/.tiup/components/playground/v1.10.3/tiup-playground display
Pid Role Uptime
--- ---- ------
884 pd 1h42m22.611039171s
58343 pd 8m51.442243337s
58592 pd 8.311906211s
895 tikv 1h42m11.136697258s
58110 tikv 12m27.366317289s
1034 tidb 1h42m6.837891486s
57302 tidb 18m29.812027642s
57315 tidb 18m28.793899547s
1102 tiflash 1h41m38.250037677s
etcd の endpoint で member を確認してみる。
$ curl -s http://localhost:2379/v2/members | jq
{
"members": [
{
"id": "3037d9ad26fb2231",
"name": "pd-0",
"peerURLs": [
"http://127.0.0.1:2380"
],
"clientURLs": [
"http://127.0.0.1:2379"
]
},
{
"id": "5cbd0ce685928950",
"name": "pd-3",
"peerURLs": [
"http://127.0.0.1:37001"
],
"clientURLs": [
"http://127.0.0.1:35929"
]
},
{
"id": "615810cfd763e2cf",
"name": "pd-1",
"peerURLs": [
"http://127.0.0.1:38071"
],
"clientURLs": [
"http://127.0.0.1:39201"
]
}
]
}
$ curl -s http://localhost:2379/v2/stats/leader | jq
{
"leader": "3037d9ad26fb2231",
"followers": {
"5cbd0ce685928950": {
"latency": {
"current": 0.001328,
"average": 0.0074498699186991936,
"standardDeviation": 0.06450564994425718,
"minimum": 0.000163,
"maximum": 0.719886
},
"counts": {
"fail": 0,
"success": 123
}
},
"615810cfd763e2cf": {
"latency": {
"current": 0.000702,
"average": 0.0025673810082063333,
"standardDeviation": 0.025057330285287605,
"minimum": 0.000144,
"maximum": 0.733244
},
"counts": {
"fail": 1,
"success": 853
}
}
}
}
スケールインを試す
PD のスケールアウトでコケたプロセスを削除するためにすでに scale-in コマンドは登場しましたが、データをもつ TiKV をスケールインさせてみます。
$ tiup playground display
tiup is checking updates for component playground ...
Starting component `playground`: /home/teraoka/.tiup/components/playground/v1.10.3/tiup-playground display
Pid Role Uptime
--- ---- ------
884 pd 2h32m32.099234107s
58343 pd 59m0.930435089s
58592 pd 50m17.800106636s
895 tikv 2h32m20.624894931s
58110 tikv 1h2m36.854510585s
1034 tidb 2h32m16.326088732s
57302 tidb 1h8m39.300221586s
57315 tidb 1h8m38.282091024s
1102 tiflash 2h31m47.738225701s
scale-in
コマンドでは外したい(停止したい)コンポーネントの PID を --pid
で指定します。
teraoka@tidb:~$ tiup playground scale-in --pid 895
tiup is checking updates for component playground ...
Starting component `playground`: /home/teraoka/.tiup/components/playground/v1.10.3/tiup-playground scale-in --pid 895
tikv will be stop when tombstone
tikv の場合はデータを持っているためか tikv will be stop when tombstone と出力されます。 tombstone (ツームストーン) は見慣れない単語ですね、直訳では墓石という意味らしいが、Active Directory では廃棄という意味で登場するようだ。(廃棄 tombstone)
持っていた Region は移して停止するのか? 停止後に他の tikv からコピーするのか?
TiDB の停止時はこんな感じ。
$ tiup playground scale-in --pid 57315
tiup is checking updates for component playground ...
Starting component `playground`: /home/teraoka/.tiup/components/playground/v1.10.3/tiup-playground scale-in --pid 57315
scale in tidb success
まとめ
tiup コマンドの playground 機能でできることを確認してみた。
TiDB のクラスタは各コンポーネントが単一コマンドで完結しているなどシンプルで良いなという印象で、そのため、ローカルのクラスタでも実構成とほぼ差がない。
Dashboard も非常に充実していて運用時には重宝しそう。
TiKV でのデータの持ち方、TiDB からのアクセスの仕方などをもっと知りたくなりましたし、今回全然触れなかった MySQL 互換の部分についても今後触れていきたい。各 TiDB インスタンス間のキャッシュの同期はどうなっているのか?
tiup コマンドは同様に簡単にプロダクション用のクラスタも作れるらしいので便利。