(一)背景
开源数据库 MyTopling 是基于开源存储引擎 ToplingDB 的 MySQL,MyTopling 分叉自 MyRocks,兼容 MyRocks,ToplingDB 分叉自 RocksDB,兼容 RocksDB。MyTopling 和 ToplingDB 相比上游都实现了巨大的性能提升与成本降低。
在阿里云的大力支持下,MyTopling 成功上线计算巢:私有化部署版,高级版,基础版,集成版(集成 LNMP/Wordpress),特价版 2核2G ¥99包年。
(二)Parallel Scan
innodb 有个选项 innodb_parallel_read_threads
,其最典型的用途是在select count(*) from SomeTable
中启用多线程扫描。
我们认为该特性对 MyTopling 引擎也非常有用,但是上游 MyRocks 没有这个功能,并且这个功能还需要下层 ToplingDB 的支持,同样 ToplingDB 的上游 RocksDB 也没有这个支持。
因为这种 Feature 需要很多脏活累活,我们本想着偷懒等上游来实现,前两天实在忍不了,就自己来下手。
(三)引子:并行排序
传统排序算法中,快速排序与归并排序可以优雅地实现多线程排序,其中快排的线程数在递归中先少后多,归并排序线程数的在递归中先多后少。但这都有一个问题,就是无法线性 Scale,瓶颈在于其中的串行部分,例如对于快排:
void pqsort(Type* a, int n) {
if (n set rocksdb_parallel_read_threads = 32;
mysql> select count(*) from bmsql_history;
+-----------+
| count(*) |
+-----------+
| 471235271 |
+-----------+
1 row in set (0.73 sec)
mysql> set innodb_parallel_read_threads = 32;
mysql> select count(*) from bmsql_history_innodb;
+-----------+
| count(*) |
+-----------+
| 471235271 |
+-----------+
1 row in set (10.07 sec)
32 线程时,ToplingDB 性能是 innodb 的 13 倍多!我们减少线程数:
mysql> set rocksdb_parallel_read_threads = 16;
mysql> select count(*) from bmsql_history;
+-----------+
| count(*) |
+-----------+
| 471235271 |
+-----------+
1 row in set (1.40 sec)
mysql> set innodb_parallel_read_threads = 16;
mysql> select count(*) from bmsql_history_innodb;
+-----------+
| count(*) |
+-----------+
| 471235271 |
+-----------+
1 row in set (7.76 sec)
16 线程时,ToplingDB 耗时多了 1 倍,而 innodb 反而更快了。再减少线程数到 8:
mysql> set rocksdb_parallel_read_threads = 8;
mysql> select count(*) from bmsql_history;
+-----------+
| count(*) |
+-----------+
| 471235271 |
+-----------+
1 row in set (2.67 sec)
mysql> set innodb_parallel_read_threads = 8;
mysql> select count(*) from bmsql_history_innodb;
+-----------+
| count(*) |
+-----------+
| 471235271 |
+-----------+
1 row in set (11.20 sec)
ToplingDB 耗时又多了接近 1 倍,innodb 耗时只多了 44%。
可以看到,ToplingDB 的单线程性能远高于 innodb,并且随线程数线性 scale,innodb 的 scale 能力则差很多。简单计算可知,ToplingDB 每线程每秒钟可扫描 2200万条,这还是在 Xeon 2682v4 这种老古董的服务器上,较新的服务器会快 ~50%!
一般而言,因为读放大,LSM 的读性能不可能追得上 Btree,但是 ToplingDB 凭借各种优化,不仅超越了同宗的 RocksDB,还超过了使用 Btree 的 innodb。不仅仅这个功能实现了巨大超越,还有很多其它功能也是大幅超越:
(八)限制
目前我们仅支持 select count(*)
全表/全索引扫描的并行化。