TDengine 线程模型 — 网络、调度、执行

TDengine 线程模型 --- 网络、调度、执行

分类 :17.内部机制 | 篇章 :02 线程模型

免费详情

TDengine 是高并发系统,线程模型直接影响吞吐和延迟。本文从原理角度介绍各类线程池和调度机制。

线程池速查表

线程池 数量参数 用途
RPC 线程 numOfRpcThreads 网络收发
Query 线程 numOfTaskQueueThreads 查询执行
Commit 线程 numOfCommitThreads 写入落盘
Sync 线程 内部 RAFT 同步
Stream 线程 内部 流计算
Mgmt 线程 内部 管理操作

详细解析

1. 整体线程架构

复制代码
┌──────────────────────────────────────┐
│         网络 I/O 线程池              │
│   - 异步 epoll                        │
│   - 解码 RPC 消息                     │
│   - 路由到对应队列                    │
└──────────────────────────────────────┘
          │
          ▼
┌──────────────────────────────────────┐
│         任务调度层                    │
│   - 按 VGroup 分队列                  │
│   - 按优先级排序                      │
│   - 防止单查询阻塞                    │
└──────────────────────────────────────┘
          │
          ├──→ 写入执行线程
          ├──→ 查询执行线程
          ├──→ 提交线程
          └──→ 同步线程


设计原则:
  - I/O 与 CPU 分离
  - 任务队列解耦
  - 避免单线程瓶颈
  - 优先级保证关键路径

2. 网络 I/O 线程

复制代码
原理:

  ① 启动时根据 numOfRpcThreads 创建
  ② 每个线程一个 epoll 实例
  ③ 连接均衡分配到各线程
  ④ 异步 read/write
  ⑤ 数据完整后投递任务


线程职责:
  - accept 连接
  - 接收 RPC 包
  - 解码包头
  - 解压数据
  - 投递到任务队列
  - 异步回发响应


配置:
  numOfRpcThreads = CPU 核数 × 0.5 ~ 1
  典型:8~16
  
  
设计要点:
  - 不做重计算
  - 不阻塞磁盘 IO
  - 快进快出

3. 查询执行线程

复制代码
原理:

  ① numOfTaskQueueThreads 控制
  ② 工作线程池
  ③ 从任务队列拉取查询任务
  ④ 执行算子(扫描/过滤/聚合)
  ⑤ 结果发回客户端


算子级并发:
  - 单查询拆为多 Task
  - 不同 VGroup 并行
  - 同 VGroup 内可分块并行


调度策略:
  - 时间片轮转
  - 优先级(短查询优先)
  - 防止饥饿


QNode(独立查询节点):
  - queryPolicy=2/3 时启用
  - 大查询从 VNode 卸载到 QNode
  - VNode 专注写入与小查询

4. 提交(Commit)线程

复制代码
原理:

  ① 内存表达到阈值
  ② 切换内存表
  ③ Commit 线程异步处理:
     a. 数据排序
     b. 列存编码 + 压缩
     c. 写入数据块文件
     d. 更新索引
     e. 清理 WAL


线程池:
  numOfCommitThreads 控制
  典型:4~8
  
  
设计要点:
  - 不阻塞写入主路径
  - 多 VGroup 并行
  - I/O 调度避免拥塞
  
  
背压:
  - Commit 跟不上 → 内存表堆积
  - 触发写入限流
  - 保护系统稳定

5. 同步(Sync)线程

复制代码
RAFT 同步线程:

  ① 内部线程组
  ② Leader 复制日志到 Follower
  ③ Follower 接收、写盘、确认
  ④ Leader 收到 majority 确认 → 提交


线程类型:
  - 发送线程:发送 AppendEntries
  - 接收线程:处理回复
  - 应用线程:将已提交日志应用到状态机
  - 心跳线程:维持 Leader 角色


设计要点:
  - 与业务线程隔离
  - 高优先级
  - 网络异常处理
  - 选举超时控制

6. 流计算线程

复制代码
Stream 执行:

  ① 流任务调度器
  ② Source 线程:订阅源数据
  ③ Computing 线程:窗口计算
  ④ Sink 线程:写入目标表


与查询共享或独立?
  - 默认共享查询线程池
  - 大量流可独立线程池
  - 防止流计算影响查询


检查点线程:
  - 定期触发 CheckPoint
  - 持久化流状态

7. 任务队列

复制代码
队列设计:

  ① 多级队列:
     - 高优先级(管理/心跳)
     - 普通优先级(查询/写入)
     - 后台优先级(合并/清理)

  ② 按 VGroup 分区:
     - 每 VGroup 独立队列
     - 单 VGroup 串行
     - 多 VGroup 并行

  ③ 限流:
     - 队列长度上限
     - 满则返回繁忙


调度算法:
  - Round Robin
  - 优先级 + 公平
  - 防饥饿


典型场景:
  - 一个慢查询不影响其他
  - 写入优先级 < 读
  - 心跳永不阻塞

8. 性能调优

