首页 > 数据库 > MySQL > MyTopling:兼容 MySQL 的云原生数据库
MyTopling 是拓扑岭( topling.cn)开发的 MySQL 兼容数据库。
MyTopling fork 自 facebook 的 myrocks-8.0.23,进行了大幅修改:
在 MyRocks 中,bulk_load 和 创建索引走的是同一套逻辑,其处理方式大致为:
在 sysbench 性能测试中,我们发现 prepare 阶段创建索引的速度很慢,进一步定位到是在内存中的排序很慢,其排序方式非常原始粗暴,使用了
std::set,并且在应该给
std::set 指定自定义 KeyComparator 的地方,把 RocksDB 中的 Comparator 指针放到每个 set 元素中。所以,即便使用最普通的优化方式,也能对性能有所提升,并降低内存用量。但我们最终进行了非常彻底的优化:
这中间的核心是 AutoSortTable,我们知道,RocksDB 的 SST 是 Static Sorted Table(也有称 Sorted String Table),创建 SST 时,输入数据必须是按 Key 有序的。支持乱序输入,其本质就是把排序从 SST 外部移到内部,貌似没啥可圈可点的。
然而,这里核心中的核心是:AutoSortTable 使用了 CSPP Trie,将 Key 逐个插入 CSPP Trie,比在内存中排序还要快,并且 CSPP Trie 只使用一整块内存,这意味着创建好的 CSPP Trie 数据结构可以通过一次 write 操作写到 SST 文件中。
最终效果是,优化后,索引创建的速度提升了 30 倍以上!
分布式 Compact 的核心是把 CompactionFilter 和 TablePropertiesCollector 需要的数据字典转移到 Compact Worker 结点上,这个,我们只需要仔细研读相关代码,将数据字典进行序列化/反序列化即可,并且,ToplingDB 提供了完善 SidePlugin 机制,使得实现这一点变得相对容易。
MyRocks 中 CompactionFilter 和 TablePropertiesCollector 使用了一些全局变量,而我们的 Compact Worker 是多线程为多个 DB 实例服务的,全局变量在多线程中是共享的,这样就会导致来自多个 DB 的数据发生混淆。所以,我们将 Compact Worker 改成多进程的,将执行 Compact Job 的代码放到 fork 出来的新进程中,关于这一点,我们 在知乎上有个回答
我们的诸多修改,有一些代码使用了 topling-core,对 RocksDB 的改动也较大,但还有一些修改没有外部依赖,我们将没有外部依赖的代码,都向上游官方 RocksDB 发起了 Pull Request
time sysbench --db-driver=mysql --threads=50 --report-interval=1 \
--mysql-host=192.168.100.10 --mysql-port=3306 \
--mysql-user=test --mysql-password=1234 --mysql-db=test2 \
--tables=1000 --table_size=5000000 oltp_read_write \
--db-ps-mode=disable --mysql_storage_engine=rocksdb prepare| CPU | 双路 E5-2682 v4 共 32 核 64 线程 |
|---|---|
| 内存 | 768G, DDR4 2133 |
| SSD | 6 个 nvme SSD(三星 970 pro) |
| CPU | 双路 E5-2682 v4 共 32 核 64 线程 |
|---|---|
| 内存 | 128G, DDR4 2400 |
| SSD | 无(无盘服务器) |
| rocksdb_write_disable_wal | ON |
|---|---|
| rocksdb_flush_log_at_trx_commit | 0 |
| disable-log-bin |
|
| gtid_mode | OFF |
| enforce_gtid_consistency | OFF |
| DBOptions.allow_fdatasync | false |
在这样的软硬件配置上,上述命令花了 7067.903 秒,平均每秒钟写入超 70万行,538MB!
最终瓶颈还是在 IO 上,然而,按照 nvme SSD 的性能,6 块 SSD 的聚合带宽超过 15GB/sec,我们在运行过程中发现实际的 IO 写入只有 2~3GB/sec,操作系统并没有完全发挥硬件的 IO 性能。
所有结点(DB 结点和 Compact 结点)全程 CPU 占用率小于 50%,因为瓶颈在 IO。
这个 sysbench 命令其实更适合 InnoDB 和原版 MyRocks,因为 prepare 是按照自增 id 顺序写数据!
在 MyTopling 中,因为有分布式 Compact 加持,我们并没有针对顺序写去做优化,我们不允许把 SST 从 L0 trivial move 到 L1,也不允许从 L1 trivial move 到更下层,而是:
我们的原则是“充分并行化”,从而“为顺序写入而优化”就没有那么重要了,因为在实际业务中,绝大部分写都是随机写入!
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70013015/viewspace-2908624/ ,如需转载,请注明出处,否则将追究法律责任。