时钟导致TDengine偶尔连接失败问题排查和解决

一、环境信息

CentOS 7.9
TDengine 3.1.0.0
OpenJDK 11

二、问题现象

一个数据接入程序,定时将数据从指定文件导入到TDengine,发现每天执行的约1000次导入作业里,有1%~2%是失败的,查询失败作业的日志可以看到抛出如下异常:

[2023-08-07 08:35:00.370] [INFO] [INFO ][2023-08-07 08:33:36] 导入中 2001637/QiJia003/1650038400000/Sec_20220416.csv, 已成功导入 51000 行, 182 MB
[2023-08-07 08:35:06.980] [INFO] [INFO ][2023-08-07 08:33:34] 导入中 2001637/QiJia001/1650038400000/Sec_20220416.csv, 已成功导入 57000 行, 183 MB
[2023-08-07 08:35:00.875] [ERROR] create connection SQLException, url: jdbc:TAOS://:/repo_QiJia_1sec, errorCode -2147483637, state 
java.sql.SQLException: TDengine ERROR (8000000b): Unable to establish connection
    at com.taosdata.jdbc.TSDBError.createSQLException(TSDBError.java:76) ~[k2box-storage-taos3-2.2.5.jar:?]
    at com.taosdata.jdbc.TSDBJNIConnector.executeQuery(TSDBJNIConnector.java:119) ~[k2box-storage-taos3-2.2.5.jar:?]
    at com.taosdata.jdbc.TSDBStatement.executeQuery(TSDBStatement.java:47) ~[k2box-storage-taos3-2.2.5.jar:?]
    at com.alibaba.druid.pool.DruidAbstractDataSource.validateConnection(DruidAbstractDataSource.java:1419) ~[k2box-storage-taos3-2.2.5.jar:?]
    at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1719) ~[k2box-storage-taos3-2.2.5.jar:?]
    at com.alibaba.druid.pool.DruidDataSource$CreateConnectionThread.run(DruidDataSource.java:2813) ~[k2box-storage-taos3-2.2.5.jar:?]
