TDengine 整体架构全景 — 深度解析

适用版本:TDengine v3.x(v3.3.x / v3.4.x) | 最后更新:2026-05-12
在这里插入图片描述

概述

TDengine 是一款专为时序数据场景设计的高性能分布式数据库。它不是在已有数据库上做的优化包装,而是从零开始自主研发的全栈时序数据处理平台,内置了数据库、缓存、流计算和数据订阅四大核心功能,一套系统即可替代传统方案中 Kafka + Redis + HBase + Flink 的复杂组合。

TDengine 的架构设计基于两个基本假设:

  1. 任何单台硬件/软件都不可靠——所以从第一天起就按分布式高可靠架构设计
  2. 任何单台计算机都无法处理海量数据——所以支持水平扩展,通过节点虚拟化和负载均衡高效利用异构集群资源

本文从进程层、逻辑层、通信层三个维度全面剖析 TDengine 的整体架构。

核心概念速查表

概念说明
dnode数据节点,taosd 进程在一台物理机上的一个运行实例,是部署和运维的最小单元
vnode虚拟节点,dnode 内部的逻辑存储单元,负责一部分表的时序数据存储和查询
vgroup虚拟节点组,由分布在不同 dnode 上的多个 vnode 组成,通过 Raft 协议保证高可用
mnode管理节点,负责集群元数据管理(用户/数据库/超级表/vgroup 分配等),最多 3 个
qnode计算节点,专门执行查询计算任务,实现存储与计算分离
snode流计算节点,专门处理流计算任务,实现流计算与批计算分离
bnode备份节点(仅企业版),用于 S3 或外部存储的数据备份
taosc客户端驱动,应用程序通过它与集群交互,负责路由、缓存和最后一级聚合
taosAdapterRESTful/WebSocket 网关,为不使用原生驱动的场景提供 HTTP 接口

详细架构解析

1. 进程架构:一个 taosd 进程,多种逻辑节点

TDengine 服务端只有一个进程——taosd。它不是单一功能的进程,而是一个节点容器,在一个进程内同时运行多种逻辑节点:

┌─────────────────────────────── taosd 进程 ──────────────────────────────┐
│                                                                          │
│  ┌──────────┐  ┌──────────┐  ┌────────┐  ┌────────┐  ┌────────┐        │
│  │  dnode    │  │  mnode   │  │ vnode  │  │ qnode  │  │ snode  │  ...   │
│  │  管理模块 │  │ (0或1个) │  │(0~N个) │  │(0或1个)│  │(0或1个)│        │
│  └──────────┘  └──────────┘  └────────┘  └────────┘  └────────┘        │
│                                                                          │
│  ┌────────────────────────────────────────────────────────────────┐      │
│  │                        RPC / Transport 层                      │      │
│  └────────────────────────────────────────────────────────────────┘      │
│                                                                          │
│  ┌────────────────────────────────────────────────────────────────┐      │
│  │                  TFS (分级文件系统)                             │      │
│  └────────────────────────────────────────────────────────────────┘      │
└──────────────────────────────────────────────────────────────────────────┘

关键设计:每个 dnode 上,mnode/qnode/snode 最多各一个;vnode 可以有多个(取决于硬件资源和数据库分片数)。哪些节点在哪些 dnode 上运行,由 mnode 统一管理和调度。

1.1 taosd 启动流程

taosd 启动时按以下顺序初始化:

  1. 解析命令行参数——读取配置文件路径、数据目录等
  2. 初始化基础设施——日志系统、信号处理、分级文件系统(TFS)
  3. 创建 dnode 管理对象——为所有支持的节点类型(dnode/mnode/vnode/qnode/snode/bnode/xnode)注册生命周期管理函数
  4. 判断本节点需要运行哪些逻辑节点——根据配置和集群状态决定
  5. 逐个打开各节点——每种节点执行自己的初始化逻辑(例如 vnode 会从磁盘恢复所有 vgroup)
  6. 逐个启动各节点——打开 RPC 端口,开始接受请求
  7. 主循环等待退出信号——收到 SIGTERM/SIGINT 后按反向顺序关闭所有节点

