TDengine 的用户如何优化数据的写入速度?

大家都听过这样的一句话:在物联网大数据的场景之下,TDengine最大的优势之一,就是写入速度——这是由于TDengine独特设计的成果。但是,一些用户在初次使用TDengine的时候会觉得写入性能并没有达到自己的预期。这些用户中,有的是直接使用TDengine的服务端,有的是使用了TDengine的客户端,还有的用户使用各种不同的连接器,可以说是形形色色不一而同。

TDengine 的用户如何优化数据的写入速度? - TDengine Database 时序数据库

那么——究竟要如何解决这些种类繁多的写入“慢”呢?我们提倡的思路就是——在确保服务端本身的参数和配置已经调整到最优的情况下,逐层向外排查硬件软件网络等因素。

对于通过连接器使用TDengine的用户来说,由于涉及了更多的模块介入以及网络问题,遇到性能问题要稍微麻烦一些。但即便如此,也要对数据库本身的做好性能相关的配置。而在此之前,用“我的xxxx连接器写数据特别慢”是不精准且不利于排查问题的。

所以不论你的场景多么复杂,我们都要首先去服务端检测TDengine的性能。而最省时高效的方法就是使用官方的工具taosdemo观察写入速度是否大致相同。这样做的好处是,可以在第一时间定位问题是否出现在数据库服务端本身。然后,我们就可以针对性地排查其余因素。比如服务端与客户端的网络通信,客户端内部是否异常。

taosdemo的具体使用方式可以通过使用“taosdemo –help”来了解,这个工具可以通过设置表数量、表行数、数据类型、单批插入行数,甚至模拟乱序写入等高级功能来模拟出你在工作使用中遇到的类似场景。跑起来后,taosdemo会自动生成数据完成写入,并在最后给出性能数据。

如果在使用taosdemo依然性能很慢的话,我们就可以做如下优化了:

1. 要提高写入效率,不能一次insert只写入一条记录,那样将是对资源的浪费。建议一条SQL语句写入多条记录,一次写入的记录条数越多,插入效率就越高。典型的情况是,一条SQL写入多个表各一条记录,如:insert into tb1 values(….) tb2 values(….) tb3 values(…)。但一条记录不能超过16K,一条SQL语句总长度不能超过64K(可通过参数maxSQLLength配置,最大可配置为1M,具体内容官方文档可查)。在使用taosdemo模拟的时候,可以通过-r参数来指定单次insert的写入行数,但是要注意计算SQL长度不要超过maxSQLLength。

注:当前最新的版本(2.1.0)里taosdemo的默认maxSQLLength已经为1MB,无需自己调整。

2.TDengine支持多线程同时写入,要进一步提高写入速度,一个12核CPU的客户端可以打开20个以上的线程同时写。但线程数达到一定数量后,速度就无法再提高,甚至还会下降,因为线程切频繁切换,带来额外开销。在使用taosdemo模拟的时候,线程数可以通过-T来指定,一般为cpu核数或二倍核数为最佳。

3. 在大量数据涌入内存等待落盘的时候,vnode虚拟数据节点的内存大小设置就显得尤为重要。cache和blocks这两个参数分别代表着内存块的大小和块数,他们的乘积便是vnode的预留内存。对于很多场景,默认的blocks数量是不够的。当写入缓存不够时,数据不能一次落盘,将会被写入.last临时文件,客观上增加磁盘的IO操作。这就需要根据你的场景酌情增加这个参数的值(3的倍数),在观察写入速度是否提升的同时,观察内存是否为性能瓶颈且保持在一个安全的使用范围内,直到找到最优解。

点击这里,查看taosdemo的使用手册。

在这个过程中,大家要不停地控制变量,观察自己的性能瓶颈出现在哪个环节。是预分配的内存不足,还是操作系统内存不足,抑或是CPU吃光,还是硬盘读写极限,然后做一个针对性的调整。

这样调整过后,对于一个直接使用TDengine服务端的用户来讲,基本就算是足够了。值得一提的是,大家不用过于专注于TDengine每秒写了多少行。因为每行有多少列(测点)和每一列(测点)的数据类型都是不固定的。

而对于使用连接器或客户端的用户来说,如果以上操作还没有解决您的写入性能问题,接下来我们再来排查网络、客户端、应用层面的因素。

由于服务端依靠网络和应用或客户端连接,所以网络问题是性能问题上不可忽视的环节。这里可以给出一个很典型的代表案例:

某用户在使用C接口插入数据的时候曾遇到这样这样的情况: 插入速度时快时慢,整体上比预期速度慢了不少。

于是,我们一起配置好了内存,线程数和单条SQL写入行数。可是在那之后,问题却依然存在。所以我们又一起看了日志发现了一些关于网络通信的告警提示,再结合服务器的监控数据,我们初步诊断写入很慢的原因是网络方面的路由阻塞。之后,该用户便重新搭建了网络拓扑只使用本地虚拟机组成局域网,问题便消失了。

另外,由于TDengine的客户端功能很多(负责获取并缓存元数据;将插入、查询等请求转发到正确的数据节点;在把结果返回给应用时,还需要负责最后一级的聚合、排序、过滤等操作)所以很多时候,TDengine的性能问题并不是出在服务端而是客户端。当你发现你的性能迟迟上不去的时候,去看一下客户端服务器的后台,兴许会有惊人的发现。万万没想到——客户端也会成为写入性能的瓶颈。这个时候,就需要你酌情增加客户端服务器性能或者数量了。

最后,连接器由于在逻辑上是很薄的一层,所以它的性能通常是受相关语言自身特性影响,排除遇到bug的情况下,一般是可以认为是没有优化空间的,比如:Java就是会比C慢一些。

OK,大概就是这样了,读到这里的用户应该对于TDengine的写入性能优化已经有了一个初步的轮廓。这样一来,日后即便是需要官方的技术支持也能做到精准提问,这样对双方都将会是一种非常愉快的体验。对于很多社区版TDengine的新用户来说,由于工作时间紧迫或者是其他原因,会导致大家没有耐心去一步一步地阅读文档了解产品。

在这个时候,这篇文章就能够发挥它该有的作用。