MariaDB 引入原子写

Sysbench OLTP, transactions per second
Sysbench OLTP,每秒事务数

在使用高性能、低延迟的存储设备(例如 SSD 卡)时,会发现新的瓶颈。这是一个关于这种瓶颈以及如何解决它的故事。

InnoDB 的一个独特功能是双写缓冲区。实现此缓冲区是为了从只写了一半的页面中恢复。这可能发生在 InnoDB 将页面(16KB = 32 个扇区)写入磁盘期间发生电源故障的情况下。在读取该页面时,InnoDB 将能够通过页面校验和不匹配来发现损坏。但是,为了恢复,需要该页面的完整副本。

双写缓冲区提供了这样一个副本。每当 InnoDB 将页面刷新到磁盘时,它首先被写入双写缓冲区。只有当缓冲区安全地刷新到磁盘后,InnoDB 才会将页面写入最终目的地。恢复时,InnoDB 会扫描双写缓冲区,并检查缓冲区中的每个有效页面,看数据文件中的页面是否也有效。

校验和计算和双写都会消耗时间,从而降低页面刷新的性能。这种影响只有在使用快速存储和繁重写负载时才会显现出来。在测试时,可以禁用这两个功能。但我强烈建议不要在生产环境中使用它们。

目前,为了使用原子写,必须使用 DirectFS 文件系统,它是 Fusion IO SDK 的一部分。Monty Program AB 的 Wlad Vaintroub 与 FusionIO 的开发人员合作,在 InnoDB/XtraDB 中实现了必要的更改以使用新功能。如果所有表空间都驻留在 directFS/FusionIO 上,从而支持原子写,则新变量 innodb_use_atomic_writes=1 将切换为使用原子写而不是双写缓冲区。此补丁已包含在 MariaDB-10.0.2 中,也将包含在 MariaDB 5.5.31 中。该功能的用户文档可在此知识库文章中找到。

现在来看数据!初步测试表明,对于小型数据集(数据集适合放入 RAM),原子写几乎没有或没有任何好处。然而,有了快速 SSD,现在可以承受拥有更大的数据集(相对于 RAM 大小),因为读写速度快得多。

以下数字是针对 Sysbench OLTP 基准测试得出的,使用了 100GB 的数据集(16 个表共 4 亿行),但 InnoDB 缓冲池中只有 16GB RAM。性能当然比通常使用 10GB 数据集时要慢。数据如下

小数据集 (10G) 大数据集 (100G)
最大只读 tps 8000 3000
最大读写 tps 6000 1800

对于大数据集,比较了以下配置

  • 双写,InnoDB 页面校验和
  • 原子写,InnoDB 页面校验和
  • 原子写,XtraDB 快速页面校验和
  • 原子写,无页面校验和
线程数 双写 原子写 原子写 + 快速校验和 原子写 + 无校验和
1 159.81 164.34 +2.8% 179.68 +12.4% 184.72 +15.6%
2 316.65 343.21 +8.4% 378.61 +19.6% 391.72 +23.7%
4 544.05 635.26 +16.8% 699.6 +28.6% 726.55 +33.5%
8 830.37 1062.8 +28.0% 1176.8 +41.7% 1214.7 +46.3%
16 1054.7 1421.2 +34.7% 1570.7 +48.9% 1610.1 +52.7%
32 1208.3 1615.1 +33.7% 1736.6 +43.7% 1767.4 +46.3%
64 1286.9 1673.2 +30.0% 1793.2 +39.3% 1833.7 +42.5%
128 1266.2 1653.1 +30.6% 1824.5 +44.1% 1875.6 +48.1%
256 1139.4 1505 +32.1% 1586.3 +39.2% 1618.3 +42.0%

结论

  • 启用原子写可以立即带来 30% 的写性能提升
  • 使用 XtraDB 的快速校验和可以将此提升到近 50%
  • 完全禁用校验和仅有微不足道的提升

基准测试详情

MariaDB-5.5.30 (lp trunk)。Sysbench-0.5 (启用 Lua)。复杂 OLTP 基准测试。16 个表共 4 亿行。16GB InnoDB 缓冲池,4GB 重做日志。

一如既往,基准测试脚本和结果可供任何人查看