taosd 内部维护一个 7 槽位的节点管理数组,每个槽位对应一种节点类型(dnode 自身、mnode、vnode、qnode、snode、bnode、xnode),为每种节点类型提供统一的 open/close/start/stop 生命周期接口。

2. VNode:数据存储的核心单元

VNode 是 TDengine 中最重要的逻辑概念——它是数据存储、查询和复制的基本单元

2.1 VNode 内部模块

每个 VNode 内部包含 5 个核心子模块,各司其职:

┌─────────────────── VNode (vgId=2) ────────────────────┐
│                                                         │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐  ┌──────────┐ │
│  │  META   │  │  TSDB   │  │  WAL    │  │   TQ     │ │
│  │ 元数据   │  │ 时序数据 │  │ 预写日志 │  │ 消息队列 │ │
│  │ (B+Tree) │ │ (LSM)   │  │         │  │ (订阅)   │ │
│  └─────────┘  └─────────┘  └─────────┘  └──────────┘ │
│                                                         │
│  ┌──────────┐  ┌──────────────────┐                    │
│  │   SMA    │  │   Buffer Pool    │                    │
│  │ 预聚合    │  │ (3段内存池)       │                    │
│  └──────────┘  └──────────────────┘                    │
│                                                         │
│  ┌──────────────────────────────────────────────┐      │
│  │              Raft Sync 模块                    │      │
│  │  (Leader 选举 / 日志复制 / 快照传输)           │      │
│  └──────────────────────────────────────────────┘      │
└─────────────────────────────────────────────────────────┘
子模块存储结构职责
METAB+Tree(自研 TDB 引擎)存储表的元数据:超级表 Schema、子表 Tag 值、表 UID 映射、Tag 索引
TSDBLSM-Tree(MemTable → SST 文件)存储时序数据,按列式存储和压缩,支持多级文件组织
WAL顺序追加日志文件写前日志,保证崩溃恢复;同时也是 Raft 日志和 TMQ 消费的数据源
TQ基于 WAL/快照管理数据订阅(TMQ)的消费进度和流计算任务的调度
SMA独立 SMA 文件预聚合引擎,支持 RSMA(Rollup SMA)多级降采样和 TSMA(用户自定义预聚合)
2.2 VNode 的数据分片机制

当创建一个数据库时,mnode 会根据 VGROUPS 参数创建指定数量的 vgroup。系统将整个 32 位 hash 空间 [0, 0xFFFFFFFF] 均匀划分给各个 vgroup,每个 vgroup 负责一段 hash 范围:

数据库 "power" (VGROUPS 4):
  vgroup 1: hashRange [0x00000000, 0x3FFFFFFF]  → dnode1
  vgroup 2: hashRange [0x40000000, 0x7FFFFFFF]  → dnode2
  vgroup 3: hashRange [0x80000000, 0xBFFFFFFF]  → dnode3
  vgroup 4: hashRange [0xC0000000, 0xFFFFFFFF]  → dnode1

当写入数据时,客户端对表名计算一致性 hash 值,然后确定该表属于哪个 vgroup,再将请求发送到对应的 vnode。也就是说,同一张表的所有数据始终在同一个 vnode 中。

2.3 VNode 的 Buffer Pool(三段缓冲池)

VNode 使用一个 3 段循环缓冲池来管理内存写入:

  ┌───────────┐    ┌───────────┐    ┌───────────┐
  │ BufPool-0 │───→│ BufPool-1 │───→│ BufPool-2 │──→ (循环)
  │ (inUse)   │    │(onCommit) │    │ (free)    │
  └───────────┘    └───────────┘    └───────────┘
       ↑                │
    新数据写入       后台线程刷盘
  • inUse:当前接收新写入的缓冲池
  • onCommit:正在被后台线程刷写到磁盘的缓冲池
  • free:已完成刷盘、等待被重新使用的缓冲池

当 inUse 的内存使用达到阈值时,触发切换:inUse → onCommit,free → inUse,然后后台 Commit 线程将 onCommit 中的数据持久化到 META(B+Tree)和 TSDB(SST 文件)。3 段设计实现了写入和落盘的流水线,确保在刷盘期间仍有空闲段接收新写入,提高写入吞吐。