[2023-08-07 08:35:00.883] [ERROR] create connection SQLException, url: jdbc:TAOS://:/repo_QiJia_1sec, errorCode -2147483637, state 
java.sql.SQLException: TDengine ERROR (8000000b): Unable to establish connection
    at com.taosdata.jdbc.TSDBError.createSQLException(TSDBError.java:76) ~[k2box-storage-taos3-2.2.5.jar:?]
    at com.taosdata.jdbc.TSDBJNIConnector.executeQuery(TSDBJNIConnector.java:119) ~[k2box-storage-taos3-2.2.5.jar:?]
    at com.taosdata.jdbc.TSDBStatement.executeQuery(TSDBStatem

三、问题排查

由于此环境的TDengine是不久前从2.6.0升级到3.1.0.0的,升级之前没有这个问题,所以一开始怀疑是TDengine的新版本有问题,或者是新版本的默认参数与旧版本不同导致的。但尝试修改了服务端和客户端(连接池)的各种参数后问题依旧。用ulimit -nlsof -p查询打开的文件数量和文件上限也在正常范围内。

后来考虑是否作业(docker容器)消耗资源有异常,查看资源占用图表时发现折线图有向反方向走的情况(下图红色箭头指向的位置),说明服务器系统时间有倒流的情况。

file

仔细查看前面的失败作业日志,其实也有时间戳倒流的现象,并且连接失败现象与时间戳倒流是同时发生的:

file

因此将问题嫌疑定位到与系统时钟有关。经过进一步排查发现,此服务器使用ntpdate定期从两台ntp服务器分别进行周期性的对时:

1、每5分钟从服务器10.102.9.31同步时间:

[root@taos-1 ~]# crontab -l
*/5 * * * * /usr/sbin/ntpdate 10.102.9.31 >/dev/null 2>&1

2、每64秒从服务器10.102.9.32同步时间:

[root@taos-1 ~]# ntpstat
synchronised to NTP server (10.102.9.32) at stratum 3
   time correct to within 115 ms
   polling server every 64 s
[root@taos-1 ~]#

并且服务器10.102.9.32的时钟比10.102.9.31慢7秒左右,这就造成了这台服务器的时钟周期性的向前和向后跳动。当TDengine服务端的时钟改变时,连接池里原有的连接会失效无法连接。

[root@taos-1 ~]# /usr/sbin/ntpdate 10.102.9.32
 7 Aug 18:51:23 ntpdate[49651]: step time server 10.102.9.32 offset 7.341666 sec

[root@taos-1 ~]# /usr/sbin/ntpdate 10.102.9.31
 7 Aug 18:54:31 ntpdate[1798]: step time server 10.102.9.31 offset -7.200571 sec

四、问题解决

从两台服务器分别对时显然是没有必要的,应该是运维人员不了解情况的情况下操作导致的,去掉其中一个对时的任务后即可。这里我们去掉的是ntpstat里配置的对时服务,我们发现它是用chrony服务实现的,因此执行systemctl stop chronydsystemctl disable chronyd

TDengine与Cassandra集群版性能对比测试

本文记录集群环境下TDengine与Cassandra数据库处理时序数据的性能对比,主要考察数据的写入和读取速度(吞吐率)指标。因为InfluxDB社区版不支持集群,所以没有放在一起进行对比。

一、测试环境

服务器

使用三台物理服务器组成数据库集群,配置如下:

CPU 内存 硬盘 网络
Intel i7 4核8线程 32G 2T 7200转机械 千兆网络
操作系统 TDengine Cassandra
CentOS 7.9 2.6 4.0.6

客户端

CPU 内存 硬盘 网络
Intel i7 4核8线程 32G 256G SSD固态 千兆网络
操作系统 JDK JMeter
Windows10 OpenJDK 11 v4

二、测试结果

数据写入性能

测试数据为10个csv文件,每个文件大小约为10GB,包含下面的内容:

  • 每个文件包含50个设备10天的数据
  • 数据频率为1秒
  • 每行数据包含500列
  • 所有数据均为double类型
  • 每个数据文件包含43200050行
  • 每个数据文件大小为167GB

以不同并发数向数据库写入10个csv文件,多次执行取结果平均值得到的结果见下图,其中横轴是并发线程数,纵轴是每秒写入的数据点数(行x列):

数据库配置为单副本的情况:

file

数据库配置为三副本的情况:

file

三副本时,服务器CPU资源占用率情况,纵轴为CPU占用百分比:

file

总体来看,在相同的条件下TDengine的数据写入速度高于Cassandra数据库,副本数量增加对写入速度没有太大影响,并且TDengine服务器CPU资源占用低于Cassandra。

数据读取性能

在两个数据库中分别建表testdb,并预先存入下面的数据:

  • 50个设备10天的数据
  • 数据频率为1秒
  • 每行数据包含500列
  • 所有数据均为double类型

数据读取测试在三副本配置下进行,测试结果如下图,其中横轴是读取的列数,纵轴是每秒读取到的点数(行x列):

file

从图中可以看到,随着抽取的列数增加两个数据库的数据抽取速度都有增加,TDengine在300列达到峰值,并且TDengine的的读取速度基本保持在Cassandra的4到5倍。

三、测试结论

以上测试结果显示,5并发下TDengine的数据写入性能与Cassandra接近,10并发以上则明显优于Cassandra;在数据读取方面TDengine的性能数倍于Cassandra具有压倒优势。

TDengine、InfluxDB与PostgreSQL单机版性能对比测试

本文记录单机环境下TDengine、InfluxDB和PostgreSQL三种数据库,处理时序数据的性能对比,主要考察数据的写入和读取速度。

一、测试环境

服务器

CPU 内存 硬盘 网络
Intel i7 4核8线程 32G 2T 7200转机械 千兆网络
操作系统 TDengine Influxdb PostgreSQL
CentOS 7.9 2.6 2.0 beta 9.0

客户端

CPU 内存 硬盘 网络
Intel i7 4核8线程 32G 256G SSD固态 千兆网络
操作系统 JDK JMeter
Windows10 OpenJDK 11 v4

二、测试数据

测试数据为10个csv文件,每个文件大小约为10GB,包含下面的内容:

  • 每个文件包含100个设备的数据
  • 数据频率为1秒
  • 每行数据包含1000列
  • 所有数据均为double类型

三、测试结果

数据写入

同时向数据库写入10个csv文件,多次执行取结果平均值:

数据库 数据行导入速率(record/s) 数据点导入速率(points/s)
InfluxDB 235 235000
TDengine 750 750208
PostgreSQL 213 213000

file

数据读取

数据读取性能与读取的列数相关,因此分别测试了不同列数情况下三种数据库的读取速度(单并发):

file

四、测试结论

以上初步测试结果显示,在单并发大多数场景下,TDengine的性能相比InfluxDB和PostgreSQL具有较大优势。由于项目时间所限,此次未能对多并发情况下各个数据库的性能进行对比略显遗憾。作为补充,可参考集群环境多并发条件下TDengine与Cassandra的性能对比(链接)。

TDengine 2.6集群版升级到3.0集群版

本文记录了在由三个物理节点组成的集群上,原地将TDengine 2.6版升级到3.0版的过程,由于3.0的改动比较大,所以此次升级并非完全平滑的升级,只升级了数据库服务,没有将数据库里的存量数据导入到新版环境,如需保留数据请联系taos团队。本文使用的TDengine版本均为社区版,非docker安装。

一、卸载2.6版

备份配置文件

> ansible allnode -m shell -a "mv /etc/taos/ /etc/taos.bak"

按taos文档说明卸载程序后配置文件是会保留的,但3.0版与2.6版的配置文件(配置项)有差异,直接让3.0使用2.6版配置文件会导致服务启动失败。因此决定自行保留并在安装后再3.0版的配置文件:

当缺省配置文件( /etc/taos/taos.cfg )存在时,仍然使用已有的配置文件,安装包中携带的配置文件修改为taos.cfg.org保存在 /usr/local/taos/cfg/ 目录

备份数据文件

数据文件默认位置在/usr/local/taos/data

> ansible allnode -m shell -a "mv /data/tdengine /data/tdengine.bak"

如果升级3.0失败需要恢复为2.6版,则备份的数据文件会起作用,否则可以删除。数据文件的位置以taos.cfg文件内的配置为准。

停止taosd服务并卸载程序

> ansible allnode -m shell -a "systemctl stop taosd"
> ansible allnode -m shell -a "rpm -e tdengine"

192.168.130.153 | CHANGED | rc=0 >>
taosadapter is running, stopping it...
TDengine is removed successfully!
192.168.130.154 | CHANGED | rc=0 >>
taosadapter is running, stopping it...
TDengine is removed successfully!
192.168.130.152 | CHANGED | rc=0 >>
taosadapter is running, stopping it...
TDengine is removed successfully!

其中ansible allnode -m shell -a命令是为了方便在集群所有节点上一起执行,如果没有装ansible工具可在每个节点上手工执行,效果是一样的。

二、安装TDengine3.0

下载单机版安装包

TDengine提供了多种格式的安装包,我们在CentOS上选择使用RPM版的。

> wget https://www.taosdata.com/assets-download/3.0/TDengine-server-3.0.1.5-Linux-x64.rpm

由于安装过程中需要输入一些信息,所以建议在每个节点上手工执行(而非通过ansible):

> rpm -ivh TDengine-server-3.0.1.5-Linux-x64.rpm

安装过程会提示输入两个信息,按taos的安装说明输入即可(我两个都选择了回车跳过):

当安装第一个节点时,出现 Enter FQDN: 提示的时候,不需要输入任何内容。只有当安装第二个或以后更多的节点时,才需要输入已有集群中任何一个可用节点的 FQDN,支持该新节点加入集群。当然也可以不输入,而是在新节点启动前,配置到新节点的配置文件中。

三、修改taos配置文件

根据之前备份的2.6版的taos.cfg文件修改3.0版的配置文件,我这里主要改的是firstEpfqdnlogDirdataDirtimezonecharset等几个:

# first fully qualified domain name (FQDN) for TDengine system
firstEp                   taos-1:6030
# local fully qualified domain name (FQDN)
fqdn                      taos-1
# The directory for writing log files
 logDir                    /data/tdengine/log
# All data files are stored in this directory
 dataDir                  /data/tdengine/data
# system time zone
 timezone              Asia/Shanghai (CST, +0800)
# system locale
 locale                    en_US.UTF-8
# default system charset
 charset                   UTF-8

为节约时间,可以先改好第一个节点的,再复制到其他节点,然后只要去每个节点修改fqdn的值即可。

> scp /etc/taos/taos.cfg root@taos-2:/etc/taos/taos.cfg
> scp /etc/taos/taos.cfg root@taos-3:/etc/taos/taos.cfg

四、启动taosd并查看状态

启动第一个节点

在第一个节点(firstEp)上启动taosd服务,并验证服务启动成功:

> systemctl start taosd
> systemctl status taosd

此处如果遇到启动失败可进一步查看日志文件来找原因。遇到过一个DND ERROR failed to start since read config error的错误比较坑,原因提示不明确。后来发现是hostname与taos.cfg不匹配造成的。

在taos命令行里验证此时有一个dnode:

> taos
taos> show dnodes;
     id      |            endpoint            | vnodes | support_vnodes |   status   |       create_time       |              note              |
=================================================================================================================================================
           1 | taos-1:6030                    |      0 |             16 | ready      | 2022-10-26 14:50:57.131 |                                |
Query OK, 1 rows in database (0.003960s)

添加其他节点

与第一个节点类似,只不过启动后要在taos命令行里执行create dnode命令将当前节点添加到集群。

> systemctl start taosd
> systemctl status taosd
> taos

taos> create dnode "taos-2";
Query OK, 0 of 0 rows affected (0.002127s)

taos> show dnodes;
     id      |            endpoint            | vnodes | support_vnodes |   status   |       create_time       |              note              |
=================================================================================================================================================
           1 | taos-1:6030                    |      0 |             16 | ready      | 2022-10-26 14:50:57.131 |                                |
           2 | taos-2:6030                    |      0 |             16 | ready      | 2022-10-26 14:54:48.635 |                                |
Query OK, 2 rows in database (0.003566s)

五、创建数据库用户(可选)

创建必要的数据库用户:

> taos -s "CREATE USER k2data PASS 'xxxxxxxx';"

创建必要的database:

注意在2.6里的DAYS改为DURATION了,且3.0不支持UPDATE参数了(相当于UPDATE=1不可修改):

taos -s 'CREATE DATABASE repos REPLICA 3 KEEP 3650 DURATION 10;'

至此TDengine版本升级完成。

参考资料

TDengine多种安装包的安装和卸载

使用安装包立即开始

集群部署和管理