• 作者:老汪软件技巧
  • 发表时间:2024-09-21 11:02
  • 浏览量:

简介

最近应客户需求搭建了一套 TDEngine 3.0 集群,并通过 J220b09fcb714a162a393029347b47f86va 代码进行了验证。基于此经历,本文将详细介绍 TDEngine 3.0 的安装与配置过程,集群的构建步骤,并附带简单Java连接示例。旨在一个经验积累以及为你提供参考和借鉴。

背景知识

在你继续阅读之前,你需要了解一些TDEngine的基础知识,比如物理节点(pnode),数据节点(dnode),虚拟节点(vnode),管理节点(mnode)等

可以看官方文档 /tdinternal/…

TDEngine简介

TDengine 是一款开源、高性能、云原生的时序数据库(Time Series Database,TSDB), 它专为物联网、车联网、工业互联网、金融、IT 运维等场景优化设计。同时它还带有内建的缓存、流式计算、数据订阅等系统功能,能大幅减少系统设计的复杂度,降低研发和运营成本,是一款极简的时序数据处理平台。

官网地址: 感兴趣的朋友可以上去看看

搭建TDEngine集群节点准备

准备3个CentOS节点

3个节点的/etc/hosts都添加以下内容

192.168.95.128 h1.taosdata.com
192.168.95.129 h2.taosdata.com
192.168.95.150 h3.taosdata.com

确保在任意一个节点上,都ping通其余两个节点

PING h3.taosdata.com (192.168.95.150) 56(84) bytes of data.
64 bytes from h3.taosdata.com (192.168.95.150): icmp_seq=1 ttl=64 time=1.33 ms
64 bytes from h3.taosdata.com (192.168.95.150): icmp_seq=2 ttl=64 time=1.35 ms
64 bytes from h3.taosdata.com (192.168.95.150): icmp_seq=3 ttl=64 time=1.08 ms
64 bytes from h3.taosdata.com (192.168.95.150): icmp_seq=4 ttl=64 time=0.840 ms

同时本地电脑也配置一下hosts,确保本地也能ping通3个CentOS节点

这里推荐一款Windows下方便编辑hosts的软件-SwitchHosts,记得使用管理员身份运行

TDEngine安装

这里使用原生安装的方式,获取TDEngine的TDengine-server-3.3.2.0-Linux-x64.tar.gz安装包,以及Windows客户端TDengine-client-3.3.2.0-Windows-x64.exe (因为我本地是Windows系统,到时候直接在本地运行Java程序进行连接)

/get-started…

吐槽: TDEngine下个软件安装包,都要留个邮箱,下载地址通过邮件发送邮箱...把邮箱留给你,你们好做下载量统计以及后续广告推广么

TDEngine安装

将TDengine-server-3.3.2.0-Linux-x64.tar.gz上传到CentOS节点目录下

进入到安装包所在目录,使用tar解压安装包

cd /usr/local/
tar -zxvf TDengine-server-3.3.2.0-Linux-x64.tar.gz

解压文件后,进入相应子目录,执行其中的install.sh安装脚本

cd TDengine-server-3.3.2.0
sudo ./install.sh

引用自官方: install.sh 安装脚本在执行过程中,会通过命令行交互界面询问一些配置信息。如果希望采取无交互安装方式,那么可以运行./install.sh -e no。运行./install.sh -h指令可以查看所有参数的详细说明信息

确认本节点的主机名或IP地址,因为之前配置过了hosts,TDEngine安装时会自动识别出本机是、还是,回车继续

输入已有集群中任何一个可用节点的 FQDN,让安装的新节点加入集群

注意:这里如果是安装第一个TDEngine节点,不需要输入任何内容,直接按回车即可。只有在安装第二、三个TDEngine节点时,才需要输入已有集群可用节点的FQDN,比如安装TDEngine节点2时,输入:6030。或者不输入也可以,后续在TDEngine节点启动前修改该节点的配置文件即可

输入邮箱以获得支持,直接回车跳过,继续安装

TDEngine启动前准备

