时序数据库 性能测试工具 TSBS

news/2024/7/9 21:31:05 标签: 时序数据库, 数据库, postgresql, timescaledb

在这里插入图片描述

TSBS 是一个时序数据处理(数据库)系统的性能基准测试平台,提供了 IoT、DevOps 两个典型应用场景,它由 Timescale 开源并负责维护。作为一个性能基准测试平台,TSBS 具有便捷、易用、扩展灵活等特点,涵盖了时序数据的生成、写入(加载)、多种类别的典型查询等功能,并能够自动汇总最终结果。由于其开放开源的特点,得到了众多数据库厂商的支持,作为专业的产品性能基准测试平台被若干数据库厂商广泛使用。

01 TSBS 性能测试原理

首先,我们来了解一下 TSBS 进行性能测试测试的本质原理。

PostgreSQL 在执行查询时会为每个查询生成一个对应的查询计划,对于数据库而言选择正确的计划来匹配查询结构和数据属性对于性能来说十分关键,因此 PostgreSQL 中使用了一个复杂的规划器 Planner 来尝试选择最好查询计划。

在 PostgreSQL 中可以使用 EXPLAIN 命令查看规划器为每个查询生成的查询规划的具体内容。

在 TimescaleDB 的查询性能测试中,单次查询耗时可以直接使用 EXPLAIN ANALYZE 命令显示 TIMING 选项包含的每个计划节点的实际启动时间 Planning time 和总执行时间 Execution time

TSBS 的性能测试很大程度上也是基于这一功能实现的,下面我们来了解一下 EXPLAIN 命令。

1.1 EXPLAIN 命令的使用

在 PostgreSQL 中,EXPLAIN 命令可以输出 SQL 语句的查询计划,具体语法如下:

EXPLAIN [ ( option [, ...] ) ] statement
EXPLAIN [ ANALYZE ] [ VERBOSE ] statement

where option can be one of:

    ANALYZE [ boolean ]
    VERBOSE [ boolean ]
    COSTS [ boolean ]
    BUFFERS [ boolean ]
    TIMING [ boolean ]
    SUMMARY [ boolean ]
    FORMAT { TEXT | XML | JSON | YAML }

ANALYZEEXPLAIN 命令中最为重要的选项,该选项为 TRUE 时 EXPLAIN 命令会实际执行该查询,然后显示真实的行计数和在每个计划结点中累计的真实运行时间

下面是和 ANALYZE 关联使用的几个选项,仅 ANALYZE 启用时下列参数才生效

  • TIMING 选项显示每个计划节点的实际启动时间和总的执行时间,默认为 TRUE
  • SUMMARY 选项在查询计划后面输出总结信息,默认为 TRUE
  • BUFFERS 选项显示关于缓存的使用信息,默认为 FALSE

还有十分常用的选项 VERBOSEFORMAT

  • VERBOSE 选项为 TRUE 会显示查询计划的附加信息,包括计划树中每个节点的输出列列表、模式限定表和函数名,默认为 FALSE
  • FORMAT 指定输出格式,默认为 TEXT,还有 XML | JSON | YAML 等格式输出更有利于通过程序解析SQL 语句的查询计划

1.2 EXPLAIN 命令的输出

从最简单的全表查询例子开始,可以看到查询计划中使用 Seq Scan 扫描全表

EXPLAIN SELECT * FROM tenk1;

                         QUERY PLAN
-------------------------------------------------------------
 Seq Scan on tenk1  (cost=0.00..458.00 rows=10000 width=244)

尝试连接两个表,并且增加 WHERE 条件,这就生成了更加复杂的查询计划树

EXPLAIN SELECT *
FROM tenk1 t1, tenk2 t2
WHERE t1.unique1 < 10 AND t1.unique2 = t2.unique2;

                                      QUERY PLAN
