开源!MatrixBench:实时物联网场景的数据压测“兵法秘籍”

2023-02-02 · YMatrix Team
#产品动态

目录

  1. MatrixBench 开源了!再认识它一下

  2. 为什么选择 MatrixBench?

  3. 开源:MatrixBench 的边界无限扩展

  4. 诚恳邀请你的加入

1. MatrixBench 开源了!再认识它一下

市场上,各种数据库 Benchmark 标准百花齐放,各大数据库厂商也醉心于展示自家产品一骑绝尘的高性能,彰显在某一应用场景冠绝群雄的姿态。

去年六月,我们随 YMatrix 4.5 发布了一款全新升级的时序场景数据加载及查询压测工具 —— MatrixBench,它支持灵活地配置设备数量、时间范围、指标数量、指标类型、采集频率、空值率、随机度等参数,还可以指定查询的并发度、定制查询语句等。

现在,它开源了!👇

MatrixBench(点击左边蓝字,访问开源代码库!)

2. 为什么选择 MatrixBench?

MatrixBench 是为 YMatrix 量身定制的 —— 当然,既然开源了,在社区用户集体智慧的加持下,未来扩展支持其他数据库也不在话下,详见第三段“开源:MatrixBench 的边界无限扩展”。

MatrixBench 不仅支持独有的新特性,而且使用的时序场景 workloads 和测试 query 也是 YMatrix 在长期实践中总结出的精华。

例如,MatrixBench 支持生成 MARS2 表和配套 index。它也能把很多指标合并成一个 JSON 类型的列,生成表和数据,让指标数不受数据库列数限制。这是 YMatrix 团队在实践中面临大宽表场景的成功经验。

测试一个数据库系统还有另一个难题:有时,一个细微的配置差别可能引发蝴蝶效应,让测试结果有了巨大差异 —— 所谓差之毫厘,谬以千里。

我们该如何调试数据库系统,让各项配置和参数都达到适合目标场景的最佳状态,进而交出一份令人满意的测试答卷?这对测试者的要求颇高, 需要深度掌握数据库系统、深刻理解不同应用场景以及丰富的经验。

这就好比一名足球教练,要在球场的博弈中胜出,不仅要了解手中的 26 枚棋子(刚刚结束的世界杯中,每队球员大名单共有 26 人),更要根据场上形势和对手情况灵活调整战术打法,执教经验也是必备选项。球员的身体条件、能力值、技术特点、性格各异,教练必须对他们的各项“参数”了如指掌才能发挥出他们的特长 —— 数据库测者也要对本数据库系统的各项参数如数家珍。除此之外,球场上针对不同对手采取的定制化战术,类比到数据库领域也同样重要。

MatrixBench 在面对不同应用场景(如:实时物联网/车联网/工业互联网场景)也要采取针对性的配置和策略。名帅通常已率队征战多载且战功显赫。而在数据库领域里,身经百战磨练出的丰富调试经验也不可或缺。

值得庆幸的是,在 YMatrix 的世界里,想领略它在时序场景下的极限表现,不必花费千万欧元的年薪雇佣一名金牌教练员—— a free MatrixBench is enough!你只要为它提供数据库的连接方式,告知它数据库集群规模、宿主机的配置规格,以及应用场景数据特征 —— 例如时间范围、指标数量与类型、空值率等,它就可以为你选择一个最佳的“兵法”。

这套“兵法”囊括的多维度内容,包括且不限于:

  • 数据库的各项 GUC 值;
  • 表结构;
  • 表的分区键;
  • 表的分布键;
  • 表分区范围的设置;
  • 索引;
  • 索引中的参数;
  • MatrixGate(YMatrix 配套高性能数据加载工具)的启动参数。

为确保最佳的使用体验,让我们一起深入 MatrixBench 的经典应用场景,感受其真实的魅力所在。

假如:你是一个新能源汽车厂商数据部的工程师,需要模拟一个车联网场景的数据加载和 query 查询。

共有 25000 辆车,每辆车每 2 秒会上传一条数据,记录发动机转速、温度等等共计 300 个指标的瞬时数据,类型都是 float8 。但是这些指标大约有一半是空值,至于具体是哪些指标则是随机行为。更复杂的是,这些数据有 5% 的可能性,会因为网络延迟、临时断电等各种原因,24 小时之后才会延迟上传。

数据加载的同时,还需要执行“单车明细”的 query,以及查询目标表记录总数的定制 query,每个 query 都要有 64 个客户端在进行并发查询。每轮跑 30s,数据加载完成之前轮次不间断,连续压测。数据时间戳范围需要跨越 24 小时,测试结束后,希望得到一份加载性能汇总报告和最后一轮 query 的统计数据 。

千万不要被这些复杂的情况吓到,因为你仅仅只需提供这么一份配置文件,即可自动形成“兵法”:

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 = "2023-01-10 09:00:00"
  ts-end = "2022-01-11 09:00:00"

  # 每几秒采集一次指标
  ts-step-in-second = "2"

  # 数据加载和查询是否同时进行
  simultaneous-loading-and-query = true

