地方エンジニアの学習日記

興味ある技術の雑なメモだったりを書いてくブログ。たまに日記とガジェット紹介。

【TiDB】入門する

記事説明

NewSQLに触れる機会が出てきそうなのでとりあえず概要だけでも知っておきたいので入門する。

所謂「NewSQL」と呼ばれるトランザクション処理を実現しつつもreadもwriteもスケーラビリティを備えた新しい種類のRDB。そのNewSQLの中でも今回はOSSで開発されている「TiDB」(タイディービーについて書いていきます。MySQL互換として使えるのは色々できそうでとても興味がある。

入門してみた感想

シャーディングをTiDBの方でいい感じにやってくれるのはとてもよさそうに思えた。とんでもないデータ量のテーブルを構造から再設計して〜みたいなケースは結構あると思っていて再設計ではなくシャーディングをしかも自動でやってくれるのはとても助かる良い機能。コンポーネントごとにスケールアウトすることが可能というのもクラウドネイティブだなと感じた。レイテンシが上がるというデメリットとスタートするまでに複数コンポーネントが必要というのがちょっとつらいのかなぁと感じた。readだけじゃなくwriteのスケールはただめちゃめちゃロマン。

NewSQL

NewSQLは新しい形のSQLデータベースで、スケーラブルな性能や分散アーキテクチャなど、これまでのRDBMSには無いような特徴を持っている。

qiita.com

TiDB

pingcap.co.jp

TiDBはアプリケーションからはMySQLと同様にアクセスできるMySQL互換のプロトコルを備えている。SQL文を処理する「TiDB」とデータを処理する「TiKV」という2つのレイヤに加えてそのへんのうまいこと連携させているPDというレイヤがある。公式のアーキテクチャはこんな感じ。Placement Driverがトランザクションやデータの配置場所を決めるいちばん重要な役割となっている。

TiDBはMySQL互換(100% ではない)のNewSQLでPingCAP 社がオープンソースとして開発している。PingCAP社は日本法人もある模様

mobile.twitter.com

国内の導入事例が結構ある。

pingcap.co.jp

対応している言語とかはこの辺。結構豊富。

TiDB の機能/特徴

  • 水平分散のスケールアウト / スケールイン
  • マルチレプリカ と高可用性
  • リアルタイム HTAP
  • クラウドネイティブの分散データベース
  • MySQL プロトコル 及び MySQL エコシステムと互換性

TiDB

SQLを解釈してデータの保存や集計などをしてクライアントへ応答する。Goで実装されている。データの保存などはしていないステートレスなコンポーネント。クエリ処理の CPU が足りないと思ったらここを増やす。

github.com

Placement Driver

すべての単一 TiKVノードのリアルタイムデータ分散のメタデータと、TiDB クラスター全体のトポロジー構造を格納している。トランザクション管理なども行う。アクセスしたいデータがどこにあるかは Placemant Driver が持っている。

github.com

TiKV

実際にデータを触る部分。CNCFによって管理されていてGAになっている。Rustで実装されている(パフォーマンスが重要なのでGoではなくRustなのだろうか?)。名前の通り Key-Value Storeとして動作するソフトウェアである。TiKV 内のデータは Region (デフォルトでは96MB) という単位で分割されている。各 Region は Raft でクラスタ化されており、Leader が IO のリクエストを受ける。TiKVは、Raftを使用してデータを複製している。(Raft何もわからん...)

github.com

もちろんMVCCがある。TiKVのトランザクションは、実行プロセスでは書き込み衝突を検出しません。衝突を検出するのはコミットフェーズ内だけとなる。

トランザクション分離レベル

docs.pingcap.com

TiDB の Repeatable Read 分離レベルは、MySQL とは異なります。 MySQL Repeatable Read 分離レベルは、更新時に現在のバージョンが表示されるかどうかをチェックしません。つまり、トランザクションの開始後に行が更新されていても、更新を続行できます。対照的に、トランザクションの開始後に行が更新された場合、TiDB オプティミスティック トランザクションロールバックされ、再試行されます。 TiDB の楽観的同時実行制御でのトランザクションの再試行は失敗し、トランザクションの最終的な失敗につながる可能性がありますが、TiDB の悲観的同時実行制御と MySQL では、更新トランザクションが成功する可能性があります。

MySQLとは少し違うらしい。トランザクションロールバック処理の後をアプリケーションで制御してる場合はそのへんに修正が必要になりそう

マイグレーションツール

公式から出ている。binlog使って差分データ移行も出来るっぽい。

speakerdeck.com

使ってみる

tiupというツールで簡単にクラスタを作れるのでやってみました。

$ curl --proto '=https' --tlsv1.2 -sSf https://tiup-mirrors.pingcap.com/install.sh | sh
$ ~/.tiup/bin/tiup playground
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

ダッシュボードも見れる。クラスタの状態とかkeyの配置状況とかまで見れる。

cliでも見れる

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| INFORMATION_SCHEMA |
| METRICS_SCHEMA     |
| PERFORMANCE_SCHEMA |
| mysql              |
| test               |
+--------------------+

テーブル作ってinsertしてselect

mysql> CREATE TABLE t1 (a int);
Query OK, 0 rows affected (0.11 sec)

mysql> DESC t1;
+-------+---------+------+------+---------+-------+
| Field | Type    | Null | Key  | Default | Extra |
+-------+---------+------+------+---------+-------+
| a     | int(11) | YES  |      | NULL    |       |
+-------+---------+------+------+---------+-------+
1 row in set (0.00 sec)

mysql> SHOW CREATE TABLE t1\G
*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE `t1` (
  `a` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
1 row in set (0.00 sec)

mysql> INSERT INTO t1 (a) VALUES (1);
Query OK, 1 row affected (0.02 sec)

mysql> SELECT * FROM t1;
+------+
| a    |
+------+
|    1 |
+------+
1 row in set (0.00 sec)

performance_schema。ちょっと少ない

mysql> show tables;
+-------------------------------------+
| Tables_in_performance_schema        |
+-------------------------------------+
| events_stages_current               |
| events_stages_history               |
| events_stages_history_long          |
| events_statements_current           |
| events_statements_history           |
| events_statements_history_long      |
| events_statements_summary_by_digest |
| events_transactions_current         |
| events_transactions_history         |
| events_transactions_history_long    |
| global_status                       |
| pd_profile_allocs                   |
| pd_profile_block                    |
| pd_profile_cpu                      |
| pd_profile_goroutines               |
| pd_profile_memory                   |
| pd_profile_mutex                    |
| prepared_statements_instances       |
| session_status                      |
| session_variables                   |
| setup_actors                        |
| setup_consumers                     |
| setup_instruments                   |
| setup_objects                       |
| tidb_profile_allocs                 |
| tidb_profile_block                  |
| tidb_profile_cpu                    |
| tidb_profile_goroutines             |
| tidb_profile_memory                 |
| tidb_profile_mutex                  |
| tikv_profile_cpu                    |
+-------------------------------------+
31 rows in set (0.00 sec)

SQLが実行されるまで

tikv.org

regionごとに並列にクエリは実行される。

終わり

今すぐ使えるかはちょっとわからなかったので詳しく調べていきたい

参考資料