--------------------------------------------------------------------------------------
 Nested Loop  (cost=4.65..118.62 rows=10 width=488)
   ->  Bitmap Heap Scan on tenk1 t1  (cost=4.36..39.47 rows=10 width=244)
         Recheck Cond: (unique1 < 10)
         ->  Bitmap Index Scan on tenk1_unique1  (cost=0.00..4.36 rows=10 width=0)
               Index Cond: (unique1 < 10)
   ->  Index Scan using tenk2_unique2 on tenk2 t2  (cost=0.29..7.91 rows=1 width=244)
         Index Cond: (unique2 = t1.unique2)

使用 EXPLAIN ANALYZE 显示计划结点执行时间和行计数之外的额外执行统计信息

EXPLAIN ANALYZE SELECT *
FROM tenk1 t1, tenk2 t2
WHERE t1.unique1 < 100 AND t1.unique2 = t2.unique2 ORDER BY t1.fivethous;

                                                                 QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------------
 Sort  (cost=717.34..717.59 rows=101 width=488) (actual time=7.761..7.774 rows=100 loops=1)
   Sort Key: t1.fivethous
   Sort Method: quicksort  Memory: 77kB
   ->  Hash Join  (cost=230.47..713.98 rows=101 width=488) (actual time=0.711..7.427 rows=100 loops=1)
         Hash Cond: (t2.unique2 = t1.unique2)
         ->  Seq Scan on tenk2 t2  (cost=0.00..445.00 rows=10000 width=244) (actual time=0.007..2.583 rows=10000 loops=1)
         ->  Hash  (cost=229.20..229.20 rows=101 width=244) (actual time=0.659..0.659 rows=100 loops=1)
               Buckets: 1024  Batches: 1  Memory Usage: 28kB
               ->  Bitmap Heap Scan on tenk1 t1  (cost=5.07..229.20 rows=101 width=244) (actual time=0.080..0.526 rows=100 loops=1)
                     Recheck Cond: (unique1 < 100)
                     ->  Bitmap Index Scan on tenk1_unique1  (cost=0.00..5.04 rows=101 width=0) (actual time=0.049..0.049 rows=100 loops=1)
                           Index Cond: (unique1 < 100)
 Planning time: 0.194 ms
 Execution time: 8.008 ms

EXPLAIN 命令的输出可以看做是一个树形结构,我们称之为查询计划树,树的每个节点包括对应的节点类型,作用对象以及其他属性例如 cost, rows, width 等。如果只显示节点类型,上面的例子可以简化为如下结构:

Sort
└── Hash Join
    ├── Seq Scan
    └── Hash
        └── Bitmap Heap Scan
            └── Bitmap Index Scan

02 TSBS 安装


TSBS 工具是使用 Golang 语言开发的,并且可以通过 go get 命令快捷获取

2.1 安装 Golang

首先,需要安装 Golang ,可以到官网获取最新版本的 go 安装包:https://golang.google.cn/doc/install

wget https://golang.google.cn/dl/go1.20.7.linux-arm64.tar.gz
rm -rf /usr/local/go 
tar -C /usr/local -zxvf go1.20.7.linux-amd64.tar.gz

解压完成后,配置环境变量 vim ~/.bashrc 添加如下内容

export GOROOT=/usr/local/go 	# 设置为go安装的路径,有些安装包会自动设置默认的goroot
export GOPATH=$HOME/go-work  	# 默认的 Golang 项目的工作空间,如果有多个使用分号分隔
export PATH=$PATH:$GOROOT/bin # 可执行文件路径

配置完成之后,查看安装配置是否成功

go env			# 查看得到go的配置信息
go version	# 查看得到go的版本号

