千家信息网

Apache TDB性能优化的知识点有哪些

发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,本篇内容介绍了"Apache TDB性能优化的知识点有哪些"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所
千家信息网最后更新 2026年10月31日Apache TDB性能优化的知识点有哪些

本篇内容介绍了"Apache TDB性能优化的知识点有哪些"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

关于存储组

现在每个存储组是一个相对独立的引擎,而且读写锁是存储组级别的。因此把存储组从1改到10,读写基本能增速8倍。单个 IoTDB 实例推荐设置 CPU 核数个存储组。存储组越多,并行度就越高。我们之后打算把锁粒度下放到设备层。

设备

设备这个概念没有在 SQL 语句里显示的定义出来,而是在服务器端处理时候默认将倒数第二层设置为设备,导致大家容易忽略这个概念。先说一下设备影响什么。

(1)区分顺序数据 和 乱序数据是以设备为粒度的。举个例子,假如一个设备在内存里写了时间戳 1-10 的数据(不论写哪些测点,时间戳都会算到这个设备头上),落盘了,再写时间戳<=10 的数据,这些数据就会被当做乱序数据缓存并落盘。

(2)设备粒度的时间范围索引。对于每个 TsFile 文件,会构造设备粒度的索引在内存里,假如所有设备都活跃,N 个 TsFile,D 个设备,就有 N*D 条索引。百万级设备的索引内存会吃不消。这个东西我们会在一两个版本内改掉。

再说一下怎么设计建模来控制设备数。对于实际应用设备和传感器层次比较简单的情况比较好说,设备下直接是传感器层,一般不会建错。对于设备下有多层结构的就要注意了。

比如我一个设备下有10个传感器(s1,s2,...,s10),每个传感器采集10个时间序列的数据(f1,f2,...f10)。这时候很容易建成 root.xxx.device.s1.f1 这种。当你建成这种时候,你以为的 device 就不再是你以为的 device 了,实际的device 变成了 root.xxx.device.s1 。 实际 device 数量就是你以为的 10 倍了。

怎么办嘞,如果设备下的子设备不多,这样建模也没啥问题,只要你心里清楚系统中实际有多少个设备就行,这样沟通不会出现偏差,便于以后排查问题。

如果子设备非常多,可以把设备后的那几层压成一层,比如 root.xxx.device.s1_f1 。由于我们是以 . 作为分隔符的,这样 s1_f1 就变成 1 层了。 实际的设备还是 root.xxx.device。

Measurement 定义

Measurement 也就是最后一层的测点。假如一个测点是 INT32 或者 INT64 类型的,而且大部分时间这个数据的值都一样,没什么变化,这时候用 RLE 编码就很好。可以大大节省磁盘空间,当然刷盘速度也会变快。压缩方式开着 SNAPPY 就挺好。

Tag & Attribute

0.10.0 引入的这两个概念,容易分不清这两个有啥区别。 虽然都是 key-value 类型的属性。但是 Tag 是可以反向查询时间序列的元数据的,假如有个 tag 的 key 是 owner,就可以用 show timeseries where owner=Thanos 查灭霸拥有的时间序列。Tag 常驻内存,有Tag到时间序列的索引。

Attribute 就是普通属性了,比如有个属性是 description="this is my series"。这些属性只能是给定时间序列的路径顺带展示一下,辅助人查看的。

因此,要根据实际需求进行区分,那些需要做反向查询的属性,就建成 tag,其他的就搞成 attribute 就行了。

读写优化

读和写关系密切,数据的写入和参数配置会影响查询性能。

写入接口

以 0.10 为例,先同类比较,insertRecords 接口肯定比 insertRecord 接口要快,这个类似 JDBC 的 executeBatch 和 execute 的区别,节省了网络通信次数。同理,insertTablets 比 insertTablet 要快,createMultiTimeseries 也比 createTimeseries 要快。

进一步,insertRecords 方法我们提供了两种,一种是传 Object 的 value,一种是传 String 的 value。如果客户端能获取 value 的类型,建议用 Object 的,会比 String 的快 25% 左右。

跨类比较的话,如果不考虑客户端做格式转化的耗时,insertTablet 比 insertRecords 要快很多,可能 8 倍以上,节省了很多对象封装的耗时,batch size 1000左右就可以。

insertTablet 这个接口默认是没排序的,如果你能保证一个 Tablet 数据的时间戳是非递减的,那就可以多加一个 sorted 为 true 的参数。就节省了客户端的排序。

在统计耗时的时候,还需要注意客户端做格式转化的耗时,可以把接口参数构造的时间和执行的时间分开统计。

查询接口

查询接口比较简单,Session 默认的 hasNext 和 next 会返回 RowRecord 结构,这个结构不一定大家都需要,可以用 SessionDataSet 的 iterator 得到一个迭代器,然后通过类似 JDBC 的接口去得到原始数据,避免很多没用的对象生成。

顺序写入

