高可用改造之构建双活冗余的TDengine时序数据处理架构

发布于:2025-08-07 ⋅ 阅读:(15) ⋅ 点赞:(0)

一、背景说明

此前,相关系统曾遭遇数据丢失事故,本方案旨在提升系统可用性,以规避类似风险。然而,该业务系统存在以下特殊性,构成了方案设计的核心约束:

  • 服务器资源严格受限: 无法部署标准的 TDengine 生产级集群(最小要求为 3 Management Node + 2 Data Node,共计 5 节点)。资源投入必须高度精简。
  • 应用层改造成本敏感: 期望避免为达成高可用目标而对应用层进行大规模的、侵入式的改造,需尽可能降低适配成本。
  • 超级表管理方式特定: 当前超级表 (STable) 采用手动维护策略。这意味着可以暂时搁置跨节点数据实时复制的需求,方案的核心目标简化为保障现有存量表结构的可靠同步。
  • 故障恢复时效性要求高: 对数据库服务故障转移 (Failover) 后的恢复时间 (RTO) 非常敏感,需最大限度减少业务中断时间。

二、方案设计

逻辑简图如下:
在这里插入图片描述
本方案构建一个双活冗余的高可用时序数据处理架构,通过主备两套独立的数据链路(数据写入服务→TDengine时序库)实现全链路冗余,最终汇聚至统一的 Tengine(淘宝开源)代理服务;

该代理服务集成健康监控与自动故障转移能力,实时检测数据库状态,在主库故障时无缝切换至备库,恢复后自动回切,使业务应用通过单一访问点获得持续可靠的数据服务,确保系统具备故障自愈能力与业务连续性保障。

主要使用的组件:

  • Tengine:代理服务,Tengine是淘宝网发起的Web服务器项目,基于Nginx优化,用于高并发场景。
  • TDengine:时序数据库:TDengine是涛思数据开发的​​高性能、分布式、支持SQL的时序数据库​​,专为物联网、工业互联网等场景设计。

三、安装部署

操作系统版本:Ubuntu 24.04.2 LTS

3.1 TDengine 备库安装

版本最好保持与主库一致,尽量减少数据一致性兼容问题。

具体步骤参考官方文档:

3.2 Tengine代理服务安装

下载文件:

 wget https://tengine.taobao.org/download/tengine-2.4.1.tar.gz
 tar -zxvf tengine-2.4.1.tar.gz

安装依赖库:

 sudo apt update
 sudo apt install g++ -y
 sudo apt install libpcre3 libpcre3-dev -y
 sudo apt install openssl libssl-dev -y
 sudo apt install zlib1g zlib1g-dev -y
 sudo apt make -y

编译安装:

cd tengine-2.4.1

sudo ./configure \
--prefix=/usr/local/src/tengine \
--without-http_upstream_keepalive_module \
--with-http_ssl_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_sub_module \
--with-http_dav_module \
--with-http_flv_module \
--with-http_mp4_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_random_index_module \
--with-http_secure_link_module \
--with-http_stub_status_module \
--with-http_auth_request_module \
--with-threads --with-stream \
--with-stream_ssl_module \
--with-http_slice_module \
--with-file-aio \
--with-http_v2_module \
--add-module=modules/ngx_backtrace_module \
--add-module=modules/ngx_debug_pool \
--add-module=modules/ngx_debug_timer \
--add-module=modules/ngx_http_concat_module \
--add-module=modules/ngx_http_footer_filter_module \
--add-module=modules/ngx_http_proxy_connect_module \
--add-module=modules/ngx_http_reqstat_module \
--add-module=modules/ngx_http_slice_module \
--add-module=modules/ngx_http_sysguard_module \
--add-module=modules/ngx_http_trim_filter_module \
--add-module=modules/ngx_http_upstream_check_module \
--add-module=modules/ngx_http_upstream_consistent_hash_module \
--add-module=modules/ngx_http_upstream_dynamic_module \
--add-module=modules/ngx_http_upstream_dyups_module \
--add-module=modules/ngx_http_upstream_keepalive_module \
--add-module=modules/ngx_http_upstream_session_sticky_module \
--add-module=modules/ngx_http_user_agent_module \
--with-compat
   