go mod 包管理工具使用(reference:https://zhuanlan.zhihu.com/p/482014524),使用 go mod 需要修改 go 的配置信息如下

go env -w GOBIN=/usr/local/go/bin					# go 的可执行文件目录
go env -w GO111MODULE=auto							# 如果为 off 不启用 module 功能到 GOPATH 路径下查找依赖包;on 表示启动 module 功能
go env -w GOPROXY=https://goproxy.cn,direct	# 设置国内代理

go mod 基础使用

# 初始化一个项目
mkdir Proj && cd Proj
go mod init Proj				# 初始化一个 module

# 删除错误或者不使用的 modules
go mod tidy

# 编辑 go.mod 文件
go mod edit

2.2 安装 TSBS

直接使用 go get 获取 tsbs 安装

go get github.com/timescale/tsbs
cd $GOPATH/src/github.com/timescale/tsbs
go mod tidy
make

使用任意 tsbs 工具验证安装成功,如下使用数据生成工具 tsbs_generate_data 执行成功如下:

$ tsbs_generate_data --help
Usage of tsbs_generate_data:
      --debug int                              Control level of debug output
      --file string                            Write the output to this path
      --format string                          Format to generate. (choices: cassandra, clickhouse, influx, mongo, siridb, timescaledb, akumuli, cratedb, prometheus, victoriametrics, timestream, questdb)
      --initial-scale uint                     Initial scaling variable specific to the use case (e.g., devices in 'devops'). 0 means to use -scale value
      --interleaved-generation-group-id uint   Group (0-indexed) to perform round-robin serialization within. Use this to scale up data generation to multiple processes.
      --interleaved-generation-groups uint     The number of round-robin serialization groups. Use this to scale up data generation to multiple processes. (default 1)
      --log-interval duration                  Duration between data points (default 10s)
      --max-data-points uint                   Limit the number of data points to generate, 0 = no limit
      --max-metric-count uint                  Max number of metric fields to generate per host. Used only in devops-generic use-case (default 100)
      --profile-file string                    File to which to write go profiling data
      --scale uint                             Scaling value specific to use case (e.g., devices in 'devops'). (default 1)
      --seed int                               PRNG seed (default: 0, which uses the current timestamp)
      --timestamp-end string                   Ending timestamp (RFC3339). (default "2016-01-02T00:00:00Z")
      --timestamp-start string                 Beginning timestamp (RFC3339). (default "2016-01-01T00:00:00Z")
      --use-case string                        Use case to generate.
pflag: help requested

03 TSBS 基础使用

3.1 生成测试数据

使用 tsbs_generate_data 工具生成测试数据,如下例子中生成 cpu 相关的时序数据,时段为 2023-08-01T00:00:002023-08-02T00:00:00Z 这一天内每隔 10 秒一条数据,这些数据通过管道传输到指定的 gzip 文件中

$ tsbs_generate_data --use-case="cpu-only" --seed=123 --scale=4000 \
    --timestamp-start="2023-08-01T00:00:00Z" \
    --timestamp-end="2023-08-02T00:00:00Z" \
    --log-interval="10s" --format="timescaledb" \
    | gzip > /tmp/timescaledb-data.gz

使用该工具生成测试工具时需要指定相关参数,部分参数含义如下:

  • –use-case:数据类型,分为 iot、cpu-only 和 devops
  • –seed:指定伪随机数生成器 PRNG 种子,例如 123
  • –scale:指定生成数据中的设备数量,例如 4000
  • –timestamp-start:数据生成的开始时间,例如 2023-08-01T00:00:00Z
  • –timestamp-end:数据生成的结束时间,例如 2023-08-02T00:00:00Z
  • –log-interval:数据之间的时间间隔,以秒为单位,例如10
  • –format:数据格式匹配指定数据库类型, 例如 timescaledb (cassandra、clickhouse、cratedb、influx、mongo、siridb、timescaledb)

3.2 生成查询脚本

可以使用 tsbs_generate_queries 工具生成指定查询类型的脚本,也可以使用 scripts/generate_queries.sh 脚本批量生成多种类型的查询脚本

# 生成指定类型的查询脚本
$ tsbs_generate_queries --use-case="cpu-only" --seed=123 --scale=4000 \
    --timestamp-start="2023-08-01T00:00:00Z" \
    --timestamp-end="2023-08-02T00:00:00Z" \
    --queries=1000 --query-type="single-groupby-1-1-1" \
    --format="timescaledb" \
    | gzip > /tmp/timescaledb-queries.gz

# 批量生成多种类型的查询脚本
$ cd /home/randy/go/src/github.com/timescale/tsbs
$ FORMATS="timescaledb" SCALE=4000 SEED=123 \
    TS_START="2023-08-01T00:00:00Z" \
    TS_END="2023-08-02T00:00:01Z" \
    QUERIES=1000 QUERY_TYPES="single-groupby-1-1-1 single-groupby-1-1-12 single-groupby-1-8-1 single-groupby-5-1-1 single-groupby-5-1-12 single-groupby-5-8-1 cpu-max-all-1 cpu-max-all-8 double-groupby-1 double-groupby-5 double-groupby-all high-cpu-all high-cpu-1 lastpoint groupby-orderby-limit" \
    BULK_DATA_DIR="/tmp/bulk_queries" scripts/generate_queries.sh

生成查询脚本的参数与生成测试数据的指定参数大部分是一致的,不同的参数主要有:

  • –queries:指定生成查询的数量,例如 1000
  • –query-type:指定生成查询脚本的类型,例如 single-groupby-1-1-1 或 last-loc 等

cpu-only 的时序数据生成查询脚本的可选类型如下表:

Query typeDescription
single-groupby-1-1-1Simple aggregrate (MAX) on one metric for 1 host, every 5 mins for 1 hour
single-groupby-1-1-12Simple aggregrate (MAX) on one metric for 1 host, every 5 mins for 12 hours
single-groupby-1-8-1Simple aggregrate (MAX) on one metric for 8 hosts, every 5 mins for 1 hour
single-groupby-5-1-1Simple aggregrate (MAX) on 5 metrics for 1 host, every 5 mins for 1 hour
single-groupby-5-1-12Simple aggregrate (MAX) on 5 metrics for 1 host, every 5 mins for 12 hours
single-groupby-5-8-1Simple aggregrate (MAX) on 5 metrics for 8 hosts, every 5 mins for 1 hour
cpu-max-all-1Aggregate across all CPU metrics per hour over 1 hour for a single host
cpu-max-all-8Aggregate across all CPU metrics per hour over 1 hour for eight hosts
double-groupby-1Aggregate on across both time and host, giving the average of 1 CPU metric per host per hour for 24 hours
double-groupby-5Aggregate on across both time and host, giving the average of 5 CPU metrics per host per hour for 24 hours
double-groupby-allAggregate on across both time and host, giving the average of all (10) CPU metrics per host per hour for 24 hours
high-cpu-allAll the readings where one metric is above a threshold across all hosts
high-cpu-1All the readings where one metric is above a threshold for a particular host
lastpointThe last reading for each host
groupby-orderby-limitThe last 5 aggregate readings (across time) before a randomly chosen endpoint

3.3 写入性能测试

tsbs 支持动态和静态数据两种写入场景:

  1. 使用 tsbs_load 工具模拟生产环境,动态生成数据并加载
  2. 预先生成的静态数据,可以使用 tsbs_load 工具加载数据文件,或者使用免配置文件的 tsbs_load_* 系列工具根据指定的数据库类型加载数据

tsbs_load 工具可以用于加载动态模拟数据或预先生成的数据文件,但是这种方式依赖于配置文件,具体使用方法参考:tsbs_load.md,配置文件样例参考:sample-configs

接下来主要介绍两种读取预先生成的数据写入到数据库实例中的方法:

  1. 使用 tsbs_load_<database> 系列工具将指定文件中的数据加载到指定数据库实例,可以用于实现向远程数据库实例写入数据
  2. 使用 scripts/load/load_<database>.sh 脚本将数据文件中的数据写入到本地数据库实例中,这个脚本的实质也是封装 tsbs_load_<database> 系列工具进行加载数据
# 使用 tsbs_load_timescaledb 工具向远程数据库实例写入数据
$ cat /tmp/timescaledb-data.gz | gunzip | tsbs_load_timescaledb \
--postgres="sslmode=require" --host="my.tsdb.host" --port=5432 --pass="password" \
--user="benchmarkuser" --admin-db-name=defaultdb --workers=8  \
--in-table-partition-tag=true --chunk-time=8h --write-profile= \
--field-index-count=1 --do-create-db=true --force-text-format=false \
--do-abort-on-exist=false

# 使用 load_timescaledb.sh 脚本向本地 timescaledb 实例写入数据
$ cd /home/randy/go/src/github.com/timescale/tsbs
$ NUM_WORKERS=2 BATCH_SIZE=10000 BULK_DATA_DIR=/tmp DATABASE_PORT=port \
DATABASE_USER=user DATABASE_NAME=dbname DATABASE_PWD=passwd \
    scripts/load/load_timescaledb.sh

tsbs_load_<database> 工具可指定参数,不同的数据库类型并不一致,在使用时可以使用 --help 命令查看相关参数的含义

$ tsbs_load_influx --help
Usage of tsbs_load_influx:
      --backoff duration            Time to sleep between requests when server indicates backpressure is needed. (default 1s)
      --batch-size uint             Number of items to batch together in a single insert (default 10000)
      --consistency string          Write consistency. Must be one of: any, one, quorum, all. (default "all")
      --db-name string              Name of database (default "benchmark")
      --do-abort-on-exist           Whether to abort if a database with the given name already exists.
      --do-create-db                Whether to create the database. Disable on all but one client if running on a multi client setup. (default true)
      --do-load                     Whether to write data. Set this flag to false to check input read speed. (default true)
      --file string                 File name to read data from
      --gzip                        Whether to gzip encode requests (default true). (default true)
      --hash-workers                Whether to consistently hash insert data to the same workers (i.e., the data for a particular host always goes to the same worker)
      --insert-intervals string     Time to wait between each insert, default '' => all workers insert ASAP. '1,2' = worker 1 waits 1s between inserts, worker 2 and others wait 2s
      --limit uint                  Number of items to insert (0 = all of them).
      --replication-factor int      Cluster replication factor (only applies to clustered databases). (default 1)
      --reporting-period duration   Period to report write stats (default 10s)
      --results-file string         Write the test results summary json to this file
      --seed int                    PRNG seed (default: 0, which uses the current timestamp)
      --urls string                 InfluxDB URLs, comma-separated. Will be used in a round-robin fashion. (default "http://localhost:8086")
      --workers uint                Number of parallel clients inserting (default 1)
pflag: help requested

数据写入过程中每 10 秒打印一次数据写入情况,每次打印的内容包括:

  • timestamp:结果输出时间,时间戳
  • metrics per second in the period:距离上一次输出期间每秒写入的 metric 数据量
  • total metrics inserted:已经插入的 metric 数据量
  • overall metrics per second:每秒总 metric 数据量
  • rows per second in the period:距离上一次输出期间每秒写入的记录行数 row
  • total number of rows:已经插入的记录行数
  • overall rows per second:每秒总记录行数

并在最后打印整体的性能测试结果包含 metric 数据和记录行 row 平均插入速度

time,per. metric/s,metric total,overall metric/s,per. row/s,row total,overall row/s
# ...
1518741528,914996.143291,9.652000E+08,1096817.886674,91499.614329,9.652000E+07,109681.788667
1518741548,1345006.018902,9.921000E+08,1102333.152918,134500.601890,9.921000E+07,110233.315292
1518741568,1149999.844750,1.015100E+09,1103369.385320,114999.984475,1.015100E+08,110336.938532

Summary:
loaded 1036800000 metrics in 936.525765sec with 8 workers (mean rate 1107070.449780/sec)
loaded 103680000 rows in 936.525765sec with 8 workers (mean rate 110707.044978/sec)

3.4 查询性能测试

数据库实例完成数据写入并准备好查询脚本之后,可以使用 tsbs_run_queries_<database> 系列工具来执行查询脚本并生成性能测试结果

$ cat /tmp/queries/timescaledb-cpu-max-all-8-queries.gz | \
    gunzip | tsbs_run_queries_timescaledb --workers=8 \
        --postgres="sslmode=disable" --hosts="my.tsdb.host" --port=5432 \ 
        --user="benchmarkuser" --pass="passwd" 

执行查询测试完成后会得到如下结果 min med mean max stddev sum count | 最小值 中位数 平均值 最大值 stddev 总时间 执行次数

run complete after 1000 queries with 8 workers:
TimescaleDB max cpu all fields, rand    8 hosts, rand 12hr by 1h:
min:    51.97ms, med:   757.55, mean:  2527.98ms, max: 28188.20ms, stddev:  2843.35ms, sum: 5056.0sec, count: 2000
all queries                                                     :
min:    51.97ms, med:   757.55, mean:  2527.98ms, max: 28188.20ms, stddev:  2843.35ms, sum: 5056.0sec, count: 2000
wall clock time: 633.936415sec

如果文章对你有帮助,欢迎一键三连 👍 ⭐️ 💬 。如果还能够点击关注,那真的是对我最大的鼓励 🔥 🔥 🔥 。


参考资料

GitHub - timescale/benchmark-postgres: Tools for benchmarking TimescaleDB vs PostgreSQL

GitHub - timescale/tsbs: Time Series Benchmark Suite, a tool for comparing and evaluating databases for time series data

TimescaleDB vs. PostgreSQL for time-series

基于 TSBS 标准数据集数据库>时序数据库 TimescaleDB、InfluxDB 与 TDengine 的性能对比测试

timescaledb简介及性能测试


http://www.niftyadmin.cn/n/5229959.html

相关文章

解析CST电磁仿真软件:探索CST版本特点及价格

在电磁领域&#xff0c;高效而精确的仿真工具对于设计和分析至关重要。CST 软件&#xff0c;作为电磁场仿真领域的领军者&#xff0c;为工程师提供了全面、灵活的解决方案。本文将深入介绍 CTS 软件的特点&#xff0c;对比不同版本的价格。 CST 软件简介 CST Studio Suite 一套…

CNN对 MNIST 数据库中的图像进行分类

加载 MNIST 数据库 MNIST 是机器学习领域最著名的数据集之一。 它有 70,000 张手写数字图像 - 下载非常简单 - 图像尺寸为 28x28 - 灰度图 from keras.datasets import mnist# 使用 Keras 导入MNIST 数据库 (X_train, y_train), (X_test, y_test) mnist.load_data()print(&…

12个国外电子元器件基本参数(下)

DAC8162SDSCR TI DAC088S085CISQNOPB TI TL4050C41QDBZR TI NE3516S02-T1D-A RENESAS TECHNOLOGY MXL862-AL-R MAXLINEAR SI32176-B-GM1R SILICON LAB

uniapp 使用web-view外接三方

来源 前阵子有个需求是需要在原有的项目上加入一个电子签名的功能&#xff0c;为了兼容性和复用性后面解决方法是将这个电子签名写在一个新的项目中&#xff0c;然后原有的项目使用web-view接入这个电子签名项目&#xff1b; 最近又有一个需求&#xff0c;是需要接入第三方的…

【Linux】快速上手自动化构建工具make/makefile

&#x1f440;樊梓慕&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》《Linux》 &#x1f31d;每一个不曾起舞的日子&#xff0c;都是对生命的辜负 目录 前言 1.什么是make / makefile 2…

微信小程序踩坑记录

一、引言 作者在开发微信小程序《目的地到了》的过程中遇到过许多问题&#xff0c;这里讲讲一些技术和经验问题。 基本目录机构&#xff1a; 二、问题 1、定位使用 获取定位一定要在app.json里面申明&#xff0c;不然是没办法获取定位信息的 "requiredPrivateInfos"…

海云安谢朝海:开发安全领域大模型新实践 人工智能助力高效安全左移

2023年11月29日&#xff0c;2023中国&#xff08;深圳&#xff09;金融科技大会成功举行&#xff0c;该会议是深圳连续举办的第七届金融科技主题年度会议&#xff0c;也是2023深圳国际金融科技节重要活动之一。做好金融工作&#xff0c;需要兼顾创新与安全&#xff0c;当智能体…

AdWords 广告字符的限制是多少?

谷歌已经发展到不仅仅是一个简单的网络搜索。谷歌已成为任何组织所希望的最好的广告网络之一&#xff0c;不断有全球观众来到它研究项目和便利设施、数据、新闻、解决方案等等。 手机的变化带来了数字广告形式的初步转变&#xff0c;随后学习算法的发展和接受也给Google AdWor…