2.4 VNode 的写入路径

一条数据从客户端到磁盘的完整路径:

客户端 INSERT SQL
    ↓
taosc 解析 SQL,计算表名 hash,定位 vgroup
    ↓
RPC 发送写入请求到 leader vnode
    ↓
leader vnode 发起 Raft Propose
    ↓ [Raft 日志复制到 follower]
多数派确认后 Apply
    ↓
┌──────────────────────────────────┐
│  1. 写入 WAL(保证持久性)         │
│  2. 写入 MemTable(内存中的数据)  │
│     - META 模块:更新表元数据      │
│     - TSDB 模块:插入时序数据      │
│  3. 触发 SMA(如果配置了 RSMA)   │
└──────────────────────────────────┘
    ↓ [当 MemTable 达到阈值]
后台 Commit 线程:MemTable → 磁盘文件
    ↓
标记对应 WAL 已落盘,可回收

3. MNode:集群的大脑

MNode 是集群的元数据管理中心,负责管理所有的全局信息。

3.1 MNode 管理的对象

MNode 使用自研的 SDB(State Database) 引擎存储元数据,SDB 本身也通过 Raft 协议在多个 mnode 之间复制,保证高可用。SDB 管理的主要对象包括:

类别管理对象说明
集群管理Cluster、DNode、MNode、QNode、SNode集群拓扑、节点注册和状态
数据管理Database、VGroup、Super Table、SMA数据库配置、分片分布、超级表 Schema
用户安全User、Role、Auth用户认证、RBAC 权限控制
流计算Stream、StreamTask流计算任务定义和调度
数据订阅Topic、Consumer、Subscribe、OffsetTMQ 主题和消费者管理
扩展功能Func(UDF)、Index、View、Compact自定义函数、索引、视图、压缩任务
事务Trans分布式事务状态机
3.2 MNode 的定时任务

MNode 内部运行一个定时器线程,周期性执行以下关键任务:

任务说明
推进未完成的事务重试因超时或节点宕机而暂停的分布式事务
TMQ 消费者负载均衡在消费者加入/离开时重新分配分区
TTL 表清理检查并删除已过期的表
DNode 离线检测发现心跳超时的 dnode,标记其上的 vgroup 为离线
Compaction 进度推进查询各 vnode 的压缩进度,更新状态机
WAL/数据修剪清理已不需要的 WAL 和过期数据
3.3 MNode 的分布式事务

MNode 通过事务对象来实现跨节点的 DDL 操作原子性。例如 CREATE DATABASE 需要在多个 dnode 上创建 vnode,这个过程通过一个多阶段事务来保证:

CREATE DATABASE 事务流程:

  1. MNode 创建事务对象,记录所有操作步骤
  2. 通过 Raft 将事务复制到所有 mnode 副本
  3. Leader mnode 按步骤执行:
     - 向 dnode1 发送 "创建 vnode1" 请求
     - 向 dnode2 发送 "创建 vnode2" 请求
     - 收集所有响应
  4. 全部成功 → 事务标记为 committed
     任一失败 → 执行回滚操作
  5. 定时器会自动重试未完成的事务

事务设计采用可重试策略幂等保证——如果某个 dnode 已经完成了操作,重试时直接返回成功而不报错。

4. QNode:存算分离的关键

QNode 是独立于 VNode 的纯计算节点。当集群配置了 QNode 后,查询引擎会将计算密集型的操作(如聚合、排序、JOIN)调度到 QNode 执行,VNode 只负责数据扫描和过滤。

无 QNode 的查询:
  taosc → VNode(扫描 + 计算 + 返回结果)

有 QNode 的查询:
  taosc → QNode(接收计算任务)
              ↓
         QNode 向多个 VNode 请求数据
              ↓
         QNode 执行聚合/排序/JOIN
              ↓
         QNode 返回结果给 taosc

如果集群中没有可用的 QNode,所有计算任务将回退到 VNode 中执行。