安装完毕后,先别着急启动,检查所有节点的TDEngine配置文件

vim /etc/taos/taos.cfg

节点1

# firstEp 是每个 dnode 首次启动后连接的第 1 个 dnode
firstEp                   h1.taosdata.com:6030
# 必须配置为本 dnode 的 FQDN,如果本机只有一个 hostname,可注释或删除如下这行代码
fqdn                      h1.taosdata.com

节点2

# firstEp 是每个 dnode 首次启动后连接的第 1 个 dnode
firstEp                   h1.taosdata.com:6030
# 必须配置为本 dnode 的 FQDN,如果本机只有一个 hostname,可注释或删除如下这行代码
fqdn                      h2.taosdata.com

节点3

# firstEp 是每个 dnode 首次启动后连接的第 1 个 dnode
firstEp                   h1.taosdata.com:6030
# 必须配置为本 dnode 的 FQDN,如果本机只有一个 hostname,可注释或删除如下这行代码
fqdn                      h3.taosdata.com

所有TDEngine节点firstEp配置都要保持一致,这里配置为:6030,即所有节点启动时都把节点1作为首次连接的第一个dnode

fqdn则为各自的hostname即可

TDEngine启动

分别启动3个节点的TDEngine

systemctl start taosd

登录节点1,启动CLI

taos

查看当前集群所有节点信息

可以看到集群目前只有节点1这个TDEngine,地址为:6030,即新建集群的 first Ep

TDEngine集群添加节点

在节点1启动TDEngine CLI, 将节点2添加到当前集群

TDEngine3.0集群搭建大冒险_TDEngine3.0集群搭建大冒险_

create dnode "h2.taosdata.com:6030"

再次查看当前集群节点

show dnodes;

可以看到节点2顺利加入集群,节点3也是用同样的方式添加进来即可

注意: 添加节点后如果该节点status为offline,可以关闭节点所在的防火墙试试,或者防火墙开放相应端口,同时节点机器时间也要保持同步

TDEngine集群添加mnode

根据官方的说法,目前集群仅有1个mnode,即节点1,还无法实现高可用性,那么我们需要继续创建mnode

在创建 TDengine 集群时,首个 dnode 将自动成为集群的 mnode,负责集群的管理和协调工作。为了实现 mnode 的高可用性,后续添加的 dnode 需要手动创建 mnode。请注意,一个集群最多允许创建 3 个 mnode,且每个 dnode 上只能创建一个 mnode。当集群中的 dnode 数量达到或超过 3 个时,你可以为现有集群创建 mnode。

继续登录CLI,执行以下命令, 把节点2作为新的mnode并添加

create mnode on dnode 2

运行以下名称查看当前集群所有mnode

show mnodes;

集群搭建参考文档: /operation/d…

TDEngine测试

创建一个business数据库

CREATE DATABASE business PRECISION 'ms' KEEP 3650 DURATION 10 BUFFER 16;

切换到该数据库

use business;

创建一张普通表sys_user

CREATE TABLE sys_user(ts timestamp, user_id varchar(64), name varchar(10) );

添加一条记录

insert into sys_user(ts, user_id, name) values (now, '1', 'bruse');

节点1查询

节点2查询

节点3查询

可以看出,我们在集群任一节点建表,对数据增删改,剩余的节点也会及时同步变更。集群数据同步是正常的。

Java连接TDEngine集群安装TDEngine-Client

双击并运行之前下载好的TDengine-client-3.3.2.0-Windows-x64.exe,等待完成安装。安装的时候最好关闭杀毒软件,我安装时卡巴斯基不停报警。。。

TDEngine-Cli安装路径在 C:\TDengine,安装完编辑配置文件C:\TDengine\cfg\taos.cfg

# 和前面一样,配置firstEp为节点1
firstEp                   h1.taosdata.com:6030
# 同时设置secondEp为节点2
secondEp                  h2.taosdata.com:6030

运行C:\TDengine\taos.exe验证

添加pom依赖

在项目pom.xml中添加TDEngine依赖和HikariCP连接池


