简介

sysbench 是一个模块化的、跨平台、多线程基准测试工具,主要用于评估测试各种不同系统参数下的数据库负载情况。本测试使用 sysbench 分别向官方原版 MySQL 和 TerarkSQL 导入 450,000,000 条数据,测试在不同内存下两者的读写性能。

非常值得注意的是,sysbench 测试中默认的数据分布是 special,表示热点非常集中的数据,从而测试结果主要体现的是缓存的性能。这就是为什么大家经常发现 sysbench 测试出来性能很高,一到生产环境,性能就跪了。

好在 sysbench 也有对其它数据分布的支持,例如 uniform,即均匀分布,其测试结果主要体现的是随机访问的性能。本文中所有的测试均使用 uniform 分布。

测试程序使用 terark/sysbench 1.0.1,我们在原版 sysbench 的基础上添加了一个次级索引范围查询测试。

测试的数据库有:TerarkSQL (下简称 TerarkDB),不开启压缩的官方原版 MySQL(下简称 InnoDB 无压缩)以及开启压缩的官方原版 MySQL(下简称 InnoDB 有压缩)。

测试平台

  • CPU: Intel(R) Xeon(R) CPU E5-2630 v3 @ 2.40GHz x2 (共16核32线程)
  • 内存: DDR4 16G @ 1866 MHz x 12 (共 192 G)
  • SSD: INTEL SSDSC2BP48 0420 IOPS 89000
  • 操作系统: CentOS 7

测试中使用的官方原版 MySQL 版本为 Ver 5.6.35 for linux-glibc2.5 on x86_64。

下文 G, GB 指 230,而非 109

数据导入

测试中使用 sysbench 导入了 450,000,000 条数据,平均每条数据约 196 字节,总大小为 82.1G;另外,有个 Secondary Index,也要占用空间,因为辅助索引列和主键索引列都是 int32,所以逻辑上,对于每条数据,辅助索引的空间占用是 8 字节,从而辅助索引的逻辑空间占用就是 8*45e7 = 3.4G。所以,数据源的等效尺寸就是 (196+8)*45e7 = 85.5G

数据导入后,数据库尺寸大小比较如下:

数据库尺寸 数据条数 单条尺寸 总尺寸 索引+数据
InnoDB 无压缩 101 G 450,000,000 196 字节 82.1 G 85.5 G
InnoDB 有压缩 56 G
TerarkDB 51 G

注1:sysbench 导入的数据是自动生成的,不是真实数据,TerarkDB 对这种假数据的压缩率,远低于对真数据的压缩率。

导入数据所使用的 sysbench 命令如下:

sysbench --report-interval=1 --db-driver=mysql --mysql-port=3306 \
         --mysql-user=root --mysql-db=sysbench --mysql-host=127.0.0.1 \
         --threads=32 --tables=1 --mysql_storage_engine=innodb \
         --table-size=450000000 --rand-type=uniform --create_secondary=on \
         /path/to/share/sysbench/oltp_insert.lua prepare

注2:插入时一定要指定 --rand-typeuniform,因为其默认值 special 为热点分布,导入的数据不能体现数据库真实的随机读写性能。

测试结果

我们运行了四种测试:

  • 主键等值查询(point_select)
  • 读写混合查询(point_select90_update10)
  • 次级索引等值查询(secondary_random_points100)
  • 次级索引范围查询(secondary_random_limit100)

这四种测试分别在 192G、32G、8G 的内存限制下运行,不同的内存限制使用内存挤占工具实现,内存挤占工具挤占一定数量的内存(不可换出)确保数据库所能使用的内存为以上指定值。

每次测试中 InnoDB 的 innodb_buffer_pool_size 总是设置为可用内存的 70%,TerarkDB 的 softZipWorkingMemLimithardZipWorkingMemLimit 分别设置为可用内存的 1/81/4.

所有的测试均使用 32 个线程,每次测试前先 warm up 30 秒,每次测试持续 15 分钟

内存测试类型TerarkDBInnoDB 无压缩InnoDB 有压缩
QPS TPS RPS QPS TPS RPS QPS TPS RPS
192G point_select 123,615 1,236.15 123,615 178,282 1,782.82 178,282 158,869 1,588.69 158,869
point_select90_update10 101,410 1,014.10 101,410 50,695 506.95 50,695 6,555 65.55 6,555
secondary_random_points100 5,143 5,143.00 514,300 14,278 14,278.79 1,427,800 2,556 2,556.01 255,601
secondary_random_limit100 9,139 91.39 913,900 21,164 211.64 2,116,400 2,749 27.49 274,900
32Gpoint_select 89,998 899.98 89,998 22,301 223.01 22,301 38,328 383.28 38,328
point_select90_update10 46,122 461.22 46,122 12,445 124.45 12,445 2,896 28.96 2,896
secondary_random_points100 1,309 1,309.22 130,922 228 227.68 22,768 269 269.14 26,914
secondary_random_limit100 1,743 17.43 174,300 232 2.32 23,200 398 3.98 39,800
8G point_select 68,864 688.64 68,864 23,829 238.29 23,829 29,016 290.16 29,016
point_select90_update10 29,916 299.16 29,916 12,787 127.87 17,787 2,103 21.03 2,103
secondary_random_points100 841 841.00 84,100 172 171.63 17,163 69 69.77 6,977
secondary_random_limit100 925 9.25 92,500 251 2.51 25,100 311 3.11 31,100

注3:

上表中 QPS 表示 Queries Per Second,TPS 表示 Transactions Per Second,RPS 表示 Rows Per Second。

将上表中的 RPS 数据做成更直观的图表,如下:


rps_192g

