目录一、TDengine 是什么和普通数据库的区别核心特性面试要点二、核心组件架构角度2.1 taosd — 主服务进程2.2 taos — 原生命令行客户端2.3 超级表STable / Super Table2.4 VNode虚拟节点2.5 MNode管理节点2.6 QNode查询节点2.7 时间分区三、工作原理面试怎么答四、实战案例监控 100 台服务器 CPU 使用率4.1 安装 TDengine4.2 创建数据库和超级表4.3 创建子表每台服务器一张4.4 写入数据4.5 查询数据各种场景4.6 JavaSpring Boot完整集成4.7 对接 Grafana 可视化4.8 对接 Prometheus面试加分项五、面试高频题 参考答案Q1: TDengine 和 InfluxDB 怎么选Q2: 超级表为什么快Q3: TDengine 如何处理大量设备同时写入Q4: 和常规关系型数据库比有什么缺陷Q5: 数据过期删除怎么做的Q6: TDengine 3.x 和 2.x 的区别Q7: 怎么保证数据不丢六、30 分钟快速上手指南自检清单七、学习路线推荐一、TDengine 是什么TDengine是涛思数据TAOS Data打造的高性能、云原生、时序数据库Time-Series Database, TSDB。一句话定位专为物联网IoT、工业互联网、车联网、运维监控等场景设计的时序数据平台核心解决海量时间序列数据的高效写入、存储、查询和分析问题。和普通数据库的区别维度传统关系库MySQL/PostgreSQL普通时序库InfluxDBTDengine数据模型松散的行/列标签字段 无模式超级表STable 子表强模式写入性能一般万级/秒较好十万级/秒千万级/秒/节点压缩比低一般 2~5x中5~10x高10~20x查询能力标准 SQL类 SQL 有限全功能 SQL支持窗口、聚合、降采样部署运维成熟一般单进程一体无外部依赖核心特性面试要点SQL 兼容— 支持标准 SQLSELECT, INSERT, CREATE, JOIN, 窗口函数等学习成本极低超级表STable— 核心抽象一张模板表 按标签tags自动分表实现千万级设备统一管理列式存储 高效压缩— 按列存储时序特有压缩算法有损/无损压缩比 10~20x时间分区— 自动按时间分片VNODES支持过期自动删除预计算— 窗口聚合、降采样、连续查询内建高效云原生架构— 支持集群、多副本、弹性伸缩无外部依赖— 一个taosd进程搞定所有不依赖 ZooKeeper/HDFS多种接入— JDBC/RESTful/MQTT/Telegraf/Prometheus 等二、核心组件架构角度2.1 taosd — 主服务进程单进程包含全部功能SQL 解析、存储引擎、时序引擎、集群通信、数据均衡。启动方式systemctl start taosd # Linux docker start tdengine # Docker2.2 taos — 原生命令行客户端连接 taosd 执行 SQL。taos # 默认连接本地 taos -h 192.168.1.100 -P 6030 # 连接远程2.3 超级表STable / Super Table这是TDengine 的灵魂概念面试必问。CREATE STABLE meters ( ts TIMESTAMP, -- 时间戳主键 value FLOAT, -- 采集值 phase INT -- 相别 ) TAGS ( location BINARY(64), -- 标签地理位置 groupId INT -- 标签分组 );超级表 模板定义数据列Data Columns— 随时间变化的值如 CPU 使用率、温度、电压标签列Tags— 固定不变的元数据如设备型号、地理位置、所属分组子表 超级表的实例化一个具体设备对应一张子表标签值在子表创建时固定后续不变所有子表共享超级表的数据列结构查询优势按标签过滤时TDengine 自动只扫描匹配的子表性能极佳。2.4 VNode虚拟节点数据分布的最小逻辑单元一个 VNode 包含多个子表的数据多个 VNode 组成 VGroupVGroup 是数据复制的最小单元2.5 MNode管理节点集群元数据管理表结构、节点信息、用户权限支持多副本使用 RAFT 协议选主维持一致性2.6 QNode查询节点3.x 新增分布式 SQL 查询协调将查询计划拆分到各 VNode 并行执行再合并结果2.7 时间分区数据自动按时间分区默认 1440 分钟/天分区内数据顺序写入保证极高的写入性能查询时通过分区裁剪只扫相关分区三、工作原理面试怎么答面试话术示例1 分钟版TDengine 之所以快我认为核心在于三点第一数据模型设计得好— 超级表将设备元数据标签和数据分离同一设备的数据物理上连续存储写入时顺序追加天然避免了随机 IO。每台设备一张子表查一台设备就是扫一个文件不是扫整张表。第二列式存储 时序压缩— 按列存储时间戳用差值编码只存 delta浮点数用施普林格编码或二阶差分实测压缩比能达到 10~20 倍。存储成本低查的时候 IO 量也少。第三计算下推— 窗口聚合、降采样直接在存储层完成不需要把原始数据拉到应用层算。比如SELECT AVG(cpu) INTERVAL(5m)数据在扫盘时就聚合完了查询性能比 MySQL 快几十倍。而且它完全兼容 SQL团队不需要额外学习新语法。四、实战案例监控 100 台服务器 CPU 使用率端到端实战从安装到查询每一步都写清楚。4.1 安装 TDengine方式一Docker推荐5 分钟上手# 拉取并启动 docker run -d --name tdengine \ -p 6030:6030 -p 6041:6041 -p 6043:6043 -p 6044:6044 \ tdengine/tdengine:3.3.5.4 # 验证 docker exec -it tdengine taos -V端口说明6030 → 原生 TCP 协议JDBC 连接6041 → RESTful HTTP 接口6043 → 集群内部通信6044 → 集群同步方式二直接安装Linux# Ubuntu/Debian wget https://www.tdengine.com/assets-download/TDengine-3.3.5.4-Linux-x64.deb sudo dpkg -i TDengine-3.3.5.4-Linux-x64.deb sudo systemctl start taosd taos -V4.2 创建数据库和超级表# 进入 TDengine Shell taos -- 创建数据库 -- KEEP 30: 数据保留 30 天自动删除 -- DURATION 10: 每 10 天一个数据文件分区 -- BUFFER 32: 写入缓存 32MB -- CACHESIZE 4: 元数据缓存 4MB CREATE DATABASE monitor KEEP 30 DURATION 10 BUFFER 32 CACHESIZE 4; USE monitor; -- 创建超级表服务器 CPU 监控 CREATE STABLE cpu_metrics ( ts TIMESTAMP, -- 采集时间 cpu_usage FLOAT, -- CPU 使用率 (%) mem_usage FLOAT, -- 内存使用率 (%) load_1m FLOAT -- 1 分钟负载 ) TAGS ( hostname BINARY(32), -- 主机名 region BINARY(16), -- 区域 env BINARY(8) -- 环境 (prod/test/staging) );4.3 创建子表每台服务器一张-- 为每台服务器创建子表 CREATE TABLE server_web_01 USING cpu_metrics TAGS(web-01, us-east-1, prod); CREATE TABLE server_web_02 USING cpu_metrics TAGS(web-02, us-east-1, prod); CREATE TABLE server_db_01 USING cpu_metrics TAGS(db-01, us-east-2, prod); CREATE TABLE server_cache_01 USING cpu_metrics TAGS(cache-01, ap-southeast-1, staging); CREATE TABLE server_db_02 USING cpu_metrics TAGS(db-02, eu-west-1, prod); -- 查一下有多少个子表 SELECT COUNT(*) FROM information_schema.ins_tables WHERE db_name monitor;4.4 写入数据方式一单条写入INSERT INTO server_web_01 (ts, cpu_usage, mem_usage, load_1m) VALUES (NOW, 45.2, 62.1, 2.3);方式二单行写入多张表事务性INSERT INTO server_web_01 (ts, cpu_usage, mem_usage, load_1m) VALUES (NOW, 47.8, 63.0, 2.5) server_db_01 (ts, cpu_usage, mem_usage, load_1m) VALUES (NOW, 32.1, 78.4, 1.8) server_cache_01 (ts, cpu_usage, mem_usage, load_1m) VALUES (NOW, 12.3, 45.6, 0.9);方式三批量造数据用于测试造 1000 条-- 生成从 NOW - 1000s 到 NOW 每秒一条的伪随机数据 INSERT INTO server_web_01 SELECT _wstart AS ts, RANDOM() % 100 AS cpu_usage, RANDOM() % 100 AS mem_usage, (RANDOM() % 100) / 10.0 AS load_1m FROM (SELECT _wstart FROM FILL(ts, 1s) RANGE(NOW - 1000s, NOW)); -- 验证写入成功 SELECT COUNT(*) FROM server_web_01;4.5 查询数据各种场景场景 1查一台服务器最近 1 小时的数据SELECT * FROM server_web_01 WHERE ts NOW - 1h ORDER BY ts DESC;场景 2查所有服务器的平均 CPU过去 1 小时SELECT AVG(cpu_usage) AS avg_cpu, MAX(cpu_usage) AS max_cpu, MIN(cpu_usage) AS min_cpu, COUNT(*) AS data_points FROM cpu_metrics WHERE ts NOW - 1h;场景 3按区域聚合SELECT region, AVG(cpu_usage) AS avg_cpu, AVG(mem_usage) AS avg_mem FROM cpu_metrics WHERE ts NOW - 1d PARTITION BY region;场景 4降采样 — 每 5 分钟一个聚合点SELECT _wstart AS window_start, AVG(cpu_usage) AS avg_cpu, MAX(cpu_usage) AS peak_cpu, MIN(cpu_usage) AS min_cpu FROM cpu_metrics WHERE ts NOW - 1h INTERVAL(5m);场景 5找出 CPU 90% 的异常时刻SELECT tbname, hostname, ts, cpu_usage, mem_usage FROM cpu_metrics WHERE cpu_usage 90 AND ts NOW - 1d ORDER BY ts DESC;场景 6TOP N 分析 — CPU 最高的前 10 台服务器SELECT tbname, hostname, AVG(cpu_usage) AS avg_cpu FROM cpu_metrics WHERE ts NOW - 1h PARTITION BY tbname ORDER BY avg_cpu DESC LIMIT 10;场景 7跨表 JOIN 查询高级-- 查 web-01 和 db-01 在相同时刻的 CPU 对比 SELECT a.ts, a.cpu_usage AS web_cpu, b.cpu_usage AS db_cpu, (a.cpu_usage - b.cpu_usage) AS diff FROM server_web_01 a JOIN server_db_01 b ON a.ts b.ts;4.6 JavaSpring Boot完整集成pom.xml 添加依赖dependency groupIdcom.taosdata.jdbc/groupId artifactIdtaos-jdbcdriver/artifactId version3.3.0/version /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-jdbc/artifactId /dependencyapplication.yml 配置spring: datasource: url: jdbc:TAOS-RS://localhost:6041/monitor username: root password: taosdata driver-class-name: com.taosdata.jdbc.rs.RestfulDriver实体类Data AllArgsConstructor NoArgsConstructor public class CpuMetric { private Date ts; private Double cpuUsage; private Double memUsage; private Double load1m; private String hostname; private String region; private String env; }DAO 层Repository public class CpuMetricDao { Autowired private JdbcTemplate jdbcTemplate; /** 单条写入自动根据 hostname 选子表 */ public void insert(CpuMetric metric) { String tableName server_ metric.getHostname().replace(-, _); String sql String.format( INSERT INTO %s (ts, cpu_usage, mem_usage, load_1m) VALUES (?, ?, ?, ?), tableName ); jdbcTemplate.update(sql, metric.getTs(), metric.getCpuUsage(), metric.getMemUsage(), metric.getLoad1m() ); } /** 批量写入按 hostname 分组每组一个 batch — 性能最好 */ public void batchInsert(ListCpuMetric metrics) { // 按 hostname 分组 MapString, ListCpuMetric grouped metrics.stream() .collect(Collectors.groupingBy(m - server_ m.getHostname().replace(-, _))); grouped.forEach((tableName, list) - { String sql String.format( INSERT INTO %s (ts, cpu_usage, mem_usage, load_1m) VALUES (?, ?, ?, ?), tableName ); jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() { Override public void setValues(PreparedStatement ps, int i) throws SQLException { CpuMetric m list.get(i); ps.setTimestamp(1, new Timestamp(m.getTs().getTime())); ps.setDouble(2, m.getCpuUsage()); ps.setDouble(3, m.getMemUsage()); ps.setDouble(4, m.getLoad1m()); } Override public int getBatchSize() { return list.size(); } }); }); } /** 查最近 N 条记录 */ public ListCpuMetric queryRecent(String hostname, int limit) { String tableName server_ hostname.replace(-, _); String sql String.format( SELECT ts, cpu_usage, mem_usage, load_1m FROM %s ORDER BY ts DESC LIMIT ?, tableName ); return jdbcTemplate.query(sql, new BeanPropertyRowMapper(CpuMetric.class), limit); } /** 按区域聚合查询 */ public ListMapString, Object aggregateByRegion(int hoursAgo) { String sql SELECT region, AVG(cpu_usage) AS avg_cpu, AVG(mem_usage) AS avg_mem, COUNT(*) AS total_points FROM cpu_metrics WHERE ts NOW - ?h PARTITION BY region ; return jdbcTemplate.queryForList(sql, hoursAgo); } }4.7 对接 Grafana 可视化在 Grafana 中安装 TDengine 数据源插件grafana-cli plugins install tdengine-datasource添加数据源URL:http://你的服务器:6041数据库monitor用户名/密码root/taosdata一个示例面板的查询 SQLSELECT _wstart AS t, AVG(cpu_usage) AS avg_cpu FROM cpu_metrics WHERE ts NOW - 1h AND region us-east-1 INTERVAL(30s)4.8 对接 Prometheus面试加分项TDengine 支持 Prometheus remote write/read 协议。Prometheus 配置# prometheus.yml remote_write: - url: http://你的服务器:6041/prometheus/v1/write?dbmonitor remote_read: - url: http://你的服务器:6041/prometheus/v1/read?dbmonitor原理Prometheus 采集的指标数据直接写入 TDengineGrafana 再从 TDengine 查询实现采集和存储解耦解决 Prometheus 单机存储瓶颈。五、面试高频题 参考答案Q1: TDengine 和 InfluxDB 怎么选答选型不只看性能。选 TDengine团队有 SQL 经验、数据有固定标签结构1 万 设备有相同采集维度需要高吞吐写入。超级表模型更匹配SQL 兼容降低学习成本。选 InfluxDB多变的无模式数据、临时探索分析为主、生态成熟度要求高。性能差距TDengine 写入吞吐千万级/秒通常比 InfluxDB 高一个数量级压缩比也更好。Q2: 超级表为什么快答三个核心原因写即顺序— 一张子表只存一个设备的数据写入是顺序追加天然无随机 IO标签→分区裁剪— 标签和数据分离按标签过滤时只扫描匹配的子表不需要全表扫时间分区— 数据按时间分区存储查询时剪切无关分区Q3: TDengine 如何处理大量设备同时写入答三层缓冲机制数据先进入内存的 WriteCache达到一定量或超时后合并写入列式文件VNode 分担写入压力 单节点实测 800 万 数据点/秒。Q4: 和常规关系型数据库比有什么缺陷答主要三点事务能力弱— 不支持跨表事务ACID 不如 MySQL小数据量无优势— 100 万行以内 MySQL 够用TDengine 优势体现不出来生态仍在成长— 不如 InfluxDB/Prometheus 成熟某些工具对接需要自己写适配Q5: 数据过期删除怎么做的答建库时指定KEEP参数如KEEP 30天TDengine 自动在后台清理过期数据文件。不需要写DELETE语句避免了传统数据库大数据量删除的性能灾难。Q6: TDengine 3.x 和 2.x 的区别答3.x 是架构重写主要变化从 2.x 的一个节点一个 dnode变为计算存储分离架构新增 QNode查询节点解耦查询负载支持 Kubernetes 部署Operator更好的 SQL 兼容性窗口函数等Q7: 怎么保证数据不丢答三种机制配合多副本— 每个 VGroup 配置 1~3 副本写入同步复制WAL— 先写 WAL 日志再写缓存宕机可恢复RAFT— 管理节点用 RAFT 保证元数据一致性六、30 分钟快速上手指南自检清单步骤操作预期结果1. 安装docker run tdengine/tdenginetaosd 启动2. 连接taos进入 shell看到taos提示符3. 建库CREATE DATABASE demo; USE demo;切换数据库成功4. 建超级表CREATE STABLE ...超级表创建成功5. 建子表CREATE TABLE ... USING ... TAGS(...)子表创建成功6. 写入INSERT INTO ... VALUES(...)返回 0 受影响行数7. 查询SELECT * FROM cpu_metrics返回数据8. 降采样SELECT ... INTERVAL(1m)分钟级聚合结果9. 标签过滤WHERE regionus-east-1只返回该区域数据10. Java 集成引入 taos-jdbcdriverCRUD 正常七、学习路线推荐Day 1: 安装 建库建表 写入查询今天的内容 Day 2: 超级表 子表机制深入 批量写入性能测试 Day 3: 降采样聚合 连续查询 数据保留策略 Day 4: Java/Spring Boot 接入 批量写入优化 Day 5: Grafana 可视化 Prometheus 对接 Day 6: 集群搭建 多副本 扩容缩容 Day 7: 性能调优 面试题复盘