复制代码
调优原则:

  ① 线程数 ≤ CPU 核数 × 2
     - 避免上下文切换开销
     - I/O 类可适当多
     
  ② numOfRpcThreads:
     - 高并发场景:核数
     - 一般:核数 / 2
     
  ③ numOfTaskQueueThreads:
     - 查询密集:核数 × 1.5
     - 写入密集:核数
     
  ④ numOfCommitThreads:
     - 多盘 I/O:4~8
     - 单盘:2~4


监控指标:
  - 队列长度
  - 线程繁忙率
  - 上下文切换
  - CPU 利用率


瓶颈识别:
  - RPC 队列堆积 → 加 RPC 线程
  - Task 队列堆积 → 加 Task 线程或拆 VGroup
  - Commit 慢 → 加 Commit 线程或 SSD

代码示例

配置线程参数

cfg 复制代码
# /etc/taos/taos.cfg

# 网络
numOfRpcSessions       30000
numOfRpcThreads        16     # 16 核机器,全用

# 查询
numOfTaskQueueThreads  16
queryPolicy            2      # 用 qnode

# 写入
numOfCommitThreads     8

# 流计算
streamMaxThreads       4

监控线程使用

sql 复制代码
-- 系统资源(看 CPU 利用率反映线程使用)
SELECT endpoint, cpu_usage 
FROM log.taosd_dnodes_info 
WHERE ts > NOW - 5m;


-- 查询并发
SELECT COUNT(*) AS active_queries 
FROM performance_schema.perf_queries;


-- 慢查询(占用线程时间)
SELECT user, exec_usec/1000 AS ms, sql 
FROM performance_schema.perf_queries 
ORDER BY exec_usec DESC LIMIT 10;

调优案例

复制代码
案例:写入吞吐不达预期

诊断:
  iostat -x 1   # 磁盘 OK
  top           # CPU 利用率 70%
  
  taos -s "SELECT * FROM log.taosd_dnodes_info"
  # 看 commit 是否堆积

发现:commit 单线程
措施:
  ALTER ALL DNODES 'numOfCommitThreads' '8';
  
结果:吞吐提升 2x


案例:查询请求 timeout

诊断:
  - 看 active_queries 是否爆满
  - 看慢查询列表

发现:大查询阻塞队列
措施:
  - queryPolicy=2 用 qnode
  - 大查询用专用账号
  
结果:小查询不再受影响

性能考量

线程开销

项 开销
单线程内存栈 ~ 1 MB
上下文切换 ~ 微秒级
锁竞争 视并发

线程数推荐

角色 数量公式
RPC 核数 × 1
Task 核数 × 1~1.5
Commit 4~8
Stream 视流数量

FAQ

Q1: 线程越多越好吗?

不是。超过 CPU 核数过多反而损耗(切换开销)。

Q2: 为什么 CPU 没满写入还慢?

可能:

  • I/O 瓶颈(磁盘)
  • 锁竞争
  • 网络瓶颈
  • 客户端不并发

Q3: 怎么看是否需要 QNode?

  • 大查询阻塞小查询 → 用 QNode
  • 查询和写入互相影响 → 用 QNode

Q4: 流计算占用太多 CPU?

  • 限制流数量
  • 减少 trigger 频率
  • 增加节点

Q5: 单查询能用多核吗?

可以。算子级并行(不同 VGroup 并行扫描)。

参考

系统构架篇

数据模型

存储引擎

查询引擎

数据写入

数据订阅

预聚合

索引

SQL 语句

客户端与连接器

运维

安全

生态

应用案例

产品对比

内部机制

关于 TDengine

TDengine 专为物联网IoT平台、工业大数据平台设计。其中,TDengine TSDB 是一款高性能、分布式的时序数据库(Time Series Database),同时它还带有内建的缓存、流式计算、数据订阅等系统功能;TDengine IDMP 是一款AI原生工业数据管理平台,它通过树状层次结构建立数据目录,对数据进行标准化、情景化,并通过 AI 提供实时分析、可视化、事件管理与报警等功能。

相关推荐
AI你一生一世15 分钟前
不止于时序存储:DolphinDB 如何成为 AI 时代的工业智能底座
java·人工智能·struts·时序数据库·工业智能·dolphindb·ai基础设施
ss27342 分钟前
为什么PostgreSQL适合AI场景?
数据库·人工智能·postgresql
瑞克-桑切斯1 小时前
7、MySQL 慢查询排查与优化实战指南
java·服务器·数据库
honsor1 小时前
SNMP 读取以太网温湿度传感器数据,监控平台对接实操
物联网·网络协议·tcp/ip
全栈陈序员1 小时前
【Git】从入门到精通(五)—— git add:将文件加入暂存区
大数据·git·elasticsearch
z06.2 小时前
MySQL索引
数据库·mysql
考虑考虑2 小时前
Posrgresql恢复.backup文件
数据库·后端·postgresql
云祺vinchin2 小时前
中小企业备份软件选型从恢复需求到总体成本评估
数据库·数据备份·中小企业备份·容灾备份软件
Zenova EdgeOS2 小时前
Go 工业边缘错误处理实战:用 errors 构建可追溯错误链
开发语言·数据库·golang
KKKlucifer2 小时前
国内数据安全服务的产品智能化转型:大模型赋能下的技术能力重构分析
大数据·数据库·重构