192G 内存对 TerarkDB 和 InnoDB 都够用,实际上,TerarkDB 只使用了大约 52G,InnoDB 则耗尽了所有内存(进程内存 + 系统缓存)。

TerarkDB 的只读性能低于 InnoDB,主要是因为 MyRocks 适配层带来的性能损失(相比引擎层损失了 10 倍以上的性能)。

TerarkDB 的读写混合性能高于 InnoDB,是因为 TerarkDB 通过 RocksDB 使用了 LSM Tree,随机写性能从根上就远优于 InnoDB 的 BTree。


rps_32g

32G 内存,TerarkDB 不太够用,但 InnoDB 很不够用,TerarkDB 尽管有 MyRocks 适配层带来的性能损失,但 InnoDB 因为内存不够受限于 IO 瓶颈 ,从而 TerarkDB 的性能远高于 InnoDB。


rps_8g

8G 内存对 TerarkDB 和 InnoDB 都很不够用,TerarkDB 的 IO 也成为瓶颈,但 InnoDB 的内存缺口更大,从而 TerarkDB 的性能仍远高于 InnoDB。


测试类型说明

1. point_select

主键等值查询,测试程序每次随机生成一个 ID 值,然后查询主键与之相等的记录。测试的每个 transaction 里包含 100 个主键等值查询 query,故每个 transaction 会访问 100 行数据。

  • 示例 SQL:
select c from sbtest1 where id = ID;
  • sysbench 命令
sysbench --time=900 --report-interval=1 --db-driver=mysql --mysql-port=3306 \
         --mysql-user=root --mysql-db=sysbench --mysql-host=127.0.0.1 \
         --threads=32 --warmup-time=30 --distinct_ranges=0 \
         --sum_ranges=0 --index_updates=0 --range_size=100 \
         --delete_inserts=0 --tables=1 --mysql_storage_engine=rocksdb \
         --non_index_updates=0 --table-size=450000000 --simple_ranges=0 --secondary_ranges=0\
         --order_ranges=0 --range_selects=off --point_selects=100 \
         --rand-type=uniform --skip_trx=on /path/to/share/sysbench/oltp_read_only.lua run

2. point_select90_update10

读写混合测试,除上述主键等值查询外,还会随机生成一个 ID,然后更新主键与该 ID 相等的记录的 c 值。测试的每个 transaction 包含 90 个主键等值查询 query,和 10 个非主键更新 query,故每个 transaction 会访问 100 行数据,并更新 10 行数据。

  • 示例 SQL:
    select c from sbtest1 where id = ID;

    update sbtest1 set c = C where id = ID;
  • sysbench 命令
sysbench --time=900 --report-interval=1 --db-driver=mysql --mysql-port=3306 \
         --mysql-user=root --mysql-db=sysbench --mysql-host=127.0.0.1 \
         --threads=32 --warmup-time=30 --distinct_ranges=0 \
         --sum_ranges=0 --index_updates=0 --range_size=100 \
         --delete_inserts=0 --tables=1 --mysql_storage_engine=rocksdb \
         --non_index_updates=10 --table-size=450000000 --simple_ranges=0 --secondary_ranges=0\
         --order_ranges=0 --range_selects=off --point_selects=90 \
         --rand-type=uniform --skip_trx=on /path/to/share/sysbench/oltp_read_write.lua run

3. secondary_random_points100

次级索引等值查询,测试程序随机生产 100 个 key,然后使用 where in 语法随机读取这 100 个 key 对应的 100 行数据。

测试的每个 transaction 包含一个 Query,每个 Query 对次级索引进行 100 次随机搜索,每次都需要进行回表操作(先从次级键拿到主键,再用主键取数据),从而每个 transaction 需要对存储引擎进行 200 次随机访问。

  • 示例 SQL:
    select id, k, c, pad from sbtest1 where k in (k1, k2, k3, ..., k100);
  • sysbench 命令
sysbench --time=900 --report-interval=1 --db-driver=mysql --mysql-port=3306 \
         --mysql-user=root --mysql-db=sysbench --mysql-host=127.0.0.1 \
         --threads=32 --warmup-time=30 --tables=1 --table-size=450000000 \
         --rand-type=uniform --skip_trx=on \
         --random_points=100 /path/to/share/sysbench/select_random_points.lua run

4. secondary_random_limit100

次级索引范围查询,该查询为我们新添加的测试,用来测试主索引的随机读性能: 次级 Key 是随机生成的,次级 Key 按大小顺序映射到主键,得到的主键序列就是随机顺序,所以,这样的访问,就是次级 Key 的顺序访问再加主键的随机访问。

测试的每个 transaction 包含 100 个次级索引范围查询 query,每个 query 会访问 100 行数据,从而每个 transaction 会访问 10,000 行数据。

  • 示例 SQL:

    select c from sbtest1 where k >= K limit 100;
    
  • sysbench 命令

    sysbench --time=900 --report-interval=1 --db-driver=mysql --mysql-port=3306 \
           --mysql-user=root --mysql-db=sysbench --mysql-host=127.0.0.1 \
           --threads=32 --warmup-time=30 --distinct_ranges=0 \
           --sum_ranges=0 --index_updates=0 --range_size=100 \
           --delete_inserts=0 --tables=1 --mysql_storage_engine=rocksdb \
           --non_index_updates=0 --table-size=450000000 --simple_ranges=0 --secondary_ranges=100 \
           --order_ranges=0 --range_selects=on --point_selects=0 \
           --rand-type=uniform --skip_trx=on /path/to/share/sysbench/oltp_read_only.lua run
    

results matching ""

    No results matching ""

    results matching ""

      No results matching ""