测试流程复现第二弹!IoTDB 在国际数据库性能测试排行榜结果如何?
之前,因为 Apache IoTDB 多项性能表现位居 benchANT 时序数据库排行榜(Time Series: DevOps)性能排行第一名,我们进行了基于 benchANT 榜单的背景介绍和基于它测试基准的环境复现。还没有看的友友们可以点此查看哦!
下面我们将继续介绍我们复现的写入、查询具体测试步骤,并分析对比 Apache IoTDB 及其它时序数据库的性能表现。
4 命令集脚本
本章节介绍 benchANT 测试流程使用的命令集脚本。
用户首先需要在 AWS 创建 EC2 实例来部署测试客户端与数据库服务端。客户端对应的 EC2 规格代码固定为 c5.4xlarge
,服务端根据测试负载不同对应两类规格代码 m5.large
与 m5.xlarge
。EC2 实例操作系统选择 ubuntu,存储类型选择 GP2,存储容量为 100GB。
创建完 EC2 实例后,用户需要在客户端部署 TSBS,在服务端部署 IoTDB Server(采用默认的 1ConfigNode + 1DataNode 模式部署)。客户端安装好 Golang 编译环境后,通过链接 https://github.com/benchANT/tsbs 将代码下载至本地,在代码目录执行 make 命令即可一键生成可执行程序,以下 4 个步骤涉及的“数据生成”、“数据导入”、“生成查询”及“执行查询”程序均位于 bin 目录下。
本章节假设 IoTDB Server 部署在 m5.xlarge 实例上,部署的机器 IP 为 172.31.8.255。
4.1 数据生成
其中参数的含义如下:
use-case:测试场景,有"devops"与"iot"两种。benchANT 测试使用的是"devops"。该场景模拟了服务器运行时的监控数据。
seed:数据生成的随机数种子。
scale:devops 场景中 host/ 服务器的数量,等同于 IoTDB 里设备的数量。
timestamp-start:生成数据集的开始时间。
timestamp-end:生成数据集的结束时间。
log-interval:每条数据的时间间隔。
format:指定数据库。
生成的数据集格式如下所示,其中 0 开头的对应于 IoTDB 中的时间序列创建语句,1 开头的表示数据插入语句。
4.2 数据导入
其中参数的含义如下:
host:IoTDB server 部署的地址,本文假设 IoTDB 部署的地址为"172.31.8.255"。
port:IoTDB server 部署的端口,默认为 6667。
user:IoTDB 连接用户名,默认为 root。
password:IoTDB 连接密码,默认为 root。
timeout:IoTDB 执行请求的超时时间。
workers:并发客户端数量。
batch-size:批处理大小,benchANT 客户端每次转发的数据行数。
该命令执行结束之后,会在 output.log 文件保存写入测试的结果,包含导入的数据总量、导入耗时、写入吞吐等指标。
4.3 生成查询
其中参数的含义如下:
timestamp-start:查询数据集的开始时间。
timestamp-end:查询数据集的结束时间。
use-case:测试场景,与写入数据生成时使用的参数保持一致。
seed:数据生成的随机数种子。与写入数据生成时使用的参数保持一致。
scale:devops 场景中 host/ 服务器的数量,等同于 IoTDB 里设备的数量,与写入数据生成时使用的参数保持一致。
queries:生成的查询测试语句的数量。
query-type:查询类型。benchANT 测试使用了查询类型"single-groupby-1-1-1",即查询一个设备、一个测点在 1 小时内按分钟分段聚合的结果。生成的查询语句示例:
SELECT MAX_VALUE(usage_user) FROM root.cpu.host_1 GORUP BY ([2022-07-25 00:00:00, 2022-07-25 01:00:00), 1h)
执行完该条命令后,总共会生成十万条查询语句,每个查询语句会从 Metric "CPU"下的 1000 个设备里随机选择 1 个设备、从"2022-07-25T00:00:00Z"至"2022-07-28T00:00:00Z"的时间区间内随机选择 1 个小时作为查询条件。
4.4 执行查询
其中参数的含义如下:
host:IoTDB server 部署的地址,本文假设 IoTDB 部署的地址为"172.31.8.255"。
port:IoTDB server 部署的端口,默认为 6667。
user:IoTDB 连接用户名,默认为 root。
password:IoTDB 连接密码,默认为 root。
workers:并发客户端数量。
print-responses:是否打印查询的结果。
use-groupby:使用 IoTDB GroupBy RPC 接口。
该命令执行结束之后,会打印出查询测试的结果,包含查询延迟、查询吞吐等指标。
为了使得 JIT 可以更好的进行代码编译预热,上述测试语句可以重复执行 3 次,每次执行间隔 30s。
5 性能对比
上一章节介绍了测试的命令集脚本,在本章节中会介绍 IoTDB 的测试结果以及达到该性能所采用的建模方式及调优参数。
5.1 IoTDB 建模
在测试中,IoTDB 的建模如下图所示,监控的 9 个大项 metric 作为 9 个 db,每个 db 下均有 1000 个设备(代表 1000 台服务器),每个 db 下的设备采集的测点保持一致,如 cpu metric 下一共记录了 10 个测点,分别为:usage_user、usage_system、usage_idle、usage_nice、usage_iowait、usage_irq、usage_softirq、usage_steal、usage_guest 和 usage_guest_nice,这 10 项测量值的数据类型均为 INT,记录了用户侧 CPU 使用率、系统侧 CPU 使用率等;mem metric 下一共记录了 9 个测点,分别为:total、available、used、free、cached、buffered、used_percent、available_percent 及 buffered_percent,这 9 项测量值的数据类型为 INT 或 DOUBLE,记录了内存总量、内存可用量、内存空闲量等。9 个大项监控指标累计记录了 101 项测量值。
除了测量值外,每个设备也会记录其专属的 tags 信息(标签值),标签值是设备的描述,其不随时间而进行改变,在 benchANT 测试场景中设备的 tags 信息记录了 region、datacenter、rack、os、arch、team、service、service_version 及 service_environment 字段,IoTDB 将 tags 数据当作一个测点存储于设备之下,并在该测点上添加 tags 索引。
在该建模中,每个设备均为对齐设备,即该设备下所有测点的时间戳都是“对齐”的,采用对齐设备,可以在一定程度上提升写入性能,降低存储空间占用。
另外我们可以发现,对于每一个 db,该 db 下的所有设备挂载的测点都是相同的,实际上这种结构也可使用 IoTDB 中的“模板”进行优化,以 cpu metric 为例,在 IoTDB 中创建一个 cpu 模板 cpu_template:
然后将该模板挂载至 root.cpu 层级并激活即可,如此 root.cpu 下的设备都会包含 cpu 模板中包含的测点。通过使用模板,可以降低数据库的元数据空间占用。
5.2 性能分析
在 benchANT 测试中,IoTDB 提供了两个版本的配置参数:Vanilla 与 Tuned,其中 Vanilla 为默认参数,即使用 IoTDB 默认的配置文件,仅修改了 JAVA 的最大堆内内存;Tuned 为进阶参数,根据机器的配置与测试负载对数据库的参数进行了相应的适配。
下表以 benchANT Small Scaling 环境( 4 核 16GB、单机部署)为例,介绍了 IoTDB 在 Vanilla 版本与 Tuned 版本下设置的参数,通过这些参数的对比,用户也可以了解 IoTDB 常见的调优方向。
内存参数:Vanilla 环境仅将 DataNode 的最大堆内内存设置机器内存*0.75,这种设置相对简单。Tuned 环境对 ConfigNode 与 DataNode 使用的内存进行了更加细致的分配。ConfigNode 存储的是集群全局数据,该部分数据通常占用空间较小,所以可以给 ConfigNode 分配较少的内存。DataNode 存储了真实的时间序列元数据与数据,该部分占用空间较大,所以给 DataNode 分配较多的内存。
GC 算法:JDK17 使用的默认 GC 算法为 G1,G1 算法以回收效率优先。而在 benchANT 的评测中,Throughput(写入吞吐、查询吞吐等)是一个重要的数据库性能衡量指标,所以可以将 GC 算法调整为更加关注吞吐量的 Parallel GC 算法。
共识协议:benchANT 测试的 xSmall 与 small 场景均为数据库单机部署,而 IoTDB 默认的共识协议 Ratis,IoT 主要适配分布式集群;对于单机实例部署,采用 Simple 共识协议便可满足要求。
合并参数:benchANT 测试中有一项评估指标为“存储空间占用”,而“存储空间占用”会在查询评测结束时进行统计,所以为了达到较低的“存储空间占用”,IoTDB-Tuned 适当加强了合并的力度,可以在更短的时间内完成数据合并。
数据分区参数:IoTDB 在 benchANT 测试的建模中会生成 9 个 database,而 benchANT 使用的测试机器规格相对较小,所以为每个 database 分配一个 data region 便可达到足够的并行度。当机器规格提升时,可以通过调整 default_data_region_group_num_per_database 参数来提升写入及查询的并行度。
其他参数:该部分列出的参数对 IoTDB 的性能影响相对较小。
enable_last_cache 用于控制是否开启 last 缓存,由于 benchANT 查询测试中没有最新值查询,所以可以关闭最新值缓存功能。由于 IoTDB 采用了高效的最新值缓存算法,所以该参数的开关对写入性能相对较小。
dn_metric_level 是 IoTDB 监控写入的级别,开启该指标主要用于线上问题排查;监控数据的采集会造成 CPU 使用率些微升高,在 benchANT 测试中可关闭该选项。
max_number_of_points_in_page 用于控制 TsFile 中 Page 的数据点数,通常数据点数越多、数据的压缩效果越好。同时 Page 里的数据点数也会影响查询的性能,benchANT 的查询测试只会查询 1 小时范围内的点,所以综合考虑压缩率与查询性能后,Tuned 环境将该值设置为合适的点数。
wal_async_mode_fsync_delay_in_ms 用于控制 WAL 模块调用 fsync 的频率,以保证数据落盘的可靠性。IoTDB-WAL 默认采用 fsync 模式,fsync_delay 等于 1 秒。通常 fsync 的频率越高,消耗的 IO 资源越多,对写入性能造成的影响越大。由于 IoTDB 采用了批量写等优化,大幅降低了 fsync 的频率对写入性能的影响,Tuned 环境将 fsync_delay 设置成 3 秒即可满足需求。
下图所示为 benchANT 在时序场景下的测试榜单,可以看到 IoTDB 在 small Scaling 环境与 xSmall Scaling 环境下的读、写、存储性能均排在首位,且大幅领先其他数据库产品。下文将基于榜单详细分析 IoTDB 与其他时序数据库的性能差异。
写入吞吐(WRITE THROUGHPUT):表示单位时间内处理的写入数据点数量,该数值越高表明数据库写入性能越高。在 small Scaling 环境下,IoTDB 的写入吞吐为 3,636,312 ops,是 InfluxDB 的 6.9 倍、TimescaleDB 的 2.3 倍、QuestDB 的 1.4 倍;在 xSmall Scaling 环境下,IoTDB 的写入吞吐为 1,426,490 ops,是 InfluxDB 的 5.4 倍、TimescaleDB 的 1.1 倍、QuestDB 的 2.8 倍。可以看到,无论是小规格机器或大规格机器,IoTDB 都能很好的压榨机器性能,表现出高效的写入效率。并且随着机器规格的提升,IoTDB 写入性能的提升也更加明显,领先其他数据库的比例也更多。
查询延迟(READ LATENCY):表示单个查询的响应时间,该数值越低表明数据库处理单个查询的速度越快。在 small Scaling 环境下,查询延迟为 2ms,查询速度是 InfluxDB 的 23 倍、TimescaleDB 的 97 倍、QuestDB 的 57 倍;在 xSmall Scaling 环境下,查询延迟为 1ms,查询速度是 InfluxDB 的 47 倍、TimescaleDB 的 430 倍、QuestDB 的 82 倍。通过测试结果可以看出,IoTDB 的查询性能领先其他数据库达十倍甚至百倍,在保持高写入性能的前提下,通过合理的文件结构设计与文件合并机制,借助于 IoTDB 强大的查询引擎及丰富的查询接口设计,IoTDB 的查询性能也达到了极致。
存储占用(STORAGE CONSUMPTION):表示存储空间占用,记录测试运行过程中的磁盘平均使用量。在 small Scaling 环境与 xSmall Scaling 环境中,IoTDB 的存储空间使用量均为 2GB,排名位于榜首,这体现了 IoTDB 的“极致压缩”能力。IoTDB 提供了丰富的编码与压缩算法,能够极好的适应各种数据类型与数据分布。在 benchANT 测试中,INT 类型使用 TS_2DIFF 编码、DOUBLE 类型使用了 GORILLA 编码,压缩方式采用了 LZ4,在保持了高压缩比的同时还能保证高写入查询性能,最终的测试结果验证了 IoTDB 的“高效读写、极致压缩”。
成本收益(OPERATIONS PER COST):,数值越高越好,因为 IoTDB 在单位成本内可执行的写入请求及查询请求是最多的,所以 IoTDB 的成本收益排名第一。
small Scaling 环境下的测试榜单:
xSmall Scaling 环境下的测试榜单:
6 总结
从测试结果可以看到,无论是在小规格机器或大规格机器上,IoTDB 都能很好的利用机器性能,表现出高效的写入效率。并且随着机器规格的提升,IoTDB 写入性能的提升也更加明显,领先其他数据库的比例也更多。
在保持高写入性能的前提下,通过合理的文件结构设计与文件合并机制,借助于 IoTDB 强大的查询引擎及丰富的查询接口设计,IoTDB 的查询性能领先其他数据库达十倍甚至百倍。
IoTDB 提供了丰富的编码与压缩算法,能够极好的适应各种数据类型与数据分布。在 benchANT 测试中,INT 类型使用 TS_2DIFF 编码、DOUBLE 类型使用了 GORILLA 编码,压缩方式采用了 LZ4,在保持了高压缩比的同时还能保证高写入查询性能,最终的测试结果验证了 IoTDB 的“高效读写、极致压缩”。
benchANT 对时序数据库测试的结果,证明了 Apache IoTDB 强大的性能和与较其他数据库系统的巨大优势。
评论