MxBench
MxBench 是MatrixDB数据加载和查询的压测工具,可以根据用户给定的设备数量、时间范围、指标数量配置快速生成随机数据,自动创建数据表,串行或并发进行数据加载和查询。用户可以灵活配置指标类型、采集频率、空值率、随机度等,还可以指定查询的线程数、定制查询语句等。MxBench可以通过命令行运行,也可以通过配置文件运行。该工具位于MatrixDB安装目录下的bin/mxbench。
1 准备
1.1 MatrixDB集群
需要一个正常运行的MatrixDB集群。
1.2 环境变量
由于MxBench需要调用createdb, gpconfig, gpstop,因此需要用户配置好相关环境变量使这些命令可以正确执行。
具体的,需要执行source <MatrixDB安装目录>/greenplum_path.sh
, 还需要正确设置以下环境变量:
- PGHOST
- PGPORT
- PGUSER
- PGPASSWORD
- PGDATABASE
- MASTER_DATA_DIRECTORY
此外,用户还可以试执行 createdb mxbench
, gpconfig -s log_rotation_size
, gpstop -rai
等命令,确保可以正确运行。
2 用法
2.1 快速试用
如果想在个人开发机上快速试用MxBench,可以使用配置文件或者命令行的方式运行MxBench.
2.1.1 配置文件
可以使用以下配置文件,命名为mxbench.conf
,并运行:
mxbench --config mxbench.conf
.
注意benchmark-parallel
参数设置需要适应机器性能,建议小于或等于CPU核数。
[database]
db-database = "testdb1"
db-master-port = 5432
[global]
# 开启进度查看功能,默认即为true
watch = true
# 生成的DDL, GUCs设置建议, Query等文件的存放目录
workspace = "/tmp/mxbench"
table-name = "table1"
# 设备数
tag-num = 25000
# 指标数据类型,支持 int4, int8, float4, float8 四种类型
metrics-type = "float8"
# 指标数目,如果指标数大于998,就把前997个作为简单列,
# 其他的作为json存放在名为ext的列中
total-metrics-count = 300
# 生成数据的起始时间戳, ts-end必须晚于ts-start,否则报错
ts-start = "2022-04-19 09:00:00"
ts-end = "2022-04-19 09:03:00"
# 每几秒采集一次指标
ts-step-in-second = "2"
[generator]
generator = "telematics"
[generator.telematics]
# 每个设备每个时间点的指标,分几条数据上传,最终在DB被upsert成1个tuple
generator-batch-size = 1
# 延迟上传的数据生成比例(1~100),时间戳往前推1小时
generator-disorder-ratio = 0
# 生成数据的空值率(1~100)
generator-empty-value-ratio = 90
# 生成数据的随机度, 有OFF/S/M/L几档,默认关闭"OFF", 一般场景可选择M档
generator-randomness = "OFF"
[writer]
writer = "stdin"
[benchmark]
benchmark = "telematics"
[benchmark.telematics]
# 数组,查询并发度
benchmark-parallel = [8]
# 提供的3个查询:单车最新值,10车最新值,单车明细
benchmark-run-query-names = ["SINGLE_TAG_DETAIL_QUERY" ]
# 每轮每条query的跑的次数或时间,让时间生效需要将次数设置为0,如下:
benchmark-run-times = 0
benchmark-runtime-in-second = "30"
2.1.2 命令行
还可以使用命令行运行MxBench。运行以下命令就等同于以上面的配置文件运行MxBench。
mxbench run \
--db-database "testdb1" \
--db-master-host "localhost" \
--db-master-port 5432 \
--db-user "mxadmin" \
--workspace "/tmp/mxbench" \
--table-name "table1" \
--ts-start "2022-04-19 09:00:00" \
--ts-end "2022-04-19 09:02:00" \
--ts-step-in-second 2 \
--generator "telematics" \
--writer "stdin" \
--benchmark "telematics" \
--benchmark-run-query-names "SINGLE_TAG_DETAIL_QUERY" \
--benchmark-parallel 8 \
--benchmark-run-times 0 \
--benchmark-runtime-in-second 30
2.2 配置详解
从示例配置文件可以看到,配置文件分为以下几个板块:
全局配置
- database: 数据库相关的配置;
- global: 包括一些表结构、数据量信息,以及是否dump数据文件或实际执行测试、是否开启进度观察等管理方面的配置;
可插件化的配置
- generator: 数据生成器:
- telematics(默认) - 生成车联网场景的数据;
- file - 从文件中读取数据;
- nil - 不生成数据。
- writer: 负责把生成的数据通过MxGate写入MatrixDB:
- http(默认) - 以HTTP的方式启动MxGate,并通过其加载数据至MatrixDB;
- stdin - 以stdin的方式启动MxGate,并通过其加载数据至MatrixDB;
- nil - 不启动MxGate,不加载。
- benchmark: 可插件化,生成并执行query语句:
- telematics(默认) - 生成并执行车辆网场景下的常用query,支持定制query;
- nil - 不生成、不执行query语句。
以下是各模块参数详解:
2.2.1 database
[database]
# 数据库名称,如果不存在,MxBench会自动创建;已存在也不会报错
db-database = "postgres"
## MatrixDB master实例所在主机的hostname
db-master-host = "localhost"
## MatrixDB master 实例的端口号
db-master-port = 5432
# MatrixDB 用户密码
db-password = ""
# MatrixDB 用户名
db-user = "mxadmin"
2.2.2 global
[global]
# MxBench 生成DDL文件,现有系统GUCs恢复脚本, 最佳实践推荐GUCs更改脚本,
# csv数据文件,query文件的目录。
# 如果不存在,MxBench会自动创建;如果已存在且非目录,则会报错。可能需要注意权限问题。
# 每次运行MxBench,都会在其下创建名为Unix时间戳的目录,该次运行生成的文件都会在该目录下。
# 默认为"/tmp/mxbench"
workspace = "/tmp/mxbench"
# 是否dump csv数据文件,可选true或false。
# 默认为false,会执行DDL、数据加载、query。
# 在workspace下Unix时间戳的目录中,会生成:DDL、GUCs相关脚本和query文件。
# 1. mxbench_ddl.sql: DDL文件;
# 2. mxbench_gucs_setup.sh: 最佳实践推荐的GUCs设置脚本,可能需要再重启MatrixDB才能全部生效。
# 3. mxbench_gucs_backup.sh: 现有系统GUCs备份。如果现有系统的GUCs和最佳实践的GUCs一致,便不会生成。
# 4. mxbench_<benchmark-plugin>_query.sql: 相应benchmark插件生成的query语句。
# 如果选择true,则不会实际执行DDL、数据加载以及query;除了上面的各文件,还会生成:
# 5. mxbench_<generator-plugin>_data.csv: 相应generator插件生成的data的csv文件。
dump = false
# 是否开启进程观察,可选true或false。
#(默认)如果选择true,则会每5秒打印一次writer和benchmark模块的执行进度信息。
# 选择false关闭。
watch = true
# 是否同时执行数据加载和查询,可选true或false。
# 如果选择true: 执行数据加载和查询的混合负载
# query跑完之后会再循环跑,直到数据加载结束。
# (默认)如果选择false: 先执行数据加载,执行完毕后再执行查询。
simultaneous-loading-and-query = false
# 如果需要定制DDL,该参数填写DDL文件的路径。
# (默认)不填写则会根据其他相关配置生成DDL。
ddl-file-path = ""
# 指标的类型。默认为"float8",即双精度浮点数。
# 只支持 "int4", "int8", "float4", "float8", 4种类型.
metrics-type = "float8"
# schema名称,默认为"public".
schema-name = "public"
# 数据表名称。默认为"", 必须手动设置。
# 如果该同名表在配置的数据库、schema下存在,会报错,终止MxBench程序。
table-name = "test_table"
# 设备数量。默认25000.
tag-num = 25000
# 指标总数。默认300.
# 如果指标总数大于998,则超过部分的指标会以json类型存放在名为"ext"的列中。
# 例如,如果指标总数设为1000,则998个会以简单列形式存放在名为c0~c997的列中,
# 其他2个以json形式放在ext的json类型的列中。
total-metrics-count = 300
# 生成数据时间戳起始时间。因为有延迟上报的数据存在,生成数据可能会早于这个时间。
ts-start = "2022-04-25 09:00:00"
# 生成数据时间戳终止时间。ts-end必须晚于ts-start,否则报错
ts-end = "2022-04-25 09:01:00"
# 每几秒采集一次指标。默认为"1"。
ts-step-in-second = "1"
2.2.3 generator
2.2.3.1 telematics(默认)
生成车联网场景数据,选择generator="telematics"。
[generator]
generator = "telematics"
[generator.telematics]
# 每个设备在每个时间戳的指标,分几条上传至MatrixDB。
# 例如,如果设置为5,名为"tag1"的设备在"2022-04-25 09:00:03"这个时间戳下,
# 各个指标的数据会分5条传到MatrixDB,最终合并为1个tuple.
# 默认为1. 即指标信息不做拆分。
generator-batch-size = 1
# 延迟上报数据的比例。取值1~100.
# 默认值为0, 即没有延迟上报的数据。
generator-disorder-ratio = 0
# 每行数据的空值率。取值为1~100. 默认为90%,即90%的指标都将是空值。
generator-empty-value-ratio = 90
# 指标数据随机度, 分为OFF/S/M/L四档。默认为OFF。
generator-randomness = "OFF"
2.2.3.2 file
从csv文件中读取数据并加载,选择generator="file"。
[generator]
generator = "file"
[generator.file]
# 数据csv数据的绝对路径。可接收一个数组,即上传多个csv文件。
generator-file-paths = []
# 同[generator.telematics],设置这两个参数非必需,
# 但是妥当设置会帮助我们更好的生成DDL语句。如选定制DDL语句则将不起作用。
generator-batch-size = 1
generator-empty-value-ratio = 90
2.2.3.3 nil
不生成、加载任何数据,选择generator="nil"。
[generator]
generator = "nil"
2.2.4 writer
2.2.4.1 http(默认)
以http形式启动MxGate并加载数据。
[writer]
writer = "http"
[writer.http]
# 发送http消息是否使用gzip压缩,默认不采用
writer-use-gzip = false
# 向MxGate发送数据的并发度。
writer-parallel = 8
2.2.4.2 stdin
以stdin方式启动MxGate并加载数据。
[writer]
writer = "stdin"
2.2.4.3 nil
不启动MxGate,不写入数据。
[writer]
writer = "nil"
2.2.5 benchmark
2.2.5.1 telematics(默认)
[benchmark]
benchmark = "telematics"
[benchmark.telematics]
# 将要顺序执行的telematics提供的query名称,
# 现提供:
# 1. "SINGLE_TAG_LATEST_QUERY"
# 2. "MULTI_TAG_LATEST_QUERY"
# 3. "SINGLE_TAG_DETAIL_QUERY"
# 共3个合法query名,分别为:
# "SINGLE_TAG_LATEST_QUERY": 获得单车最近时间戳的各个指标值;
# "MULTI_TAG_LATEST_QUERY": 随机选取10车,获得其最近时间戳的各个指标值;
# "SINGLE_TAG_DETAIL_QUERY": 获得单车在一段时间内的各个指标的值。
# 注:对于超宽表,指标数很多,可能DBMS不支持一次获取所有指标值,
# 因此下面由参数可以调试获取的指标数以及"SINGLE_TAG_DETAIL_QUERY"的时间段取值。
# 例如,输入[ "SINGLE_TAG_LATEST_QUERY", "MULTI_TAG_LATEST_QUERY", "SINGLE_TAG_DETAIL_QUERY" ] 就可以顺序执行上述三个query。
# 在此基础上删减query名称便可不执行对应query。输入其他名称会被忽略。
# 默认为空,即不执行任何预设query。
benchmark-run-query-names = [ "SINGLE_TAG_DETAIL_QUERY" ]
# 定制query,使用"," 分隔。
# 例如, ["SELECT COUNT(*) from t1", "SELECT MAX(ts) from t1"]
# 默认为空,即不执行任何定制query.
benchmark-custom-queries = []
# 跑query的并发度,可以输入多个,顺序对应并发度执行各个query,使用","分隔。
# 例如,输入 [1, 8] 就可以先以并发度1跑各个query,再以并发度为8跑各个query。
# 默认为空。
benchmark-parallel = [8]
# 每个query在每个并发度下跑的次数,根据这么多次跑的结果做延迟和TPS统计,默认为0。
benchmark-run-times = 0
# 每个query在每个并发度下跑的时间(秒), 根据这段时间内query执行的结果做延迟和TPS统计。
# 只在benchmark-run-times为0的情况下才生效。默认为60,即每个query在每个并发度下跑60秒。
benchmark-runtime-in-second = "60"
2.2.5.2 nil
如果不需要执行任何query,则将benchmark设为nil。
[benchmark]
benchmark = "nil"
2.3 示例配置文件
2.3.1 超宽稀疏表生成数据并运行混合负载
[database]
db-database = "testdb2"
db-master-port = 5432
[global]
# 开启进度查看功能,默认即为true
watch = true
# 生成的DDL, GUCs最佳实践建议, Query等文件的存放目录
workspace = "/home/mxadmin/mxbench/workspace"
# 数据加载和查询是否同时进行
simultaneous-loading-and-query = true
table-name = "table2"
# 设备数
tag-num = 20000
# 指标数据类型,支持 int4, int8, float4, float8 四种类型
metrics-type = "float8"
# 指标数目,如果指标数大于998,就把前997个作为简单列,
# 其他的作为json存放在名为ext的列中
total-metrics-count = 5000
# 生成数据的起始时间戳,ts-end必须晚于ts-start,否则报错
ts-start = "2022-04-19 00:00:00"
ts-end = "2022-04-19 00:01:00"
[generator]
generator = "telematics"
[generator.telematics]
# 每个设备每个时间点的指标,分几条数据上传,最终在DB被upsert成1个tuple
generator-batch-size = 1
# 延迟上传的数据生成比例(1~100),时间戳往前推1小时
generator-disorder-ratio = 0
# 生成数据的空值率(1~100)
generator-empty-value-ratio = 90
# 生成数据的随机度, 有OFF/S/M/L几档,默认关闭"OFF"
generator-randomness = "OFF"
[writer]
writer = "stdin"
[benchmark]
benchmark = "telematics"
[benchmark.telematics]
# 数组,查询并发度
benchmark-parallel = [64]
# 提供的3个查询:单车最新值,10车最新值,单车明细
benchmark-run-query-names = [ "SINGLE_TAG_LATEST_QUERY", "MULTI_TAG_LATEST_QUERY", "SINGLE_TAG_DETAIL_QUERY" ]
# 每轮每条query的跑的次数或时间,让时间生效需要将次数设置为0,如下:
benchmark-run-times = 0
benchmark-runtime-in-second = "60"
2.3.2 从外部读取DDL并外部读取csv文件加载,不跑查询
[database]
db-database = "testdb3"
db-master-port = 5432
[generator]
# 从csv文件中读取数据
generator = "file"
[generator.file]
generator-file-paths = ["/home/mxadmin/mxbench/data.csv"]
[global]
table-name = "table3"
watch = true
workspace = "/home/mxadmin/mxbench/workspace"
ddl-file-path = "/home/mxadmin/mxbench/ddl.sql"
[writer]
writer = "stdin"
[benchmark]
benchmark = "nil"
2.4 示例命令行
2.4.1 超宽稀疏表生成数据并运行混合负载
使用示例配置文件1运行MxBench相当于使用以下命令行运行MxBench:
mxbench run \
--db-database "testdb2" \
--db-master-port 5432 \
--db-user "mxadmin" \
--workspace "/home/mxadmin/mxbench/workspace" \
--simultaneous-loading-and-query \
--table-name "table2" \
--tag-num 25000 \
--metrics-type "float8" \
--total-metrics-count 5000 \
--ts-start "2022-04-19 00:00:00" \
--ts-end "2022-04-19 00:01:00" \
--generator "telematics" \
--generator-batch-size 1 \
--generator-disorder-ratio 0 \
--generator-empty-value-ratio 90 \
--generator-randomness "OFF" \
--writer "stdin" \
--benchmark "telematics" \
--benchmark-run-query-names "SINGLE_TAG_LATEST_QUERY" \
--benchmark-run-query-names "MULTI_TAG_LATEST_QUERY" \
--benchmark-run-query-names "SINGLE_TAG_DETAIL_QUERY" \
--benchmark-parallel 64 \
--benchmark-run-times 0 \
--benchmark-runtime-in-second 60
2.4.2 从外部读取DDL并外部读取csv文件加载,不跑查询
使用示例配置文件2运行MxBench相当于使用以下命令行运行MxBench:
mxbench run \
--db-database "testdb3" \
--db-master-port 5432 \
--workspace "/home/mxadmin/mxbench/workspace" \
--ddl-file-path "/home/mxadmin/mxbench/ddl.sql" \
--table-name "table3" \
--generator "file" \
--generator-file-paths "/home/mxadmin/mxbench/data.csv" \
--writer "stdin" \
--benchmark "nil"
2.5 FAQ
-
只加载,不查询 将benchmark设为nil;
-
只查询,不加载 将generator设为nil;
-
加载和查询同时跑 global设置中simultaneous-loading-and-query为true。
-
想要生成并dump出csv数据文件 global设置中dump为true, 生成的文件在workspace设置的目录下的
目录中。 -
想要查看生成的ddl和query workspace设置的目录下的
目录中。 -
想要跑定制DDL 在global设置中的ddl-file-path中填写ddl文件的绝对路径。
-
想要跑定制query 在 telematics benchmark的 benchmark-custom-queries中填写定制query语句, 用""括起来。不支持随机参数。
-
不想采用系统建议的GUCs, 保留现有GUCs运行mxbench: MxBench检测到现有系统和建议GUCs有不一致时,会在标准输出中做提示,并且询问是否需要重设GUCs并启动数据库。输入"N",保留原有GUCs. MxBench这时还会再次确认是否继续运行MxBench。选择"Y", 继续运行。
-
对参数合法性有什么要求? global 配置里:
- ts-end必须晚于ts-start;
- table-name、schema-name 不为空;
- tag-num必须大于0;
- ts-step-in-second不为0。
3 理解进度信息和统计报告
3.1 进度信息
示例:
● Stdin Writer Report
● period start: 2022-04-29 10:08:11, end: 2022-04-29 10:08:16, period: 5.000129734s
● count written in total: 637025 rows/ 1500000 rows 42%, 637025 rows in this period
● size written in total: 160878718 bytes/ 360000003 bytes 44%, 160878718 bytes in this period
● size written to MxGate in total: 350075440 bytes, 350075440 bytes in this period
● Telematics Benchmark Report
● stats for query SINGLE_TAG_LATEST_QUERY with parallel 8: progress: 100%
● stats for query MULTI_TAG_LATEST_QUERY with parallel 8: progress: 43%
说明:总共由两部分组成,即writer和benchamrk的进度报告。
3.1.1 writer
- period start, period end, period: 该统计窗口的起止时间和时间段;
- count written: 已经写入的数据行数和预计数据行数,以及二者的百分比。xx in this period:该统计窗口内写入的行数;
- size written: 已经写入的数据字节数和预计数据字节数,以及二者的百分比。xx in this period: 该统计窗口内写入的字节数;
- size written to MxGate: 把数据转化成文本后写入MxGate的字节数。xx in this period: 该统计窗口内写入MxGate的字节数。
3.1.2 benchmark
某条query在某并发度parallel参数下的执行进度。query与数据加载同时进行时,query会在数据加载结束之前一直进行,因此可能会循环运行多轮。该进度报告只显示最近一轮的进度报告
3.2 统计报告
3.2.1 writer
┌───────────────────────────────────────────────────────┐
│ Summary Report for Stdin Writer │
├─────────────────────────────────┬─────────────────────┤
│ start time: │ 2022-04-27 13:29:01 │
├─────────────────────────────────┼─────────────────────┤
│ stop time: │ 2022-04-27 13:29:58 │
├─────────────────────────────────┼─────────────────────┤
│ size written to MxGate (bytes): │ 848333400 │
├─────────────────────────────────┼─────────────────────┤
│ lines inserted: │ 1500000 │
├─────────────────────────────────┼─────────────────────┤
│ compress ratio: │ 1.561276 : 1 │
└─────────────────────────────────┴─────────────────────┘
- start time: 数据加载起始时间;
- end time: 数据加载终止时间;
- size written to MxGate (bytes): 向MxGate写入数据的字节数;
- lines inserted: 插入数据的条数. 由于upsert可能存在,这一数字可能会高于数据库中实际的数据条数。
- compress ratio: 压缩比,即向MxGate写入数据的大小和实际数据库中该表的大小的比值。
3.2.2 benchmark
每条query,在每个parallel参数下都会产生一个报告,会实时打印出来。
┌─────────────────┬───────────────┐
│ Overall Latency │ 29.948370582s │
│ Average Latency │ 13.723304ms │
│ P75 Latency │ 14.35972ms │
│ P50 Latency │ 13.654556ms │
│ P25 Latency │ 12.925912ms │
│ TPS │ 582 │
└─────────────────┴───────────────┘
- Pxx 代表xx百分位数的延迟。例如P75是14.35972ms,说明执行query的次数中,有25%延迟高于它,75%低于它. P50即中位数。
- TPS: 每秒执行query的次数.
汇总报告:
┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Summary Report for Telematics Benchmark │
├─────────────────────┬─────────────────────────────────────┬─────────────────────────────────────┬─────────────────────────────────────┤
│ Parallel\Query Name │ SINGLE_TAG_LATEST_QUERY │ MULTI_TAG_LATEST_QUERY │ SINGLE_TAG_DETAIL_QUERY │
├─────────────────────┼─────────────────────────────────────┼─────────────────────────────────────┼─────────────────────────────────────┤
│ 8 │ ┌─────────────────┬───────────────┐ │ ┌─────────────────┬───────────────┐ │ ┌─────────────────┬───────────────┐ │
│ │ │ Overall Latency │ 30.008625133s │ │ │ Overall Latency │ 36.407016561s │ │ │ Overall Latency │ 29.948370582s │ │
│ │ │ Average Latency │ 23.81758ms │ │ │ Average Latency │ 7.270212105s │ │ │ Average Latency │ 13.723304ms │ │
│ │ │ P75 Latency │ 24.911171ms │ │ │ P75 Latency │ 8.139682559s │ │ │ P75 Latency │ 14.35972ms │ │
│ │ │ P50 Latency │ 23.411248ms │ │ │ P50 Latency │ 7.161237157s │ │ │ P50 Latency │ 13.654556ms │ │
│ │ │ P25 Latency │ 20.899622ms │ │ │ P25 Latency │ 6.642459805s │ │ │ P25 Latency │ 12.925912ms │ │
│ │ │ TPS │ 335 │ │ │ TPS │ 1 │ │ │ TPS │ 582 │ │
│ │ └─────────────────┴───────────────┘ │ └─────────────────┴───────────────┘ │ └─────────────────┴───────────────┘ │
│ │ progress: 100% │ progress: 100% │ progress: 100% │
└─────────────────────┴─────────────────────────────────────┴─────────────────────────────────────┴─────────────────────────────────────┘
- 每行代表某并发度下各query的执行结果。
- 每列代表每个query在各个并发度下的执行结果。
- 如果query集执行了多轮(混合负载的情况下,数据加载未结束,query便会一直执行),则仅展示最后一轮的结果。
- 如果因为query执行错误或者用户中断执行,进度条会显示当前进度,统计信息是根据已经执行query的做出统计。