sudo make  
sudo make install

安装完成后,Tengine 的文件结构如下:​​

  • 二进制文件:/usr/local/src/tengine/sbin/nginx
  • 配置文件:/usr/local/src/tengine/conf/nginx.conf
  • 日志目录:/usr/local/src/tengine/logs/
  • 模块目录:/usr/local/src/tengine/modules/

验证 Tengine 是否安装成功​:

# 查看版本
$ sudo ./nginx -v
Tengine version: Tengine/3.1.0
nginx version: nginx/1.24.0

# 查看编译时启用的模块
$ sudo ./nginx -V
Tengine version: Tengine/3.1.0
nginx version: nginx/1.24.0
built by gcc 13.3.0 (Ubuntu 13.3.0-6ubuntu2~24.04) 
built with OpenSSL 3.0.13 30 Jan 2024
TLS SNI support enabled
configure arguments: --prefix=/usr/local/src/tengine --without-http_upstream_keepalive_module --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module --with-threads --with-stream --with-stream_ssl_module --with-http_slice_module --with-file-aio --with-http_v2_module --add-module=modules/ngx_backtrace_module --add-module=modules/ngx_debug_pool --add-module=modules/ngx_debug_timer --add-module=modules/ngx_http_concat_module --add-module=modules/ngx_http_footer_filter_module --add-module=modules/ngx_http_proxy_connect_module --add-module=modules/ngx_http_reqstat_module --add-module=modules/ngx_http_slice_module --add-module=modules/ngx_http_sysguard_module --add-module=modules/ngx_http_trim_filter_module --add-module=modules/ngx_http_upstream_check_module --add-module=modules/ngx_http_upstream_consistent_hash_module --add-module=modules/ngx_http_upstream_dynamic_module --add-module=modules/ngx_http_upstream_dyups_module --add-module=modules/ngx_http_upstream_keepalive_module --add-module=modules/ngx_http_upstream_session_sticky_module --add-module=modules/ngx_http_user_agent_module --with-compat

启动 Tengine​:

# 启动 Tengine
sudo /usr/local/src/tengine/sbin/nginx

# 检查是否运行
ps aux | grep nginx

四、初始化配置

4.1 TDengine

4.1.1 备库同步表结构

TDengine 提供的数据备份、恢复工具 — taosdump。

主库导出数据(按天导出数据):

taosdump -h localhost -P 6030 -o /file/path -D dbname -S '2024-12-17 00:00:00' -E '2024-12-18 00:00:00' 

执行上述命令后,taosdump 会连接 localhost:6030 所在的 TDengine 集群,查询数据库 dbname 中的所有数据,并将数据备份到 /file/path 下。

# 备库恢复数据
taosdump -i /file/path -h localhost -P 6030

执行上述命令后,taosdump 会连接 localhost:6030 所在的 TDengine 集群,并将 /file/path 下的数据文件恢复到 TDengine 集群中。

4.1.2 备库同步用户

1.备库创建与主库在用的相同的用户,保持账号密码一致。
2.主库和备库均创一个相同的最小权限的只读用户,方便后续代理监测数据库状态使用。

用户和权限管理参考官方文档:

4.2 Tengine

根据之前的需求,需要配置 Tengine 作为 TDengine 的 HTTP API 代理,并实现高可用故障转移。

4.2.1 创建自定义配置文件

避免覆盖默认配置

sudo mkdir -p /usr/local/src/tengine/conf/conf.d
sudo nano /usr/local/src/tengine/conf/conf.d/tdengine.conf

4.2.2 写入 TDengine 代理配置​

编辑tdengine-proxy.conf配置文件:

# =============================================
# 动态 Upstream 配置:定义 TDengine 后端服务器组
# =============================================