对于时序数据库,时序是一个很重要的概念,最好不要乱来。IoTDB 支持数据的乱序写入,但是乱序数据会影响查询性能,主要是对于聚合查询,原理是乱序数据会让预计算的统计信息失效,把聚合查询降维打击到读原始数据。

正常情况下,有个几倍的乱序都没问题,但是如果往一个时间段写入了过多(几万倍)的乱序数据,查询时候有可能爆内存。举个例子,内存缓冲区写了时间戳1-10的数据落盘了,然后又写了 9999 遍 1-10 的缓冲区,这样磁盘上就有 1 万个时间戳是 1-10 的数据块。查询时候需要将 1万 个数据块都读出来进行合并,内存占用就比较大了。

面对这种场景,我们会后台做数据整理来处理乱序(在0.9引入的merge,但是0.9版本有bug,0.10修掉了,但是先默认关掉了,会在0.11重新开放merge),但是如果能在客户端避免乱序,就尽量写入的时候避免掉。一个设备就按递增的顺序写入。

如果前边接了 kafka,最好注意一下,把设备 id 作为分区粒度,这样一个设备的数据都会发送到一个分区里,消费的时候同一个分区也能保证顺序。

内存缓冲区

先介绍一下每个序列在内存里能缓存多少个点的怎么算的,用 memtable 大小除以序列数,再除以每个点的大小,比如long类型就是 16字节(8字节时间戳,8字节值),float是12字节。

memtable 的大小可以从日志里看到,搜 reaches,大概日志就是 the memtable size xxx reaches the threshold。如果配置文件里的 enable_parameter_adapter 没有改为 false,这个 memtable 大小就不固定,随着注册的序列数量调整的。

内存缓冲区在一定范围内尽可能大有利于读写。平均每个序列能缓冲100万点以下是比较好的。但是不建议太大,查询时候会临时排序,如果内存中数据点过多,比如千万级,查询时候内存排序会占个十几秒。

为了避免这个问题,0.10.0 里加了个参数,avg_series_point_number_threshold ,默认是 10000,也就是内存缓冲区中每个序列最多缓存这么多点就会刷盘,这个默认参数没给好,可以改成50万或者100万。

memtable_size_threshold 这个参数越大,写入速度快,一般在几百M到一两G左右。不要设置的过小,比如几M,会严重影响写入速度。在设置这个参数时候需要注意不要超内存限制,调这个参数之前需要保证 enable_parameter_adapter 改为 false。

多数据目录

数据库的瓶颈在磁盘IO,简单的提升磁盘IO能力的就是配置多盘。IoTDB 的数据目录可以在 data_dirs 参数配置,用逗号分隔多个目录。可以每块盘一个目录。在写数据的时候会到这几个盘里找最空闲的写。

客户端优化

刚才说了存储组级别的锁,对于同一个存储组的N个写线程,这N个写线程都会抢一把锁,一个存储组对应不超过50个客户端比较好,写线程过多会导致过多的锁竞争。

线程池 SessionPool 的容量,一般搞个服务器 CPU 核数就可以了,不要过多。

客户端的内存,数据的生产和消费速率也可以监控起来,避免提交的任务积压过多,如果客户端内存满了,会出现一个现象:客户端发送请求到服务器,服务器执行和返回很快,但是客户端接收结果会很慢。

容易爆内存的点

select * from root 这个语句在序列过多时候最好不要做,这个操作会把整个库当做一张表,一下查出来所有列的一批数据,容易爆内存,我们会在0.11版本加个检查,及时拒绝。

show timeseries 在 0.10 及以前的版本会把系统所有序列在内存里拷贝一遍传给客户端,如果序列过多,最好指定前缀做个过滤。或者 show child paths 一层一层往下查。

时间序列过多(亿级),元数据可能爆内存,可以按照一条时间序列 200字节估计一下,大概1千万序列会占2G元数据(就是那个元数据树)。

"Apache TDB性能优化的知识点有哪些"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

数据 设备 内存 时间 序列 客户 时候 查询 客户端 参数 过多 存储 接口 实际 就是 时间序列 缓冲 字节 属性 粒度 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网黑科技 哈尔滨大商圈互联网科技有限公司 山东特亿宝互联网科技有限公司 互联网科技工作委员会副主任毛军 互联网科技会 中国 科技 互联网 西安互联网科技 善班互联网科技 镁科技互联网资讯平台 丰台科技园 互联网公司 剑昆互联网络科技有限公司临桂 贵州叶脉互联网科技有限公司所属行业 互联网科技项目计划书材料类 996高科技互联网公司 长沙茂晟互联网科技有限公司 小米互联网科技园入驻 上海钢联属于互联网科技股吗 广东工业互联网大赛深圳学泰科技 信承诺互联网科技有限公司 互联网硬科技公司 互联网科技公司经营范围 中国互联网科技工作委员会毛军 互联网中国科技 广州互联网科技公司 互联网科技公司发展 互联网科技有哪些公司 广西互联网科技孵化中心 济南有互联网科技公司吗 互联网时代的科技公司 平安好医生打造互联网科技医疗
0