分类 :17.内部机制 | 篇章 :01 内存管理
TDengine 是高吞吐时序数据库,内存管理直接决定写入和查询性能。本文从原理角度讲解内存池、缓存层、回收机制。
内存模块速查表
| 模块 | 用途 |
|---|---|
| 内存表 | 写入缓冲(按 VNode) |
| 块缓存 | 读取热数据 |
| 元数据缓存 | Catalog/Schema |
| 查询内存 | 临时计算 |
| 连接缓存 | 客户端会话 |
| WAL 缓冲 | 写前日志 |
详细解析
1. 内存分层架构
┌────────────────────────────────────────┐
│ 查询临时内存 │
│ - 中间结果集 │
│ - 排序/聚合缓冲 │
│ - JOIN 哈希表 │
└────────────────────────────────────────┘
▲ 查询时按需分配
│
┌────────────────────────────────────────┐
│ 读缓存层 │
│ - Block Cache(数据块) │
│ - Last Cache(最新值) │
│ - 元数据缓存 │
└────────────────────────────────────────┘
▲ 查询/写入触发
│
┌────────────────────────────────────────┐
│ 写入内存表 │
│ - 按 VNode 维护 │
│ - 达阈值 Flush 到磁盘 │
└────────────────────────────────────────┘
▲ 写入入口
│
┌────────────────────────────────────────┐
│ WAL 缓冲 │
│ - 写前日志 │
│ - 定期 fsync │
└────────────────────────────────────────┘
2. 写入内存表
原理:
① 写入流程:
Client → RPC → VNode 内存表
│
├── 排序(按时间)
├── 合并重复
└── 累积到阈值
│
▼
Flush 到磁盘块
② 阈值控制:
- 配置 buffer 大小(每 VNode)
- 达到阈值后切换内存表
- 旧内存表后台 Flush
- 新写入进入新内存表
③ 多版本:
- 内存表 1(正在写)
- 内存表 2(正在 Flush)
- 内存表 3(等待回收)
内存使用估算:
单 VNode buffer ~ 几 MB ~ 几十 MB
集群多个 VGroup × 多副本 × buffer = 总写入内存
示例:3 节点 × 24 VGroups × 16MB = 1.2 GB
3. 块缓存(Block Cache)
原理:
① 查询时从磁盘读 Block
② Block 缓存到内存
③ 后续查询命中缓存直接返回
④ LRU 策略淘汰
配置:
- cache 参数控制大小
- 自适应淘汰
- 热点块优先保留
命中率:
- 时序查询时间局部性强
- 命中率通常 70%+
- 大范围历史查询命中率低
作用:
- 重复查询加速 10x+
- 减少磁盘 IO
- 节省 CPU 解压
4. 最新值缓存(Last Cache)
原理:
CACHEMODEL 配置:
- 'none' 不缓存
- 'last_row' 缓存整行最新
- 'last_value' 缓存每列最新值
- 'both' 都缓存
作用:
- SELECT LAST(*)、LAST_ROW(*) 极速
- 直接从内存返回
- 不扫描数据块
适用:
- 设备实时状态查询
- 大盘最新值
- SCADA 实时显示
开销:
- 每子表占用少量内存
- 写入时同步更新
- 万级子表 ~ 几百 MB
5. 元数据缓存
缓存内容:
① Catalog(数据库/表信息)
- 库名、表名、超级表
- Schema 定义
② Schema(列定义、Tag 定义)
③ 路由表(哪个 VGroup 在哪个节点)
④ 用户权限
客户端缓存:
- 客户端连接后拉取元数据
- 本地缓存
- 版本号检测变化
服务端缓存:
- MNode 维护权威元数据
- DNode/VNode 缓存子集
失效机制:
- DDL 操作触发版本递增
- 客户端定期 / 主动检查
- 缓存淘汰旧版本
6. 查询内存
查询过程内存分配:
① 解析(小):
- SQL AST
- 解析树
② 优化(小):
- 计划节点
③ 执行(大):
- 输入块缓冲
- 中间结果
- 排序缓冲
- 聚合状态(按组)
- JOIN 哈希表
- 输出缓冲
控制:
- 单查询内存上限(配置)
- 超过后失败 / 溢出磁盘
- 大查询用 QNode 隔离
典型规模:
- 小查询:< 1MB
- 中查询:几 MB ~ 几十 MB
- 大聚合(高基数 GROUP BY):GB 级
7. 内存回收
回收时机:
① 写入内存表 Flush:
- 落盘后释放
- 新内存表接收新写入
② 查询结束:
- 临时分配回收
- 缓冲池归还
③ 连接断开:
- 会话相关释放
- 缓存查询结果释放
④ 缓存 LRU:
- 内存压力下淘汰冷块
- 释放给新查询使用
⑤ 后台压缩/合并:
- 合并后释放旧块
内存碎片:
- 使用对象池减少碎片
- 定期检查碎片率
- 严重时可重启进程
8. 内存压力应对
监控指标:
- 总内存使用
- 各模块占比
- 缓存命中率
- OOM 风险
应对:
① 减少 buffer
ALTER DATABASE ... BUFFER 8;
# 减小写入内存
② 减少 cache
# 减小块缓存
③ 关闭 LastCache
ALTER DATABASE ... CACHEMODEL 'none';
④ 限制单查询
# 大查询走 QNode
⑤ 限制连接数
ALTER ALL DNODES 'numOfRpcSessions' '5000';
⑥ 增加物理内存
# 根本解决
OOM 自我保护:
- 写入限流
- 查询拒绝
- 缓存清理
- 极端情况:进程退出
代码示例
内存配置参数
cfg
# /etc/taos/taos.cfg
# 全局
cache 16 # 写入缓存(MB)
numOfRpcSessions 5000 # 连接数
numOfCommitThreads 4 # 提交线程
# 按库配置
# CREATE DATABASE iot
# BUFFER 256 -- 单 VNode 写入 buffer (MB)
# CACHE 16 -- 单 VNode 块缓存 (MB)
# CACHEMODEL 'last_value' -- LastCache 模式
监控内存使用
sql
-- DNode 内存
SELECT endpoint, mem_used, mem_total,
mem_used * 100.0 / mem_total AS pct
FROM information_schema.ins_dnodes;
-- VNode 内存
SELECT db_name, vgroup_id, dnode_id,
memory_size_mb
FROM information_schema.ins_vnodes
ORDER BY memory_size_mb DESC LIMIT 10;
-- log 数据库(监控历史)
SELECT _wstart, endpoint,
AVG(memory_usage_pct) AS avg_mem
FROM log.taosd_dnodes_info
WHERE ts > NOW - 1h
PARTITION BY endpoint
INTERVAL(5m);
内存调优案例
sql
-- 案例 1: OOM 频繁
-- 排查:缓存过大
SELECT memory_usage_pct FROM log.taosd_dnodes_info
WHERE ts > NOW - 1h ORDER BY ts DESC;
-- 措施:缩小 cache
-- ALTER DATABASE ... CACHE 8;
-- 案例 2: 查询慢
-- 排查:缓存命中率低
-- 措施:增加 cache,CACHEMODEL 'last_value'
-- 案例 3: 写入卡顿
-- 排查:内存表 Flush 不及时
-- 措施:增加 numOfCommitThreads,加大 BUFFER
性能考量
内存与性能
| 内存配置 | 写入性能 | 查询性能 |
|---|---|---|
| 充足 | 最佳 | 最佳 |
| 适中 | 良 | 良 |
| 紧张 | 退化 | 退化 |
| 不足 | OOM | OOM |
典型配置
| 集群规模 | 单节点内存 |
|---|---|
| 测试 | 8 GB |
| 小型生产 | 32 GB |
| 中型 | 64 GB |
| 大型 | 128 GB+ |
FAQ
Q1: 怎么知道内存够不够?
看 mem_used_pct:
- < 60%:充足
- 60~80%:合理
- 80~90%:紧张
-
90%:危险
Q2: CACHEMODEL last_value 占多少?
每子表 ~ 200 B × 列数。10 万子表 + 10 列 ~ 200 MB。
Q3: 内存表大小怎么调?
按写入负载和延迟:
- 高吞吐:大 BUFFER(256MB+)
- 低延迟:小 BUFFER(16~64MB)
Q4: 查询 OOM 怎么办?
- 用 LIMIT 限制
- 加时间过滤
- 拆分子查询
- 用 qnode 隔离
- 升级内存
Q5: 重启后缓存丢失?
是的,缓存是内存中的。重启后第一波查询稍慢,逐步预热。
参考
系统构架篇
- 01-《TDengine 整体架构全景》
- 02-《集群拓扑深度解析》
- 03-《MNode 内部机制深度解析》
- 04-《RPC 通信层深度解析》
- 05-《VNode 生命周期》
- 06-《RAFT 共识协议》
- 07-《端到端的消息流》
数据模型
- 01-《数据库创建与参数详解》
- 02-《超级表/子表/普通表》
- 03-《支持数据类型深度解析》
- 04-《TDengine Tag 设计哲学与 Schema 变更机制》
- 05-《TDengine 虚拟表实现原理》
存储引擎
- 01-《TDengine 存储引擎概览》
- 02-《TDengine MemTable 深度解析》
- 03-《TDengine WAL 预写日志机制》
- 04-《TDengine 数据文件格式》
- 05-《TDengine Commit 与 Flush 机制 》
- 06-《TDengine Compaction 合并策略 》
- 07-《TDengine 数据保留与 TTL》
- 08-《TDengine 压缩编码机制》
- 09-《TDengine Cache 与 Last 查询加速》
- 10-《TDengine 逻辑计划生成》
查询引擎
- 01-《TDengine 查询引擎概览》
- 02-《TDengine SQL 解析与词法分析》
- 03-《TDengine 语义分析与 AST 重写》
- 04-《TDengine 逻辑计划生成》
- 05-《TDengine 物理计划生成》
- 06-《TDengine 扫描算子》
- 07-《TDengine 聚合算子》
- 08-《TDengine 连接算子》
- 09-《TDengine 排序、填充与投影》
- 10-《TDengine 分布式查询执行》
- 11-《TDengine EXPLAIN 与查询优化》
数据写入
- 01-《TDengine SQL INSERT》
- 02-《TDengine 无模式写入》
- 03-《TDengine STMT 写入》
- 04-《TDengine 写入内部流程》
- 05-《TDengine 数据更新删除》
数据订阅
- 01-《TDengine 数据订阅》
- 02-《TDengine 订阅 vs Kafka》
- 03-《TDengine TMQ 消费流程》
- 04-《TDengine 内部机制》
- 05-《TDengine TMQ 最佳实践》
预聚合
索引
SQL 语句
- 01-《TDengine DDL》
- 02-《TDengine DML SELECT》
- 03-《TDengine DML 函数完整参考》
- 04-《TDengine JOIN 完整语法》
- 05-《TDengine 窗口完整语法》
- 06-《TDengine 操作符与表达式》
- 07-《TDengine 系统表》
- 08-《TDengine SQL 与标准 SQL 差异》
客户端与连接器
- 01-《TDengine 的连接方式》
- 02-《TDengine C/C++ 连接器》
- 03-《TDengine java 连接器》
- 04-《TDengine Python 连接器》
- 05-《TDengine Go 与 Rust 连接器》
- 06-《TDengine Node.js 与 C# 连接器》
运维
- 01-《TDengine 部署指南》
- 02-《TDengine 配置详解》
- 03-《TDengine 监控系统》
- 04-《TDengine 备份与恢复》
- 05-《TDengine 版本升级》
- 06-《TDengine 加密使用指南》
安全
生态
- 01-《TDengine taosAdapter》
- 02-《TDengine taosX 与 Explorer》
- 03-《TDengine Grafana 集成》
- 04-《TDengine 第三方工具》
应用案例
- 01-《TDengine IoT 设备监控》
- 02-《TDengine 工业大数据与智能制造》
- 03-《TDengine 车联网与新能源汽车》
- 04-《TDengine 能源与电力监控》
- 05-《TDengine IT 运维与可观测性》
产品对比
关于 TDengine
TDengine 专为物联网IoT平台、工业大数据平台设计。其中,TDengine TSDB 是一款高性能、分布式的时序数据库(Time Series Database),同时它还带有内建的缓存、流式计算、数据订阅等系统功能;TDengine IDMP 是一款AI原生工业数据管理平台,它通过树状层次结构建立数据目录,对数据进行标准化、情景化,并通过 AI 提供实时分析、可视化、事件管理与报警等功能。
