赞
踩
WAL是SQLite3.7.0版本引入的一个重大改进。SQLite官网宣称在很多使用场景下,WAL模型的性能都要好于默认的DELETE模式。下面将针对几个主要场景对WAL性能做测试,测试的硬件与xxx保持一致。
纯写场景
1) 测试说明
测试简单更新事务在WAL模式下与DELETE日志模式性能对比,测试语句形如:update user set c1=c1+1 where id=xxx,id为主键,串行执行更新。通过执行1w个更新事务,统计程序运行时间。
2) 测试结果
测试时间结果以毫秒计算,TPS是每秒执行的事务数,通过事务数与时间相比获取结果。
| WAL模式 | DELETE模式 |
第一轮 | 55176 | 159196 |
第二轮 | 54442 | 164341 |
第三轮 | 56171 | 162329 |
第四轮 | 56167 | 166117 |
第五轮 | 55969 | 163139 |
平均值 | 55581 | 163024 |
TPS | 179.9 | 61.3 |
3) 结果分析
从测试结果来看,WAL日志模式下,纯写性能要远远好于DELETE模式,前者大概是后者的3倍。这个性能差异主要源于每次事务提交,WAL模式只需要将更新的日志写入磁盘即可,而DELETE模式修改过程中,首先需要将原始数据页拷贝到日志文件中,并进行fsync;然后再将修改页写入磁盘,同时也需要fsync,确保数据落盘,并且还要将日志文件清除。因此,写事务在WAL模式下,只需要一次fsync,并且是顺序写;而DELETE模式下,需要至少两次fsync(日志,数据),并且更新的数据可能离散分布在多个page中,因此可能需要多个fsync来完成。众所周知,fsync调用是非常耗时的,导致DELTE模式下写性能不如WAL模式。
纯读场景
1) 测试说明
测试WAL模式下,纯读性能数据,测试语句形如:“select * from user where id = xxx”,id为主键,对比WAL模式与DELETE模式下读性能。每个线程执行10w次查询,统计最终执行时间。QPS为每秒执行的查询数
2) 测试结果
| WAL模式 | DELETE模式 | ||
2线程 | 4线程 | 2线程 | 4线程 | |
第一轮 | 2847 | 5050 | 4124 | 8168 |
第二轮 | 2730 | 5795 | 3833 | 8074 |
第三轮 | 2688 | 5675 | 3819 | 8077 |
第四轮 | 2959 | 5894 | 3881 | 7787 |
第五轮 | 2836 | 5924 | 3873 | 7958 |
平均值 | 2817 | 5667 | 3906 | 8012 |
QPS | 7w | 7w | 5.1w | 5w |
3) 结果分析
从结果来看,WAL模式下,读性能要好于DELETE模式,大概提高了将近30%。这说明开启WAL模式下,对读性能也有提高。目前我还没有找到性能提升的原因,后续仔细阅读源码后,再做分析。
读写场景
1) 测试说明
在WAL模式下,事务提交时实际是以append方式写wal日志文件,因此读写不冲突;而DELETE模式下,写事务需要写DB(缓存,文件),与读事务读DB(缓存,文件)冲突,因此只能串行读写,通过前面的测试可知,WAL模式下,每秒读写事务数比例大概是500:1;DELETE模式下,每秒读写事务数比例大概是800:1,这里的测试不打算比较读写同时存在时两种模式的对比,而是单独测试WAL,以读写比为500:1场景,看看读写的QPS和TPS是否与单独执行有差异。测试中,读写线程都并发读写同一张表,读采用5个线程,主键查询,每个线程执行100w个读;写采用1个线程,主键更新,执行1w次写。测试时间的单位为毫秒,QPS和TPS分别为每秒的读和写,QPS=500w/时间,TPS=100w/时间。
2) 测试结果
| WAL模式 | |
第一轮 | 67543 | |
第二轮 | 66812 | |
第三轮 | 72946 | |
第四轮 | 78844 | |
第五轮 | 74501 | |
平均值 | 72129 | |
QPS|TPS | 6.94w | 138 |
3) 结果分析
通过读写比500:1的测试模型,基本保证了读写是同时完成的,从另外一方面来说,就是读写是充分竞争的。从测试结果来看,WAL模式下,读的QPS为6.94w,与单独测试读7w的性能几乎无差异;写的TPS为138, 较单独测试写的179略有下降,这可能与设置的读写比有关系。通过测试结果可以充分说明,WAL模式下,读写是充分并发的,并且几乎没有性能损耗。
批量导入场景
1) 测试说明
这个测试主要了了解WAL模式和DELETE模式下,导入数据性能对比。创建2个表,每个表导入10w条记录,总共20w记录,观察导入的时间。
2) 测试结果
| WAL模式 | DELETE模式 |
第一轮 | 28019 | 18036 |
第二轮 | 28500 | 17959 |
第三轮 | 28575 | 17578 |
第四轮 | 29078 | 18076 |
第五轮 | 29184 | 17989 |
平均值 | 28671 | 17909 |
TPS | 6975 | 11167 |
3) 结果分析
从结果来看,DELETE模式的批量导入性能要好于WAL模式,这主要源于,DELETE模式记录的是old-page,而insert操作没有old-page,所以无需记录日志,而WAL记录的是修改页,所以代价比DELETE模式高。
wal文件大小测试
1) 测试说明
wal模式下,日志采用单独的wal文件,事务将更新写入wal文件,事务执行过程中,不断写wal文件,直到提交后,才有机会做检查点,控制wal文件不继续膨胀。由于端设备,空间资源也非常稀缺,我们来看看wal 模式和delete模式下日志文件对空间的损耗。WAL模式下, wal_autocheckpoint用来控制做检查点时机,这个参数对WAL文件影响至关重要,测试也围绕、这个参数展开。
2) 测试结果
场景 | 日志文件容量 | |
| WAL模式 | DELETE模式 |
批量导入(大事务) | 200M | 4k |
主键更新(1w行事务) wal_autocheckpoint=1000 | 20M | 19M |
单条更新(单行事务) 更新1w行 wal_autocheckpoint=1000 | 1M | 4k |
单条更新事务 更新1w行 wal_autocheckpoint=4000 | 4M | 4k |
单条更新事务 更新1w行 wal_autocheckpoint=0 | 42M | 无 |
3) 结果分析+
从测试结果来看,批量导入大事务时,测试中DB文件200M,产生的WAL日志文件也是200M,由于是INSERT操作,DELETE模式下,日志文件记录原始数据页,所以依然为4k,这4k应该是控制信息。对于大事务更新操作,WAL模式和DELETE模式产生的日志量基本相当,只不过一个记录修改后的数据,一个记录修改前的数据。对于单行事务,DELETE模式的日志文件基本没有增长,而WAL模式下,日志文件与wal_autocheckpoint参数相关,默认情况下该参数值为1000个page,每个page_size为1k,因此大约为1M;调整为4000后,日志文件也随之膨胀到4M;设置为0,亦即关闭检查点后,更新1w条记录,将使wal膨胀到42M。因此,无论是WAL模式还是DELETE模式,事务大小都对日志文件大小有影响,对于WAL模式,为了控制日志文件大小,wal_autocheckpoint参数非常重要。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。