5. SNode:流计算的专用节点

SNode 专门处理流计算(CREATE STREAM)任务。当集群配置了 SNode 后,MNode 会将流计算任务调度到 SNode 执行,从而避免流计算占用 VNode 的写入和查询资源。

流计算任务分配:
  有 SNode → MNode 调度流任务到 SNode
  无 SNode → 流任务在 VNode 中执行(与数据存储共享资源)

6. Taosc:智能客户端驱动

Taosc 不是一个简单的连接库——它是一个智能路由和缓存引擎,封装了所有分布式系统的复杂性。

6.1 Taosc 的核心能力
能力说明
元数据缓存缓存 vgroup 分布信息和表 schema,避免每次操作都查询 mnode
路由和重定向自动发现 mnode、自动追踪 vgroup leader 变化
SQL 解析和规划在客户端侧完成 SQL 解析、语义分析和物理计划拆分
任务调度将分布式子任务并行分发到各 vnode/qnode
结果合并收集各节点返回的局部结果,执行最后一级聚合
心跳管理定期向 mnode 发送心跳,维护连接和刷新元数据
6.2 连接建立流程
应用程序调用 taos_connect(host, user, pass, db, port)
    ↓
taosc 向配置的 firstEp 发送连接请求
    ↓
如果该 dnode 不是 mnode → 返回 mnode 的地址列表 → 自动重定向
    ↓
mnode 返回连接响应:
  - 集群 ID
  - 服务器时间戳
  - mnode 地址列表
    ↓
taosc 缓存集群信息,启动心跳线程(默认每 1.5 秒)
    ↓
返回连接句柄给应用
6.3 查询执行全流程
应用调用 taos_query("SELECT avg(voltage) FROM meters WHERE location='Beijing'")
    ↓
1. taosc 解析 SQL,构建抽象语法树(AST)
    ↓
2. 元数据查找(带缓存):
   - 检查缓存中是否有 "meters" 表的元数据
   - 没有 → 向 mnode 请求 vgroup 分布信息
   - 没有 → 向 vnode 请求表 schema
    ↓
3. 语义分析 + 类型检查 + 权限校验
    ↓
4. 逻辑计划 → 物理计划 → 分布式计划拆分
   (将查询拆分为多个子任务,每个子任务对应一个 vnode/qnode)
    ↓
5. 调度器并行分发子任务到各 vnode/qnode
   各节点并行执行扫描和局部聚合
    ↓
6. 结果合并:
   收集各节点的局部结果,taosc 执行最后一级合并/聚合
    ↓
7. 返回最终结果给应用

7. RPC 通信层

7.1 通信协议

TDengine 集群内所有通信均使用 TCP 协议,通信层基于自研的 RPC 框架。

每个 dnode 维护 4 个独立的 RPC 通道:

通道用途说明
Server RPC监听外部请求接收来自 taosc 和其他 dnode 的请求
Client RPC发起通用请求向其他 dnode 发送请求
Status RPC状态心跳dnode 定期向 mnode 上报状态
Sync RPCRaft 同步专用于 Raft 日志复制和快照传输
7.2 消息路由机制

当 taosd 收到一条 RPC 消息时:

  1. 版本兼容性检查——确认客户端和服务端版本兼容
  2. IP 白名单检查(如果启用)——拒绝未授权的来源
  3. 根据消息类型查路由表——确定由哪种节点类型处理(mnode/vnode/qnode 等)
  4. 获取对应的节点——如果需要 mnode 但本 dnode 没部署 mnode → 返回重定向信息
  5. 放入对应的工作队列——写入请求进写入队列,查询请求进查询队列
  6. 工作线程从队列取出消息并执行
7.3 工作队列隔离

TDengine 使用多种工作队列来隔离不同类型的操作,确保写入不阻塞查询、查询不阻塞 Raft 同步:

队列类型用途
Write Queue写入操作(Raft Propose)
Apply QueueRaft Apply(已提交的写入执行)
Query Queue查询执行
Fetch Queue查询结果获取
Sync QueueRaft 同步消息处理
Stream Queue流计算任务