upstream tdengine_servers {

    # 主要后端服务器:192.168.3.55,监听 6041 端口(TDengine 的 HTTP API / REST 接口)
    # max_fails=3:如果连续 3 次请求失败,则标记此节点为不可用
    # fail_timeout=30s:在 30 秒内失败达到 max_fails 次数后,该节点会被暂时剔除,30 秒后可能重新尝试恢复
    server 192.168.3.55:6041 max_fails=3 fail_timeout=30s;

    # 备用服务器:192.168.3.30,仅当所有非 backup 的服务器都不可用时,才会将请求转发至此
    server 192.168.3.30:6041 backup;

    # -------------------------------
    # Tengine 健康检查模块配置(关键)
    # 注意:此功能是 Tengine 特有,原生 Nginx 不支持
    # -------------------------------

    # 健康检查配置
    check interval=5000            # 每隔 5000 毫秒(即 5 秒)对后端发起一次健康检查
           timeout=10000           # 健康检查请求的超时时间为 10 秒
           rise=2                  # 连续 2 次检查成功,标记节点为健康
           fall=2                  # 连续 2 次检查失败,标记节点为不健康
           type=http               # 健康检查类型为 HTTP(适用于 TDengine 的 /rest/sql 接口)
           port=6041;              # 检查的端口,必须与后端服务端口一致

    # 健康检查发送的 HTTP 请求报文(模拟一次 SQL 查询,检测服务是否存活)
    # 这是一个标准的 POST 请求,访问 /rest/sql 接口,执行 "select 1;" 语句
    check_http_send "POST /rest/sql HTTP/1.1\r\nHost: $host\r\nAuthorization: Basic cm9vdDp0YW9zZGF0YQ==\r\nContent-Type: text/plain\r\nContent-Length: 9\r\n\r\nselect 1;";

    # 健康检查响应校验:只检查 HTTP 响应状态码是否为 2xx (即请求是否成功返回)
    # 如果希望更严格,可以进一步校验返回的 JSON 中的 code 是否为 0(需要 Tengine 支持更高级匹配,如 json 匹配)
    check_http_expect_alive http_2xx;

    # 注意:下面这行是注释掉的,因为 Tengine 默认可能不支持直接匹配 JSON 字段(如 {"code":0})
    # 如果你的 Tengine 支持高级健康检查匹配(如 json 匹配模块),可以取消注释并配置:
    # check_http_match json:{"code":0};

    # 会话保持策略:使用 ip_hash,确保同一个客户端的请求始终落到同一台后端服务器
    # 适用于需要“有状态”访问的场景,比如避免频繁切换导致会话或缓存不一致
    ip_hash;
}

# =============================================
# Server 块:监听 6041 端口,接收客户端请求并代理到上游的 TDengine 服务器
# =============================================

server {
    # 监听 6041 端口(与 TDengine 的 HTTP API 端口一致)
    listen 6041;

    # -------------------------------
    # 反向代理核心配置
    # -------------------------------

    location / {
        # 将请求反向代理到上面定义的 tdengine_servers upstream 组
        proxy_pass http://tdengine_servers;

        # 代理协议相关头部设置(确保后端能获取到真实的客户端信息)
        proxy_http_version 1.1;                    # 使用 HTTP/1.1 协议(支持长连接等特性)
        proxy_set_header Host $host;               # 设置请求的 Host 头
        proxy_set_header X-Real-IP $remote_addr;   # 记录客户端真实 IP
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  # 记录经过的代理 IP 链
        proxy_set_header Upgrade $http_upgrade;    # 支持 WebSocket 等升级协议
        proxy_set_header Connection $http_connection;

        # -------------------------------
        # 超时控制(根据业务需求调整)
        # -------------------------------
        proxy_read_timeout 600s;     # 读取后端响应的超时时间(600 秒,适合复杂查询)
        proxy_send_timeout 600s;     # 发送请求到后端的超时时间
        proxy_connect_timeout 600s;  # 与后端建立连接的超时时间

        # -------------------------------
        # 故障转移相关配置
        # -------------------------------
        proxy_next_upstream error timeout http_500 http_502 http_503 http_504 non_idempotent;
        # 如果出现以下错误,尝试自动切换到下一个可用的 upstream 服务器:
        # - error:连接失败等底层错误
        # - timeout:请求超时
        # - http_500 / 502 / 503 / 504:后端返回这些 HTTP 错误码
        # - non_idempotent:允许对非幂等请求(如 POST)也进行重试(谨慎使用)

        proxy_next_upstream_timeout 10;  # 故障转移时,最多等待 10 秒尝试下一个节点
        proxy_next_upstream_tries 3;     # 最多尝试 3 次(包括首次)
    }

    # =========================================
    # 健康检查状态页(Tengine 提供)
    # 访问 /status 可以查看 upstream 各节点的健康状态
    # =========================================

    location /status {
        # 启用 Tengine 的健康检查状态监控页面
        check_status;
        access_log off;  # 关闭该页面的访问日志(避免日志过大)
    }

    # =========================================
    # 默认访问页面(可选)
    # 访问根路径 / 返回一个简单的文本提示
    # =========================================

    location = / {
        return 200 'Tengine TDengine Proxy is operational\n';
        add_header Content-Type text/plain;
    }
}