[generator]
  generator = "telematics"

  [generator.telematics]
    # 每个设备每个时间点的指标,分几条数据上传,最终在DB被upsert成1个tuple
    generator-batch-size = 1
    # 延迟上传的数据生成比例(0~100),时间戳往前推24小时
    generator-disorder-ratio = 5
    # 生成数据的空值率(0~100)
    generator-empty-value-ratio = 50
    # 生成数据的随机度, 有OFF/S/M/L几档,默认关闭"OFF", 一般场景可选择M档
    generator-randomness = "M"

[writer]
  # 使用mxgate的stdin方式加载数据
  writer = "stdin"

[benchmark]
  benchmark = "telematics"

  [benchmark.telematics]
    # 数组,查询并发度
    benchmark-parallel = [64]
    # 跑一个查询:单车明细查询
    benchmark-run-query-names = ["SINGLE_TAG_DETAIL_QUERY" ]
    # 用户定制query
    benchmark-custom-queries = ["select count(*) from talbe1"]
    # 每轮每条query的跑的次数或时间,让时间生效需要将次数设置为0,如下:
    benchmark-run-times = 0
    benchmark-runtime-in-second = "30"

兵法在手,MatrixBench 便开始组织实战,真刀真枪地检验这套阵容的实效。它会实际地进行数据加载、query 查询,(“只加载,不查询”,“只查询,不加载”,“加载和查询同时跑”均能配置哦!),把各项关键的测试数据展现在你的面前。

  • 数据加载:可以实时观测加载速率、压缩比等关键指标。

    • 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 的字节数。

● Stdin Writer Report
  ● period start: 2023-01-10 10:08:11, end: 2023-01-10 10:08:16, period: 5.00s

  ● count written in total: 637025 rows/ 1500000 rows 42.12%, 637025 rows in this period

  ● size written in total: 160878718 bytes/ 360000003 bytes 44.23%, 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%
  • 数据查询:可以展现每个 query 在每个测试周期的平均执行时间 (P50)、P90、 P75、 P25 以及 TPS 等各项指标。

    • Pxx 代表 xx 百分位数的延迟。例如 P75 是 14.35ms,说明执行 query 的次数中,有 25% 延迟高于它,75% 低于它 . P50 即中位数。
    • TPS:每秒执行 query 的次数.
┌─────────────────┬───────────────┐
│ Overall Duration│       29.942s │
│ Average Latency │       13.72ms │
│ P75 Latency     │       14.35ms │
│ P50 Latency     │       13.65ms │
│ P25 Latency     │       12.92ms │
│ TPS             │           582 │
└─────────────────┴───────────────┘

测试结束后,你将收到一份汇总报告。战果如何,一目了然。

  • Writer 部分

    • start time:数据加载起始时间;
  • -end time:数据加载终止时间;

    • size written to mxgate (bytes):向 mxgate 写入数据的字节数;
    • lines inserted:插入数据的条数,由于 upsert 可能存在,这一数字可能会高于数据库中实际的数据条数。
    • compress ratio:压缩比,即向 mxgate 写入数据的大小和实际数据库中该表的大小的比值。
  • Benchmark 部分

    • 每行代表某并发度下各 query 的执行结果。
    • 每列代表每个 query 在各个并发度下的执行结果。
    • 如果 query 集执行了多轮(混合负载的情况下,数据加载未结束,query 便会一直执行),则仅展示最后一轮的结果。
    • 如果因为 query 执行错误或者用户中断执行,进度条会显示当前进度,统计信息是根据已经执行 query 的做出统计。