8. VGroup 与 Raft 共识

8.1 VGroup 的作用

VGroup(虚拟节点组)是 TDengine 实现高可用的关键机制。一个 VGroup 由分布在不同 dnode 上的多个 VNode 组成,它们之间通过 Raft 一致性协议 保持数据同步。

vgroup 3 (REPLICA 3):
  ┌──────────┐    ┌──────────┐    ┌──────────┐
  │ VNode    │    │ VNode    │    │ VNode    │
  │ (Leader) │←──→│(Follower)│←──→│(Follower)│
  │ dnode-1  │    │ dnode-2  │    │ dnode-3  │
  └──────────┘    └──────────┘    └──────────┘
       ↑
    写入请求
  • 写操作 只能在 Leader VNode 上执行
  • Leader 将 WAL 日志异步复制到 Follower
  • 多数派确认后,数据才被认为已提交
  • Leader 宕机时,剩余 Follower 自动选举新 Leader
8.2 副本数与 VGroup 数
-- 创建 3 副本、8 个 vgroup 的数据库
CREATE DATABASE power REPLICA 3 VGROUPS 8;
-- 这会创建 8 × 3 = 24 个 VNode,分布在至少 3 个 dnode 上
  • 副本数(REPLICA):创建数据库时指定,默认 1,最大 3。决定每个 VGroup 中的 VNode 数量。
  • VGroup 数(VGROUPS):创建数据库时指定,默认自动计算。决定数据被分成多少个分片。
  • 约束:创建 N 副本的数据库,集群至少需要 N 个 dnode。

9. 集群拓扑示例

一个典型的 3 节点生产集群:

┌─────────── dnode-1 (192.168.1.101:6030) ──────────────┐
│  mnode (Leader)     │  vnode(vg=1,Leader)              │
│  qnode              │  vnode(vg=4,Follower)            │
│  snode              │  vnode(vg=7,Leader)              │
└───────────────────────────────────────────────────────┘
                            │ TCP
┌─────────── dnode-2 (192.168.1.102:6030) ──────────────┐
│  mnode (Follower)   │  vnode(vg=1,Follower)            │
│  qnode              │  vnode(vg=5,Leader)              │
│                     │  vnode(vg=8,Follower)            │
└───────────────────────────────────────────────────────┘
                            │ TCP
┌─────────── dnode-3 (192.168.1.103:6030) ──────────────┐
│  mnode (Follower)   │  vnode(vg=1,Follower)            │
│  qnode              │  vnode(vg=6,Leader)              │
│                     │  vnode(vg=9,Leader)              │
└───────────────────────────────────────────────────────┘

10. 端到端完整操作流程

10.1 写入流程(INSERT)
App:INSERT INTO d1001 USING meters TAGS('Beijing',2) VALUES(now, 10.3, 219, 0.31)
    │
    ↓
Taosc:
    ├── 解析 SQL
    ├── 查缓存:"meters" 的 vgroup 分布信息?
    │   → 没有 → 向 mnode 请求 → mnode 返回各 vgroup 的 hash 范围和 leader 地址
    ├── 计算 "d1001" 的 hash → 命中 vgroup 3
    ├── 查缓存:d1001 的 schema?
    │   → 没有 → 向 vgroup 3 的 leader 请求 → 返回 schema
    ├── 如果 d1001 不存在 → 自动建表(因为用了 USING 子句)
    ├── 编码数据,发送写入请求到 vgroup 3 的 leader
    │
    ↓
VNode (Leader, vgroup 3):
    ├── Raft Propose → 复制 WAL 到 Follower
    ├── 多数派确认 → Apply
    ├── 写 WAL → 写 MemTable
    └── 返回成功
    │
    ↓
Taosc:缓存 leader 信息,返回成功给 App
10.2 查询流程(SELECT)
App:SELECT avg(voltage) FROM meters WHERE location='Beijing' AND ts > now-1h
    │
    ↓