注意:

  • Authorization: Basic cm9vdDp0YW9zZGF0YQ== 是 root:taosdata 的 Base64 编码,请确保 TDengine 监测用户权限配置正确。如果你修改了 TDengine 的用户名或密码,需要同步更新这里的 Authorization 头。
  • ​​/status 页面访问控制​​:目前 /status 是开放的,生产环境中建议增加访问限制(如 IP 白名单、Basic Auth 等),避免泄露后端状态信息。
  • 超时与重试参数调优:根据你的业务场景(如查询复杂度、网络延迟等),可以适当调整 proxy_read_timeout、proxy_next_upstream_timeout 等参数。
  • 日志与监控:建议开启 Tengine 的 access 日志(或部分路径的日志),便于排查问题。可通过 /status 页面实时查看 upstream 各节点健康状态,实现快速故障定位。

编辑主配置文件nginx.conf:

# =============================================
# Tengine 或 Nginx 主配置文件
# 通常文件名为 nginx.conf 或 tengine.conf
# 此配置为服务的基础配置,包含全局运行参数、事件模型、HTTP 服务定义等
# =============================================

# -------------------------------
# 运行用户配置(通常注释掉,使用默认用户,如 nobody 或 nginx)
# -------------------------------
#user  nobody;
# 如果你希望 Tengine/Nginx 以特定系统用户身份运行(如 nginx、tengine),可以取消注释并指定,例如:
# user  nginx;
# user  tengine;
# 默认情况下,Tengine/Nginx 通常以 nobody 或编译时指定的用户运行。

# -------------------------------
# 工作进程数配置:自动根据 CPU 核心数设置
# -------------------------------
worker_processes  auto;
# 定义 Tengine/Nginx 启动的工作进程数,通常设置为 auto 让其自动检测 CPU 核心数量并启动对应进程数,
# 也可以手动指定,例如:worker_processes  4;

# -------------------------------
# 错误日志配置
# -------------------------------
error_log  logs/error.log;
# 定义错误日志的存储路径,这里为相对路径 logs/error.log(相对于 Tengine/Nginx 的安装目录或 prefix 路径)
# 错误日志用于记录服务运行过程中的错误、警告等信息,是排查问题的重要依据

# 可选:你可以取消注释下面的某一行,调整错误日志的记录级别:
# #error_log  logs/error.log  notice;   # 记录 notice 级别及以上的日志信息
# #error_log  logs/error.log  info;     # 记录 info 级别及以上的日志信息

# 另外,你也可以将错误日志输出到管道,进行日志切割和归档(当前是注释掉的):
# #error_log  "pipe:rollback logs/error_log interval=1d baknum=7 maxsize=2G";

# -------------------------------
# 进程 PID 文件(记录主进程 ID,默认注释掉,通常位于 logs/nginx.pid)
# -------------------------------
#pid        logs/nginx.pid;
# 定义存储 Tengine/Nginx 主进程 PID 的文件路径,用于管理进程(如启动、停止、重载配置)
# 默认情况下通常位于 logs/nginx.pid,也可以自定义路径

