TiDB を触ってみる
こんにちは。k-jun です。今週は雑多に見つけた library を試していきます。
https://github.com/pingcap/tidb
Spanner の分散データベースシステムの流派をもとにしており、OpenSource 化しようとする動きの一端ですね。 類似の BD として CockroachBD がありますが果たして。
Github を見る限りは簡単に起動できるようなので、ひとまず見てみます。
docker run --name tidb-server -d -p 4000:4000 pingcap/tidb:latest docker ps | grep tidb 6a0943cfc1fb pingcap/tidb:latest "/tidb-server" 16 minutes ago Up 16 minutes 0.0.0.0:4000->4000/tcp tidb-server
何やら動き出しましたね。接続。
mysql -h 127.0.0.1 -P 4000 -u root -D test --prompt="tidb> " Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 79 Server version: 5.7.25-TiDB-v5.0.1 TiDB Server (Apache License 2.0) Community Edition, MySQL 5.7 compatible Copyright (c) 2000, 2021, Oracle and/or its affiliates. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. tidb>
繋がりますねぇ...! Storage Engine と、トランザクション分離レベルも見てみる。
tidb> show engines; +--------+---------+------------------------------------------------------------+--------------+------+------------+ | Engine | Support | Comment | Transactions | XA | Savepoints | +--------+---------+------------------------------------------------------------+--------------+------+------------+ | InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES | +--------+---------+------------------------------------------------------------+--------------+------+------------+ 1 row in set (0.01 sec) tidb> SELECT @@GLOBAL.tx_isolation, @@tx_isolation; +-----------------------+-----------------+ | @@GLOBAL.tx_isolation | @@tx_isolation | +-----------------------+-----------------+ | REPEATABLE-READ | REPEATABLE-READ | +-----------------------+-----------------+ 1 row in set (0.00 sec)
今の処は完全に mysql。ファントムリードは発生するだろうか。
tidb1> CREATE TABLE parent ( id INT NOT NULL, PRIMARY KEY (id) ) ENGINE=INNODB; tidb1> select * from parent; +----+ | id | +----+ | 1 | | 2 | +----+ 2 rows in set (0.00 sec)
tidb1> begin; tidb2> begin; tidb1> insert parent(id) values(3); tidb2> select * from parent; +----+ | id | +----+ | 1 | | 2 | +----+ tidb1> commit; tidb2> select * from parent; +----+ | id | +----+ | 1 | | 2 | +----+ tidb2> commit; tidb2> select * from parent; +----+ | id | +----+ | 1 | | 2 | | 3 | +----+
うーん。文句ない。ではいよいよ性能比較。データを容易。ひとまず 100万レコード程度。
sysbench oltp_read_write --table-size=1000000 --mysql-db=test --mysql-user=root --mysql-host=127.0.0.1 --mysql-port=4000 prepare sysbench 1.0.20 (using bundled LuaJIT 2.1.0-beta2) Creating table 'sbtest1'... Inserting 1000000 records into 'sbtest1' Creating a secondary index on 'sbtest1'...
実行
sysbench oltp_read_write --table-size=1000000 --mysql-db=test --mysql-user=root --mysql-host=127.0.0.1 --mysql-port=4000 run sysbench 1.0.20 (using bundled LuaJIT 2.1.0-beta2) Running the test with following options: Number of threads: 1 Initializing random number generator from current time Initializing worker threads... Threads started! SQL statistics: queries performed: read: 3276 write: 936 other: 468 total: 4680 transactions: 234 (23.30 per sec.) queries: 4680 (466.03 per sec.) ignored errors: 0 (0.00 per sec.) reconnects: 0 (0.00 per sec.) General statistics: total time: 10.0410s total number of events: 234 Latency (ms): min: 36.28 avg: 42.90 max: 64.85 95th percentile: 49.21 sum: 10039.50 Threads fairness: events (avg/stddev): 234.0000/0.00 execution time (avg/stddev): 10.0395/0.00
466.03 QPS ぐらい。前に mysql v5.7 で同様の確認をした際には 800 QPS ぐらい出ていたので、少し遅い。 並列度を上げて実験してみる。
sysbench oltp_read_write --table-size=1000000 --mysql-db=test --mysql-user=root --mysql-host=127.0.0.1 --mysql-port=4000 --threads=8 run sysbench 1.0.20 (using bundled LuaJIT 2.1.0-beta2) Running the test with following options: Number of threads: 8 Initializing random number generator from current time Initializing worker threads... Threads started! FATAL: mysql_stmt_execute() returned error 9007 (Write conflict, txnStartTS=424790832799023104, conflictStartTS=424790832779624448, conflictCommitTS=424790832800858112, key={tableID=51, handle=502457} primary=[]byte(nil) [try again later]) for query 'COMMIT' FATAL: `thread_run' function failed: ...al/Cellar/sysbench/1.0.20/share/sysbench/oltp_common.lua:409: SQL error, errno = 9007, state = 'HY000': Write conflict, txnStartTS=424790832799023104, conflictStartTS=424790832779624448, conflictCommitTS=424790832800858112, key={tableID=51, handle=502457} primary=[]byte(nil) [try again later]
おろ...? コケた...。これはどういうことだろうか.... 調べたら以下がヒット。
https://github.com/pingcap/tidb/issues/5622
--oltp-auto-inc=off
オプションが現在はどうも存在していないのでひとまずエラーを無視することにして対応。2件のみの発生なので問題ないと判断。
error を返すだけなので、速度的にも遅くはなっていないはず。
sysbench oltp_read_write --table-size=1000000 --mysql-db=test --mysql-user=root --mysql-host=127.0.0.1 --mysql-port=4000 --threads=8 --mysql-ignore-errors=all run sysbench 1.0.20 (using bundled LuaJIT 2.1.0-beta2) Running the test with following options: Number of threads: 8 Initializing random number generator from current time Initializing worker threads... Threads started! SQL statistics: queries performed: read: 13300 write: 3800 other: 1898 total: 18998 transactions: 948 (94.24 per sec.) queries: 18998 (1888.65 per sec.) ignored errors: 2 (0.20 per sec.) reconnects: 0 (0.00 per sec.) General statistics: total time: 10.0579s total number of events: 948 Latency (ms): min: 54.83 avg: 84.62 max: 196.36 95th percentile: 125.52 sum: 80216.28 Threads fairness: events (avg/stddev): 118.5000/1.41 execution time (avg/stddev): 10.0270/0.02
うーん.. 微妙。mysql は 3400 QPS ぐらい出たので。並列度をもっと上げてみる。
~/ghq/github.com/slidevjs/slidev/slidev(main ✗) sysbench oltp_read_write --table-size=1000000 --mysql-db=test --mysql-user=root --mysql-host=127.0.0.1 --mysql-port=4000 --threads=128 --mysql-ignore-errors=all run sysbench 1.0.20 (using bundled LuaJIT 2.1.0-beta2) Running the test with following options: Number of threads: 128 Initializing random number generator from current time Initializing worker threads... Threads started! SQL statistics: queries performed: read: 16926 write: 4836 other: 2325 total: 24087 transactions: 1116 (102.64 per sec.) queries: 24087 (2215.40 per sec.) ignored errors: 93 (8.55 per sec.) reconnects: 0 (0.00 per sec.) General statistics: total time: 10.8714s total number of events: 1116 Latency (ms): min: 367.49 avg: 1210.11 max: 3330.35 95th percentile: 2159.29 sum: 1350477.52 Threads fairness: events (avg/stddev): 8.7188/0.90 execution time (avg/stddev): 10.5506/0.21
エラーの数がいよいよ無視できない数に。が、どうも性能が頭打ってるな。 ということで少なくとも Local の PC では mysql のほうが良さそうな結果に。 分散 DB なので Kubernetes などに乗っけて検証してみないとわからんですね。
今回はこれぐらいで。ではでは。