Taosc:
    ├── 解析 SQL → 语义分析 → 逻辑计划 → 物理计划
    ├── 拆分为分布式子计划:
    │   ├── 子任务 1 → vgroup 1:扫描 + 过滤 + 局部聚合
    │   ├── 子任务 2 → vgroup 2:扫描 + 过滤 + 局部聚合
    │   ├── 子任务 3 → vgroup 3:扫描 + 过滤 + 局部聚合
    │   └── 合并任务 → qnode 或 taosc 自身:合并局部结果
    ├── 并行分发子任务到各 vnode/qnode
    ├── 各节点执行:
    │   ├── Tag 过滤:location='Beijing' → 筛选出符合条件的子表
    │   ├── 时间过滤:ts > now-1h → 定位文件组和数据块
    │   ├── 扫描数据 → 局部 avg 计算
    │   └── 返回局部结果
    ├── taosc/qnode 合并所有局部结果 → 最终 avg
    └── 返回给 App

11. 存储层概览

11.1 数据文件组织

每个 VNode 的数据目录结构如下:

/var/lib/taos/vnode/vnode2/
├── vnode.json              # VNode 配置和状态信息
├── wal/                    # WAL 预写日志
│   ├── 00000000.log
│   └── 00000001.log
├── meta/                   # 元数据 B+Tree
│   ├── main.tdb
│   └── main.tdb-journal
└── tsdb/                   # 时序数据(LSM 结构)
    ├── v2f1000.head        # BRIN 索引(块范围索引)
    ├── v2f1000.data        # 列式数据块
    ├── v2f1000.sma         # 预计算统计信息(min/max/sum)
    ├── v2f1000.stt         # 碎片数据(STT 文件)
    └── v2f1000.tomb        # 删除记录
11.2 三层数据存储
层级存储位置数据内容
数据库元数据MNode(SDB)集群拓扑、用户、数据库配置、超级表 Schema、VGroup 分布
表元数据VNode(META)子表名 → UID 映射、Tag 值、表 Schema、Tag 索引
时序数据VNode(TSDB)按 (时间戳, 版本号) 排序的列式时序数据

12. 关键配置参数

参数默认值说明
fqdnhostnamednode 的 FQDN,用于集群通信
serverPort6030taosd 监听端口
firstEp-集群第一个 dnode 的 endpoint,新节点加入时指定
secondEp-备用 endpoint,firstEp 不可达时使用
dataDir/var/lib/taos数据文件存储目录,支持多磁盘多级存储
tempDir/tmp临时文件目录
supportVnodesCPU×2单个 dnode 支持的最大 VNode 数
statusInterval1 秒dnode 向 mnode 上报状态的间隔

13. 线程模型概览

TDengine 的线程模型是多线程、多队列的架构:

taosd 进程中的主要线程组:

┌─ RPC 线程组 ──────────────────────────────────┐
│  Server IO 线程 × N      (接收 RPC 请求)       │
│  Client IO 线程 × N      (发送 RPC 请求)       │
└───────────────────────────────────────────────┘

┌─ VNode 线程组(所有 VNode 共享) ─────────────┐
│  Query Worker 线程池     (查询执行)             │
│  Fetch Worker 线程池     (结果获取)             │
│  Write Worker 线程池     (写入 Raft Propose)    │
│  Apply Worker 线程池     (Raft Apply)          │
│  Sync Worker 线程池      (Raft 同步)           │
│  Stream Worker 线程池    (流计算)              │
│  Commit 线程 × 1         (MemTable 刷盘)       │
│  Merge/Compact 线程 × 1  (SST 文件合并)        │
└───────────────────────────────────────────────┘

┌─ MNode 线程组 ────────────────────────────────┐
│  Read Worker 线程池      (元数据查询)          │
│  Write Worker 线程池     (DDL 操作)            │
│  Sync Worker 线程池      (Raft 同步)           │
│  Timer 线程 × 1          (定时任务)            │
└───────────────────────────────────────────────┘

每个 VNode 拥有独立的写入队列、同步队列和 Apply 队列,但共享全局的查询线程池和 Fetch 线程池。这种设计既保证了 VNode 之间写入隔离,又避免了线程资源浪费。