# -------------------------------
# events 块:定义与连接处理模型相关的参数
# -------------------------------
events {
    worker_connections  1024;
    # 每个工作进程允许的最大并发连接数,即每个工作进程可以同时处理 1024 个连接
    # 如果你的服务器并发访问量较高,可以适当调大此值,比如 2048、4096
    # 注意:总并发连接数 ≈ worker_processes × worker_connections
}

# -------------------------------
# http 块:定义 HTTP 服务的全局配置
# -------------------------------
http {
    include       mime.types;
    # 引入 MIME 类型定义文件,通常为 conf/mime.types
    # 该文件定义了各种文件扩展名对应的 Content-Type,例如 .html -> text/html, .jpg -> image/jpeg
    # 用于正确设置响应头中的 Content-Type 字段

    default_type  application/octet-stream;
    # 默认的 MIME 类型,当请求的文件类型未在 mime.types 中匹配时,使用此默认类型
    # application/octet-stream 表示二进制流,通常用于文件下载

    # -------------------------------
    # 日志格式定义(当前被注释,未启用)
    # -------------------------------
    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';
    # 定义一个名为 main 的日志格式,包含客户端 IP、时间、请求内容、状态码、响应大小、来源页、用户代理等信息
    # 可用于 access_log 记录详细的访问日志

    # -------------------------------
    # 访问日志配置(当前被注释,未启用)
    # -------------------------------
    #access_log  logs/access.log  main;
    # 启用访问日志,并使用上面定义的 main 格式记录每个请求的详细信息

    # 可选:使用管道进行日志切割与归档(比如按天切割、限制大小等,当前注释掉):
    # #access_log  "pipe:rollback logs/access_log interval=1d baknum=7 maxsize=2G"  main;

    # -------------------------------
    # 高性能传输相关配置
    # -------------------------------
    sendfile        on;
    # 启用 sendfile 零拷贝传输机制,提升静态文件(如图片、CSS、JS)的发送效率,减少用户态与内核态数据拷贝
    # 推荐开启,除非你的系统不支持

    #tcp_nopush     on;
    # 仅在 sendfile 开启时生效,用于优化数据包的发送策略,提高网络传输效率

    # -------------------------------
    # 长连接超时时间配置
    # -------------------------------
    #keepalive_timeout  0;
    keepalive_timeout  65;
    # 设置客户端与服务器之间的长连接保持时间,单位为秒
    # 即客户端在多长时间内没有新请求时,Tengine/Nginx 会主动关闭连接
    # 默认 65 秒是一个较为通用的设置,可根据业务需求调整

    # -------------------------------
    # gzip 压缩配置(当前注释掉,未启用)
    # -------------------------------
    #gzip  on;
    # 是否启用 gzip 压缩功能,开启后可以对响应内容(如 HTML/JSON/CSS/JS)进行压缩,减少传输数据量,提升加载速度
    # 如果需要启用,取消注释,并可进一步配置 gzip_types 等参数

    # -------------------------------
    # 引入自定义配置文件(模块化管理配置,推荐!)
    # -------------------------------
    include /usr/local/src/tengine/conf/conf.d/*.conf;
    # 引入 conf.d 目录下的所有 .conf 文件,常用于将不同功能模块(如 server 块、upstream 块、location 路由等)拆分到独立文件中管理
    # 推荐将不同虚拟主机、代理规则、静态资源目录等配置拆分到 conf.d/ 目录下,便于维护

    # -------------------------------
    # map 指令:动态变量映射(常用于协议升级,如 WebSocket)
    # -------------------------------
    map $http_upgrade $connection_upgrade {
        default upgrade;
        ''      close;
    }
    # 功能:根据客户端请求头中的 $http_upgrade 值动态设置变量 $connection_upgrade 的值
    # 应用场景:主要用于支持 WebSocket 协议或 HTTP 长连接升级
    # - 如果 $http_upgrade 有值(比如 "websocket"),则 $connection_upgrade = upgrade
    # - 如果为空,则 $connection_upgrade = close
    # 通常与 proxy_set_header 和 proxy_pass 配合使用,实现 WebSocket 代理

    # -------------------------------
    # server 块:定义一个监听 8088 端口的 HTTP 服务
    # -------------------------------
    server {
        listen       8088;
        # 监听本机 8088 端口,可以是 HTTP 默认端口 80、HTTPS 默认端口 443,或者自定义端口如 8088、8888 等
        # 该服务将响应发送到此端口上的 HTTP 请求

        server_name  localhost;
        # 定义该 server 块匹配的服务器名称(即域名),这里设置为 localhost
        # 通常用于开发环境,生产环境中应设置为你的实际域名,如 example.com 或 *.example.com
        # 你可以配置多个 server_name,支持基于域名的虚拟主机

        # =========================================
        # 此处通常会继续定义:
        # - location / {}           # 根路径的路由规则,比如反向代理、静态文件目录等
        # - proxy_pass              # 反向代理到后端服务
        # - root / alias            # 静态文件路径
        # - 其他 location 块
        # =========================================
        
       location / {
            root   html;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

4.2.3 测试验证

测试配置并重载 Tengine​:

# 测试配置语法是否正确
sudo /usr/local/src/tengine/sbin/nginx -t

# 重载配置(不中断服务)
sudo /usr/local/src/tengine/sbin/nginx -s reload

五、验证高可用功能

5.1 检查健康状态​

# 查看上游节点状态(需 Tengine 支持 status 模块)
curl "http://127.0.0.1/status/upstream?upstream=tdengine_backend"

输出应显示节点状态(up 或 down)。

5.2 模拟故障转移​

1.手动停止一台 TDengine 节点:

sudo systemctl stop taosd  # 假设 TDengine 通过 systemd 管理

2.观察 Tengine 日志:

tail -f /usr/local/src/tengine/logs/error.log

3.通过 /status 页面实时查看 upstream 各节点健康状态:
在这里插入图片描述

4.再次访问代理端口,验证请求是否自动切换到其他节点:

curl -u root:taosdata "http://127.0.0.1:6041/rest/sql?query=SELECT+1"

六、小结

本文通过构建​​双活冗余的高可用时序数据处理架构​​,通过以下核心组件实现全链路冗余与自动故障切换:

  • ​​双独立数据链路​​:业务数据写入服务分别连接主备两套TDengine时序库,形成双写冗余。
  • ​​统一代理入口​​:所有业务请求通过单一的Tengine代理服务访问数据库,代理层集成健康监控与自动故障转移能力。
  • ​​无缝故障切换​​:代理实时检测数据库状态,主库故障时自动切换至备库,主库恢复后支持自动回切,确保业务持续访问。

关键特性

  • ​​高可用保障​​:主备TDengine库互为冗余,结合代理层的健康检查与自动切换,避免单点故障导致的数据不可用。
  • ​​低改造成本​​:业务应用仅需连接统一的Tengine代理地址,无需感知底层主备库切换逻辑,无需大规模修改代码。
  • ​​存量表同步​​:聚焦存量表结构的可靠同步(手动维护超级表),暂不强制要求跨节点实时数据复制,降低复杂度。
  • ​​快速故障恢复​​:代理层实时监控数据库健康状态,故障转移响应迅速,满足高时效性的RTO要求。

核心组件

  • ​​Tengine​​:基于Nginx优化的代理服务,支持高并发场景,集成健康检查、负载均衡及自动故障转移功能,作为业务访问的唯一入口。
  • ​​TDengine​​:高性能时序数据库,负责存储和管理时序数据,主备库通过双写和代理切换实现冗余。

该方案通过“双写+统一代理+智能切换”的组合设计,在资源受限和应用低改造的前提下,有效解决了数据丢失风险,保障了系统的连续性与可靠性。


网站公告

今日签到

点亮在社区的每一天
去签到