時序數(shù)據(jù)庫在海量數(shù)據(jù)寫入場景中扮演著關(guān)鍵角色,其寫入性能直接影響物聯(lián)網(wǎng)、工業(yè)互聯(lián)網(wǎng)等實時數(shù)據(jù)采集系統(tǒng)的整體效率。TDengine作為一款專為時序數(shù)據(jù)設計的時序數(shù)據(jù)庫,提供了多種高效的數(shù)據(jù)寫入方式,從標準SQL到無模式寫入,從單條插入到批量寫入,覆蓋了各類業(yè)務場景。本文將全面介紹TDengine的數(shù)據(jù)寫入機制、無模式寫入?yún)f(xié)議以及寫入性能優(yōu)化技巧,幫助開發(fā)者構(gòu)建高性能的數(shù)據(jù)采集管道。
一、TDengine多種寫入方式概覽
TDengine支持靈活多樣的數(shù)據(jù)寫入方式,開發(fā)者可以根據(jù)業(yè)務場景選擇最適合的方案。以下是TDengine支持的主要寫入方式:
| 寫入方式 | 適用場景 | 特點 |
|---|---|---|
| 標準SQL寫入 | 少量數(shù)據(jù)、調(diào)試場景 | 簡單直觀,兼容標準SQL語法 |
| 批量寫入 | 大數(shù)據(jù)量導入、定時任務 | 高吞吐,減少網(wǎng)絡交互 |
| 多表寫入 | 多設備同時上報 | 一次請求寫入多張子表 |
| 自動建表寫入 | 動態(tài)設備接入 | 無需預先建表,自動創(chuàng)建子表 |
| 無模式寫入 | 跨平臺遷移、多協(xié)議接入 | 兼容InfluxDB/OpenTSDB協(xié)議 |
1.1 標準SQL寫入
最基礎(chǔ)的寫入方式,使用標準INSERT語句:
-- 向子表寫入單條數(shù)據(jù)
INSERT INTO d1001 (ts, current, voltage, phase)
VALUES ('2025-06-03 10:00:00', 10.5, 220, 0.8);
-- 向多張子表寫入數(shù)據(jù)
INSERT INTO d1001 VALUES ('2025-06-03 10:01:00', 10.2, 219, 0.81)
d1002 VALUES ('2025-06-03 10:01:00', 11.3, 221, 0.79);
1.2 批量寫入
批量寫入是提升寫入性能的關(guān)鍵手段。TDengine支持在一條INSERT語句中寫入大量數(shù)據(jù):
-- 批量寫入:一次插入多行數(shù)據(jù)
INSERT INTO d1001 VALUES
('2025-06-03 10:00:00', 10.5, 220, 0.8)
('2025-06-03 10:01:00', 10.2, 219, 0.81)
('2025-06-03 10:02:00', 10.8, 221, 0.78)
('2025-06-03 10:03:00', 10.1, 218, 0.82);
批量寫入時,TDengine會在服務端進行寫入優(yōu)化,將多條記錄合并后一次性寫入存儲引擎,大幅減少磁盤I/O次數(shù)。
二、無模式寫入(Schemaless)
TDengine的無模式寫入功能是其一大亮點,允許在不預先創(chuàng)建表結(jié)構(gòu)的情況下直接寫入數(shù)據(jù)。這一特性極大簡化了數(shù)據(jù)接入流程,特別適合設備動態(tài)增減的物聯(lián)網(wǎng)場景。
2.1 兼容InfluxDB Line Protocol
TDengine支持InfluxDB的行協(xié)議格式,方便從InfluxDB遷移或使用InfluxDB生態(tài)工具:
-- 使用InfluxDB Line Protocol格式寫入
-- 語法: <measurement>,<tags> <fields> <timestamp>
INSERT INTO stb1,t0=1,t1=2 c0=1.0,c1="hello" 1626006833639ms
其中:
stb1為超級表名稱t0=1,t1=2為標簽值c0=1.0,c1="hello"為數(shù)據(jù)列1626006833639ms為時間戳(支持ms/us/ns/s等多種精度)
2.2 兼容OpenTSDB JSON/telnet格式
TDengine同時兼容OpenTSDB的數(shù)據(jù)寫入?yún)f(xié)議:
// OpenTSDB JSON格式
{
"metric": "cpu.usage",
"timestamp": 1626006833,
"value": 75.5,
"tags": {
"host": "server01",
"region": "cn-beijing"
}
}
# OpenTSDB telnet格式
put cpu.usage 1626006833 75.5 host=server01 region=cn-beijing
2.3 自動建表機制
無模式寫入的核心優(yōu)勢在于自動建表。當寫入的數(shù)據(jù)對應的子表不存在時,TDengine會自動創(chuàng)建超級表和子表:
-- 配置自動建表參數(shù)
CREATE DATABASE power
SML_AUTO_CREATE_DB ON -- 無模式寫入時自動創(chuàng)建數(shù)據(jù)庫
SML_CHILD_TABLE 'auto_ct' -- 自動建表時子表命名規(guī)則
SML_TZ 'Asia/Shanghai'; -- 時區(qū)設置
自動建表的規(guī)則如下:
- 若超級表不存在,自動創(chuàng)建超級表
- 若子表不存在,根據(jù)標簽值自動創(chuàng)建子表
- 子表名稱由
SML_CHILD_TABLE參數(shù)控制
三、寫入優(yōu)化核心技術(shù)
3.1 WAL預寫日志
WAL(Write Ahead Log)是TDengine保證數(shù)據(jù)不丟失的核心機制。寫入流程如下:
客戶端寫入請求 → WAL預寫日志 → 內(nèi)存緩沖區(qū) → 返回成功 → 異步刷盤到數(shù)據(jù)文件
WAL的工作原理:
- 先寫日志再寫內(nèi)存:數(shù)據(jù)先持久化到WAL文件,再寫入內(nèi)存緩沖區(qū)
- 崩潰恢復保障:系統(tǒng)異常重啟時,通過重放WAL恢復未刷盤的數(shù)據(jù)
- 順序?qū)懭雰?yōu)化:WAL采用追加寫入方式,充分利用磁盤順序?qū)懶阅?/li>
-- WAL相關(guān)配置參數(shù)
ALTER DATABASE mydb WAL_LEVEL 1; -- WAL日志級別
-- 0: 不寫WAL; 1: 寫WAL但不執(zhí)行fsync; 2: 寫WAL并執(zhí)行fsync
3.2 批量寫入?yún)?shù)優(yōu)化
TDengine提供了多個參數(shù)用于控制批量寫入行為:
| 參數(shù) | 默認值 | 說明 |
|---|---|---|
| maxInsertBatchRows | 1000000 | 單次批量寫入的最大行數(shù) |
| maxInsertBatchCols | 1000000 | 單次批量寫入的最大列數(shù) |
| maxSQLLength | 1048576 | 單條SQL語句的最大長度(字節(jié)) |
-- 通過taos.cfg調(diào)整批量寫入?yún)?shù)
maxInsertBatchRows 1000000
maxInsertBatchCols 1000000
最佳實踐建議:
- 每批寫入數(shù)據(jù)量建議在1000~100000行之間
- 單條SQL不宜過大,避免超過
maxSQLLength限制 - 根據(jù)網(wǎng)絡帶寬和內(nèi)存情況調(diào)整批量大小
3.3 Buffer配置與vgroups規(guī)劃
合理的Buffer和vgroups配置是寫入性能調(diào)優(yōu)的基礎(chǔ):
-- 創(chuàng)建高性能寫入數(shù)據(jù)庫
CREATE DATABASE iot_data
BUFFER 1024 -- 每個vnode的寫緩存大?。∕B)
VGROUPS 8 -- 虛擬節(jié)點組數(shù)量
WAL_LEVEL 1 -- WAL級別
PRECISION 'ms'; -- 時間精度
vgroups規(guī)劃原則:
- vgroups數(shù)量建議不超過數(shù)據(jù)節(jié)點(dnode)的CPU核數(shù)
- 每個vgroup至少分配256MB的Buffer
- 寫入吞吐量高的場景適當增加vgroups數(shù)量
四、taosAdapter數(shù)據(jù)接入
taosAdapter是TDengine提供的數(shù)據(jù)接入組件,支持多種主流監(jiān)控和數(shù)據(jù)采集工具的協(xié)議:
4.1 支持的數(shù)據(jù)接入?yún)f(xié)議
| 協(xié)議/工具 | 用途 | 配置方式 |
|---|---|---|
| Telegraf | 通用數(shù)據(jù)采集 | taosAdapter配置文件 |
| StatsD | 應用指標采集 | taosAdapter配置文件 |
| collectd | 系統(tǒng)指標采集 | taosAdapter配置文件 |
| Prometheus | 監(jiān)控數(shù)據(jù)寫入 | taosAdapter配置文件 |
| InfluxDB Line Protocol | 兼容寫入 | RESTful API |
4.2 taosAdapter配置示例
# taosAdapter配置文件(部分)
telegraf:
enable: true
port: 6044
db: telegraf_db
prometheus:
enable: true
port: 6043
db: prometheus_db
statsd:
enable: true
port: 6045
db: statsd_db
通過taosAdapter,用戶無需編寫代碼即可將Telegraf、Prometheus等工具采集的數(shù)據(jù)直接寫入TDengine,大幅降低了數(shù)據(jù)接入的復雜度。
五、代碼示例:多語言寫入實踐
5.1 Python寫入示例
import taos
# 建立連接
conn = taos.connect(host='localhost', port=6030, user='root', password='taosdata')
cursor = conn.cursor()
# 創(chuàng)建數(shù)據(jù)庫和超級表
cursor.execute('CREATE DATABASE IF NOT EXISTS power PRECISION "ms"')
cursor.execute('USE power')
cursor.execute('''
CREATE STABLE IF NOT EXISTS meters (
ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT
) TAGS (location INT, groupId INT)
''')
# 自動建表寫入(使用SML協(xié)議)
# 先確保數(shù)據(jù)庫配置了SML_AUTO_CREATE_DB ON
cursor.execute('''
INSERT INTO power.meters _s0 _i0 _i1
USING power.meters TAGS(1, 1)
VALUES ('2025-06-03 10:00:00', 10.5, 220, 0.8)
''')
# 批量寫入
sql = 'INSERT INTO power.meters'
for i in range(1000):
ts = f'2025-06-03 10:{i//60:02d}:{i%60:02d}'
sql += f' _s{i} _i{i//100} _i{i%10} VALUES (\'{ts}\', {10.0+i*0.1}, 220, 0.8)'
cursor.execute(sql)
cursor.close()
conn.close()
5.2 JDBC寫入示例
import com.taosdata.jdbc.TSDBDriver;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class TDengineWriteExample {
public static void main(String[] args) throws Exception {
String url = "jdbc:TAOS://localhost:6030/power?charset=UTF-8";
Connection conn = DriverManager.getConnection(url, "root", "taosdata");
Statement stmt = conn.createStatement();
// 批量寫入
StringBuilder sb = new StringBuilder("INSERT INTO ");
for (int i = 0; i < 1000; i++) {
sb.append(String.format(
"d%d VALUES ('2025-06-03 10:%02d:%02d', %f, %d, %f) ",
i, i / 60, i % 60, 10.0 + i * 0.1, 220, 0.8
));
}
stmt.execute(sb.toString());
stmt.close();
conn.close();
}
}
5.3 RESTful API寫入示例
# 通過RESTful API寫入數(shù)據(jù)
curl -u root:taosdata -d 'INSERT INTO power.meters
_s0 _i0 _i1 USING power.meters TAGS(1, 1)
VALUES ("2025-06-03 10:00:00", 10.5, 220, 0.8)' \
http://localhost:6041/rest/sql/power
六、寫入性能調(diào)優(yōu)總結(jié)
6.1 異步寫入策略
對于對寫入延遲不敏感但吞吐量要求極高的場景,可以采用異步寫入策略:
- 調(diào)整WAL級別:將
WAL_LEVEL設為1,避免每次寫入都執(zhí)行fsync - 增大Buffer:適當增大每個vnode的寫緩存,減少刷盤頻率
- 合理設置vgroups:根據(jù)CPU核數(shù)和數(shù)據(jù)量規(guī)劃vgroups數(shù)量
6.2 性能調(diào)優(yōu)檢查清單
| 調(diào)優(yōu)項 | 推薦配置 | 說明 |
|---|---|---|
| BUFFER | 256~1024 MB | 根據(jù)可用內(nèi)存調(diào)整 |
| VGROUPS | 不超過CPU核數(shù) | 過多會導致資源競爭 |
| WAL_LEVEL | 1(推薦) | 平衡性能與可靠性 |
| maxInsertBatchRows | 1000000 | 保持默認即可 |
| 批量大小 | 1000~100000行 | 根據(jù)實際場景測試 |
結(jié)語
TDengine作為一款專為時序數(shù)據(jù)設計的時序數(shù)據(jù)庫,在數(shù)據(jù)寫入方面提供了豐富的功能和極致的性能優(yōu)化。從標準SQL寫入到無模式寫入,從WAL預寫日志到批量寫入優(yōu)化,TDengine為開發(fā)者構(gòu)建高性能數(shù)據(jù)采集系統(tǒng)提供了完整的解決方案。通過合理配置Buffer、vgroups和WAL參數(shù),結(jié)合taosAdapter的多協(xié)議接入能力,TDengine能夠輕松應對每秒千萬級數(shù)據(jù)點的寫入需求,是物聯(lián)網(wǎng)和工業(yè)互聯(lián)網(wǎng)場景下時序數(shù)據(jù)庫的理想選擇。



互聯(lián)網(wǎng).png)



-1.png)











伙伴.png)
伙伴.png)