性能考量

  1. MNode 不是瓶颈:taosc 会缓存 vgroup 分布和表 schema,只有首次访问时才需要联系 mnode。后续操作直接路由到 vnode。
  2. 写入优化:WAL + MemTable 的追加写模式,配合列式存储和压缩,写入吞吐极高。
  3. 查询优化:BRIN 索引 + SMA 预计算 + Tag 索引 + 时间分区,多级过滤减少数据扫描量。
  4. 存算分离:通过 QNode 实现计算与存储的解耦,避免大查询影响写入性能。
  5. 多级存储:支持 SSD/HDD/S3 多级存储,热数据放 SSD,冷数据放 HDD 或 S3,降低成本。

FAQ

Q1: TDengine 的 vnode 和传统数据库的分片(shard)有什么区别?

VNode 本质上就是一个数据分片,但它更加自包含。每个 VNode 不仅存储时序数据(TSDB),还存储该分片内所有表的元数据(META)、预写日志(WAL)、预聚合数据(SMA)和消费进度(TQ)。这意味着一个 VNode 可以独立完成数据的写入、查询和恢复,不依赖外部的元数据服务。

Q2: MNode 最多只有 3 个,会不会成为单点瓶颈?

不会。MNode 管理的是"低频"的元数据操作(如建库、建表、DDL),这些操作占比很小。真正的高频操作(数据写入和查询)直接路由到 VNode,不经过 MNode。taosc 会缓存所有需要的路由信息,正常情况下只在首次访问时联系 MNode。

Q3: 如果 taosc 连接的 dnode 宕机了怎么办?

taosc 会自动重试连接集群中的其他 dnode。由于每个 dnode 都知道所有 mnode 的 endpoint,taosc 可以通过任意存活的 dnode 重新获取集群信息。对于多副本数据库,如果当前 leader vnode 所在的 dnode 宕机,taosc 会自动连接同一 vgroup 中新选举出的 leader。

Q4: QNode 和 VNode 中执行查询有什么区别?

在 VNode 中执行查询时,扫描和计算共享 VNode 的资源(内存、CPU),大查询可能影响写入性能。使用 QNode 后,VNode 只负责数据扫描和初步过滤,复杂的聚合、排序、JOIN 在 QNode 上执行,实现了存储和计算的资源隔离。

Q5: TDengine 的 Raft 实现有什么特点?

TDengine 自研了 Raft 共识协议实现,支持:

  • Leader 选举与自动故障转移
  • 日志复制(基于 WAL)
  • 快照传输(用于新节点追赶数据)
  • 仲裁机制(2 副本场景下的脑裂处理)

MNode 和 VGroup 都使用同一套 Raft 实现,但独立运行各自的 Raft 组。

Q6: 一个 dnode 上可以同时运行多少种节点?

理论上一个 dnode 可以同时运行 mnode + 多个 vnode + qnode + snode + bnode。在小规模部署中,单个 dnode 可以承担所有角色。在大规模生产环境中,建议将 mnode 和 qnode 部署在独立的 dnode 上,避免资源争抢。

Q7: 为什么 TDengine 使用 FQDN 而不是 IP 地址进行通信?

FQDN 比 IP 地址更稳定。在容器化、云部署场景中,IP 地址可能频繁变化,而 FQDN 可以通过 DNS 动态解析。使用 FQDN 使集群能够适应 IP 变化而无需重新配置。

Q8: taosc 缓存了元数据,如果表 schema 变了怎么办?

taosc 的心跳机制会定期向 mnode 同步最新信息。当 schema 发生变更时,mnode 会递增版本号。taosc 在心跳中发现版本号变化后会刷新缓存。如果在刷新之前使用了旧 schema 写入,vnode 会返回 schema 不匹配错误,taosc 会自动重新获取最新 schema 并重试。

参考

  • TDengine 官方文档 - 整体架构:https://docs.taosdata.com/tdinternal/arch/
  • TDengine 官方文档 - 存储引擎:https://docs.taosdata.com/tdinternal/storage/
  • TDengine GitHub 源码:https://github.com/taosdata/TDengine
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TDengine (老段)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值