<dependency>
    <groupId>com.taosdata.jdbcgroupId>
    <artifactId>taos-jdbcdriverartifactId>
    <version>3.3.2version>
dependency>

<dependency>
    <groupId>com.zaxxergroupId>
    <artifactId>HikariCPartifactId>
dependency>

使用连接池的好处包括但不限于可以重用已有的数据库连接,减少了每次请求创建和销毁连接的开销

配置连接池

// 关键代码
private HikariDataSource taosDataSourceCluster() throws Exception {
        Class.forName("com.taosdata.jdbc.TSDBDriver");
        HikariConfig config = new HikariConfig();
        // 这里不特别指定hostname和port
        config.setJdbcUrl("jdbc:TAOS://:/");
        // TDEngine默认的账户和密码
        config.setUsername("root");
        config.setPassword("taosdata");
        // 更多配置自行设置
        return new HikariDataSource(config);
    }

在连接池配置时,不特别指定JDBC所连接的hostname和port,那么jdbc会使用客户端的配置文件,建立连接。如果firstEp节点不行,则尝试secondEp节点,只要保证 firstEp 和 secondEp 中一个节点有效,就可以正常建立到集群的连接。

代码编写

抽象一个执行TDEngine业务逻辑的接口

/**
 * 抽象出TDEngine执行的业务逻辑
 *
 */
@FunctionalInterface
public interface TDExecutable {
    /**
     * 执行TDEngine具体业务逻辑
     *
     * @param statement {@link Statement}
     */
    void execute(Statement statement) throws Exception;
}

写一个简单的TDEngine操作类

@Slf4j
@AllArgsConstructor
public class TaosService {
    /**
     * 连接池
     */
    private HikariDataSource ds;
    /**
     * 获取TD连接
     */
    private Connection getConnection() throws RuntimeException {
        try {
            return this.ds.getConnection();
        } catch (Exception e) {
            log.error("{}: {}", TaosError.GET_CONNECTION_ERR.getMsg(), e.getMessage(), e);
            throw new TaosException(e);
        }
    }
    /**
     * 执行任务
     *
     * @param executable {@link TDExecutable}
     */
    public void execute(TDExecutable executable) {
        Connection connection = this.getConnection();
        try (Statement statement = connection.createStatement()) {
            // 执行业务方具体逻辑
            executable.execute(statement);
        } catch (SQLException e) {
            log.error("errCode: {} errMsg: {}", e.getErrorCode(), e.getMessage());
            throw new TaosException(e);
        } catch (Exception e) {
            log.error("{}: {}", TaosError.EXECUTE_ERROR.getMsg(), e.getMessage(), e);
            throw new TaosException(e);
        } finally {
            // 释放连接
            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException e) {
                    log.error("{}:{}", TaosError.CLOSE_CONNECTION_ERR.getMsg(), e.getMessage(), e);
                }
            }
        }
    }
}

写一个简单查询

this.taosService.execute((statement -> {
    ResultSet resultSet = statement.executeQuery("select * from business.sys_user limit 1");
    while (resultSet.next()) {
        log.info("user Id:{} user Name:{}", resultSet.getString("user_id"), resultSet.getString("name"));
    }
}));

输出结果正确

user Id:1 user Name:bruse

当然,更好的方式是使用一些数据访问框架进行TDEngine的CRUD,比如 BeetlSQL3

总结

其实我本人对TDEngine并不太感冒,多年开发生涯中也只在一家做物联网的公司使用到了TDEngine。对于集群连接模式感觉是有种不太自然,不需要特别指定hostname和port可以理解,但是要保证firstEp和secondEp两个至少一个可用,这一点就难受了。

假设当前集群有6个节点加入,firstEp为节点1,secondEp为节点2,假设非常不巧节点1和节点2都挂了,那还剩下节点3~6可用,这种情况下难道我要修改客户端taos.cfg,把firstEp和secondEp修改为剩下的可用节点,并重启程序么...(有经历过的同学也可以留言告诉我哈哈)