┌───────────────────────────────────────────────────────┐
│            Summary Report for Stdin Writer            │
├─────────────────────────────────┬─────────────────────┤
│ start time:                     │ 2023-01-10 13:29:01 │
├─────────────────────────────────┼─────────────────────┤
│ stop time:                      │ 2023-01-10 13:29:58 │
├─────────────────────────────────┼─────────────────────┤
│ size written to mxgate (bytes): │ 848333400           │
├─────────────────────────────────┼─────────────────────┤
│ lines inserted:                 │ 1500000             │
├─────────────────────────────────┼─────────────────────┤
│ compress ratio:                 │ 1.56 : 1            │
└─────────────────────────────────┴─────────────────────┘
┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│                                                Summary Report for Telematics Benchmark                                                │
├─────────────────────┬─────────────────────────────────────┬─────────────────────────────────────┬─────────────────────────────────────┤
│ Parallel\Query Name │ SINGLE_TAG_LATEST_QUERY             │ MULTI_TAG_LATEST_QUERY              │ SINGLE_TAG_DETAIL_QUERY             │
├─────────────────────┼─────────────────────────────────────┼─────────────────────────────────────┼─────────────────────────────────────┤
│ 8                   │ ┌─────────────────┬───────────────┐ │ ┌─────────────────┬───────────────┐ │ ┌─────────────────┬───────────────┐ │
│                     │ │ Overall Duration│        30.00s │ │ │ Overall Duration│       36.401s │ │ │ Overall Duration│        29.94s │ │
│                     │ │ Average Latency │       23.81ms │ │ │ Average Latency │         7.27s │ │ │ Average Latency │       13.72ms │ │
│                     │ │ P75 Latency     │       24.91ms │ │ │ P75 Latency     │         8.13s │ │ │ P75 Latency     │       14.31ms │ │
│                     │ │ P50 Latency     │       23.41ms │ │ │ P50 Latency     │         7.16s │ │ │ P50 Latency     │       13.65ms │ │
│                     │ │ P25 Latency     │       20.89ms │ │ │ P25 Latency     │         6.64s │ │ │ P25 Latency     │       12.92ms │ │
│                     │ │ TPS             │           335 │ │ │ TPS             │             1 │ │ │ TPS             │           582 │ │
│                     │ └─────────────────┴───────────────┘ │ └─────────────────┴───────────────┘ │ └─────────────────┴───────────────┘ │
│                     │ progress: 100%                      │ progress: 100%                      │ progress: 100%                      │
└─────────────────────┴─────────────────────────────────────┴─────────────────────────────────────┴─────────────────────────────────────

3.开源:MatrixBench 的边界无限扩展

开源对于 MatrixBench 来说,是对于自身边界的无限扩展。开源之后,MatrixBench 是如何根据配置文件炮制出一套“兵法秘籍”,便一览无遗了。

这就好像你拥有查看森保一(日本足球队主帅)笔记本和战术板的权限,看看“名将”是如何运筹帷幄,从而率领蓝色武士连续扳倒两个前世界冠军。你也会突然明白,德尚在决赛上半场 40 分钟,面临两球落后的局势,一口气换下两名主力前锋的奥秘 —— 不同的场景当然要采取不同的配置和策略。不仅如此,你还对每个执法主裁的吹罚尺度了如指掌。作为足球场上的大法官,他们像是 Benchmark 具体需要跑的 query —— 你的成绩它说了算。

开源的灵魂是自由,你可以随时随地修改 MatrixBench 的源代码为自己数据库和应用场景做“私人定制”。如同一名 FIFA 2023 玩家,总是饶有兴致打造一支独一无二的、自己心目中的完美球队。你精心定制开发了一款数据加载工具,也能轻松让它加入 MatrixBench 的“队伍”,一起打赢这场数据库压测的“比赛”。足球游戏中,裁判的各项参数也能调一调 —— 这个争议点球判不判,那个疑似越位吹不吹?往往细微的差别就能让比赛有截然不同的走向 —— 测试 query 也是这样,一点点写法的变动也会造成走不同的 query plan,最终的执行效率也会千差万别。

在数据库测试领域,个性化需求层出不穷:

  • 想扩展数据特点的描述参数达到更深一层的定制化?

  • 想让另外的程序掌控数据生成的逻辑?

  • 想让 MatrixGate 以外的工具承担数据加载的重任?

  • 新场景需要跑更丰富的 query 类型?

  • 想支持别的数据库?

MatrixBench 有三个主要组件:Generator, Writer 和 Benchmark,分别负责数据生成、数据写入和 query 查询,均已被插件化。根据自己的需要,编写定制化插件,就可以通过 MatrixBench 的组件接口协议与主流程无缝衔接,即插即拔,安全可靠。

例如,目前已有三种 Generator:

  • Telematics

  • File

  • Nil

Telematics 会实时生成流式数据,发送给下游组件 Writer;File 从用户提供的 csv 文件读取数据, 设成 Nil 相当于不略过数据加载这一步。假如现在你已经有了自己的数据生成器,你就可以编写一个名为 Exteral 的 Generator,把外部生成器数据接过来。仅需实现下面的接口:


// internal/engine/generator.go
type IGenerator interface {
        NilCheck
        ConfigurablePlugin
        GetPrediction(*metadata.Table) (GeneratorPrediction, error)
        ModifyMetadataConfig(*metadata.Config)
        Run(GlobalConfig, *metadata.Metadata, WriteFunc) error
        Close() error
}

4.诚挚邀请你的加入

在现在的时间维度下,MatrixBench 是一名全能战士;但面向未来,它只是一位蹒跚学步的幼儿。因此,我们诚恳邀请你加入 mxbench 开源社区,帮我们一起丰满 MatrixBench 的羽翼。从修改一处拼写错误,到“生擒 bug”一只,甚至是重构代码,你的贡献将使它更加高内聚、低耦合、易扩展。

我们欢迎一切 PR 和 issue!YMatrix 开发团队给了 MatrixBench 生命, 但只有靠社区的力量,它才能茁壮成长,持续进步,为数据库的优化和迭代精诚服务!