時(shí)序數(shù)據(jù)庫(kù)在海量數(shù)據(jù)寫(xiě)入場(chǎng)景中扮演著關(guān)鍵角色,其寫(xiě)入性能直接影響物聯(lián)網(wǎng)、工業(yè)互聯(lián)網(wǎng)等實(shí)時(shí)數(shù)據(jù)采集系統(tǒng)的整體效率。TDengine作為一款專(zhuān)為時(shí)序數(shù)據(jù)設(shè)計(jì)的時(shí)序數(shù)據(jù)庫(kù),提供了多種高效的數(shù)據(jù)寫(xiě)入方式,從標(biāo)準(zhǔn)SQL到無(wú)模式寫(xiě)入,從單條插入到批量寫(xiě)入,覆蓋了各類(lèi)業(yè)務(wù)場(chǎng)景。本文將全面介紹TDengine的數(shù)據(jù)寫(xiě)入機(jī)制、無(wú)模式寫(xiě)入?yún)f(xié)議以及寫(xiě)入性能優(yōu)化技巧,幫助開(kāi)發(fā)者構(gòu)建高性能的數(shù)據(jù)采集管道。
一、TDengine多種寫(xiě)入方式概覽
TDengine支持靈活多樣的數(shù)據(jù)寫(xiě)入方式,開(kāi)發(fā)者可以根據(jù)業(yè)務(wù)場(chǎng)景選擇最適合的方案。以下是TDengine支持的主要寫(xiě)入方式:
| 寫(xiě)入方式 | 適用場(chǎng)景 | 特點(diǎn) |
|---|---|---|
| 標(biāo)準(zhǔn)SQL寫(xiě)入 | 少量數(shù)據(jù)、調(diào)試場(chǎng)景 | 簡(jiǎn)單直觀,兼容標(biāo)準(zhǔn)SQL語(yǔ)法 |
| 批量寫(xiě)入 | 大數(shù)據(jù)量導(dǎo)入、定時(shí)任務(wù) | 高吞吐,減少網(wǎng)絡(luò)交互 |
| 多表寫(xiě)入 | 多設(shè)備同時(shí)上報(bào) | 一次請(qǐng)求寫(xiě)入多張子表 |
| 自動(dòng)建表寫(xiě)入 | 動(dòng)態(tài)設(shè)備接入 | 無(wú)需預(yù)先建表,自動(dòng)創(chuàng)建子表 |
| 無(wú)模式寫(xiě)入 | 跨平臺(tái)遷移、多協(xié)議接入 | 兼容InfluxDB/OpenTSDB協(xié)議 |
1.1 標(biāo)準(zhǔn)SQL寫(xiě)入
最基礎(chǔ)的寫(xiě)入方式,使用標(biāo)準(zhǔn)INSERT語(yǔ)句:
-- 向子表寫(xiě)入單條數(shù)據(jù)
INSERT INTO d1001 (ts, current, voltage, phase)
VALUES ('2025-06-03 10:00:00', 10.5, 220, 0.8);
-- 向多張子表寫(xiě)入數(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 批量寫(xiě)入
批量寫(xiě)入是提升寫(xiě)入性能的關(guān)鍵手段。TDengine支持在一條INSERT語(yǔ)句中寫(xiě)入大量數(shù)據(jù):
-- 批量寫(xiě)入:一次插入多行數(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);
批量寫(xiě)入時(shí),TDengine會(huì)在服務(wù)端進(jìn)行寫(xiě)入優(yōu)化,將多條記錄合并后一次性寫(xiě)入存儲(chǔ)引擎,大幅減少磁盤(pán)I/O次數(shù)。
二、無(wú)模式寫(xiě)入(Schemaless)
TDengine的無(wú)模式寫(xiě)入功能是其一大亮點(diǎn),允許在不預(yù)先創(chuàng)建表結(jié)構(gòu)的情況下直接寫(xiě)入數(shù)據(jù)。這一特性極大簡(jiǎn)化了數(shù)據(jù)接入流程,特別適合設(shè)備動(dòng)態(tài)增減的物聯(lián)網(wǎng)場(chǎng)景。
2.1 兼容InfluxDB Line Protocol
TDengine支持InfluxDB的行協(xié)議格式,方便從InfluxDB遷移或使用InfluxDB生態(tài)工具:
-- 使用InfluxDB Line Protocol格式寫(xiě)入
-- 語(yǔ)法: <measurement>,<tags> <fields> <timestamp>
INSERT INTO stb1,t0=1,t1=2 c0=1.0,c1="hello" 1626006833639ms
其中:
stb1為超級(jí)表名稱(chēng)t0=1,t1=2為標(biāo)簽值c0=1.0,c1="hello"為數(shù)據(jù)列1626006833639ms為時(shí)間戳(支持ms/us/ns/s等多種精度)
2.2 兼容OpenTSDB JSON/telnet格式
TDengine同時(shí)兼容OpenTSDB的數(shù)據(jù)寫(xiě)入?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 自動(dòng)建表機(jī)制
無(wú)模式寫(xiě)入的核心優(yōu)勢(shì)在于自動(dòng)建表。當(dāng)寫(xiě)入的數(shù)據(jù)對(duì)應(yīng)的子表不存在時(shí),TDengine會(huì)自動(dòng)創(chuàng)建超級(jí)表和子表:
-- 配置自動(dòng)建表參數(shù)
CREATE DATABASE power
SML_AUTO_CREATE_DB ON -- 無(wú)模式寫(xiě)入時(shí)自動(dòng)創(chuàng)建數(shù)據(jù)庫(kù)
SML_CHILD_TABLE 'auto_ct' -- 自動(dòng)建表時(shí)子表命名規(guī)則
SML_TZ 'Asia/Shanghai'; -- 時(shí)區(qū)設(shè)置
自動(dòng)建表的規(guī)則如下:
- 若超級(jí)表不存在,自動(dòng)創(chuàng)建超級(jí)表
- 若子表不存在,根據(jù)標(biāo)簽值自動(dòng)創(chuàng)建子表
- 子表名稱(chēng)由
SML_CHILD_TABLE參數(shù)控制
三、寫(xiě)入優(yōu)化核心技術(shù)
3.1 WAL預(yù)寫(xiě)日志
WAL(Write Ahead Log)是TDengine保證數(shù)據(jù)不丟失的核心機(jī)制。寫(xiě)入流程如下:
客戶(hù)端寫(xiě)入請(qǐng)求 → WAL預(yù)寫(xiě)日志 → 內(nèi)存緩沖區(qū) → 返回成功 → 異步刷盤(pán)到數(shù)據(jù)文件
WAL的工作原理:
- 先寫(xiě)日志再寫(xiě)內(nèi)存:數(shù)據(jù)先持久化到WAL文件,再寫(xiě)入內(nèi)存緩沖區(qū)
- 崩潰恢復(fù)保障:系統(tǒng)異常重啟時(shí),通過(guò)重放WAL恢復(fù)未刷盤(pán)的數(shù)據(jù)
- 順序?qū)懭雰?yōu)化:WAL采用追加寫(xiě)入方式,充分利用磁盤(pán)順序?qū)懶阅?/li>
-- WAL相關(guān)配置參數(shù)
ALTER DATABASE mydb WAL_LEVEL 1; -- WAL日志級(jí)別
-- 0: 不寫(xiě)WAL; 1: 寫(xiě)WAL但不執(zhí)行fsync; 2: 寫(xiě)WAL并執(zhí)行fsync
3.2 批量寫(xiě)入?yún)?shù)優(yōu)化
TDengine提供了多個(gè)參數(shù)用于控制批量寫(xiě)入行為:
| 參數(shù) | 默認(rèn)值 | 說(shuō)明 |
|---|---|---|
| maxInsertBatchRows | 1000000 | 單次批量寫(xiě)入的最大行數(shù) |
| maxInsertBatchCols | 1000000 | 單次批量寫(xiě)入的最大列數(shù) |
| maxSQLLength | 1048576 | 單條SQL語(yǔ)句的最大長(zhǎng)度(字節(jié)) |
-- 通過(guò)taos.cfg調(diào)整批量寫(xiě)入?yún)?shù)
maxInsertBatchRows 1000000
maxInsertBatchCols 1000000
最佳實(shí)踐建議:
- 每批寫(xiě)入數(shù)據(jù)量建議在1000~100000行之間
- 單條SQL不宜過(guò)大,避免超過(guò)
maxSQLLength限制 - 根據(jù)網(wǎng)絡(luò)帶寬和內(nèi)存情況調(diào)整批量大小
3.3 Buffer配置與vgroups規(guī)劃
合理的Buffer和vgroups配置是寫(xiě)入性能調(diào)優(yōu)的基礎(chǔ):
-- 創(chuàng)建高性能寫(xiě)入數(shù)據(jù)庫(kù)
CREATE DATABASE iot_data
BUFFER 1024 -- 每個(gè)vnode的寫(xiě)緩存大?。∕B)
VGROUPS 8 -- 虛擬節(jié)點(diǎn)組數(shù)量
WAL_LEVEL 1 -- WAL級(jí)別
PRECISION 'ms'; -- 時(shí)間精度
vgroups規(guī)劃原則:
- vgroups數(shù)量建議不超過(guò)數(shù)據(jù)節(jié)點(diǎn)(dnode)的CPU核數(shù)
- 每個(gè)vgroup至少分配256MB的Buffer
- 寫(xiě)入吞吐量高的場(chǎng)景適當(dāng)增加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 | 應(yīng)用指標(biāo)采集 | taosAdapter配置文件 |
| collectd | 系統(tǒng)指標(biāo)采集 | taosAdapter配置文件 |
| Prometheus | 監(jiān)控?cái)?shù)據(jù)寫(xiě)入 | taosAdapter配置文件 |
| InfluxDB Line Protocol | 兼容寫(xiě)入 | 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
通過(guò)taosAdapter,用戶(hù)無(wú)需編寫(xiě)代碼即可將Telegraf、Prometheus等工具采集的數(shù)據(jù)直接寫(xiě)入TDengine,大幅降低了數(shù)據(jù)接入的復(fù)雜度。
五、代碼示例:多語(yǔ)言寫(xiě)入實(shí)踐
5.1 Python寫(xiě)入示例
import taos
# 建立連接
conn = taos.connect(host='localhost', port=6030, user='root', password='taosdata')
cursor = conn.cursor()
# 創(chuàng)建數(shù)據(jù)庫(kù)和超級(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)
''')
# 自動(dòng)建表寫(xiě)入(使用SML協(xié)議)
# 先確保數(shù)據(jù)庫(kù)配置了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)
''')
# 批量寫(xiě)入
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寫(xiě)入示例
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();
// 批量寫(xiě)入
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寫(xiě)入示例
# 通過(guò)RESTful API寫(xiě)入數(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
六、寫(xiě)入性能調(diào)優(yōu)總結(jié)
6.1 異步寫(xiě)入策略
對(duì)于對(duì)寫(xiě)入延遲不敏感但吞吐量要求極高的場(chǎng)景,可以采用異步寫(xiě)入策略:
- 調(diào)整WAL級(jí)別:將
WAL_LEVEL設(shè)為1,避免每次寫(xiě)入都執(zhí)行fsync - 增大Buffer:適當(dāng)增大每個(gè)vnode的寫(xiě)緩存,減少刷盤(pán)頻率
- 合理設(shè)置vgroups:根據(jù)CPU核數(shù)和數(shù)據(jù)量規(guī)劃vgroups數(shù)量
6.2 性能調(diào)優(yōu)檢查清單
| 調(diào)優(yōu)項(xiàng) | 推薦配置 | 說(shuō)明 |
|---|---|---|
| BUFFER | 256~1024 MB | 根據(jù)可用內(nèi)存調(diào)整 |
| VGROUPS | 不超過(guò)CPU核數(shù) | 過(guò)多會(huì)導(dǎo)致資源競(jìng)爭(zhēng) |
| WAL_LEVEL | 1(推薦) | 平衡性能與可靠性 |
| maxInsertBatchRows | 1000000 | 保持默認(rèn)即可 |
| 批量大小 | 1000~100000行 | 根據(jù)實(shí)際場(chǎng)景測(cè)試 |
結(jié)語(yǔ)
TDengine作為一款專(zhuān)為時(shí)序數(shù)據(jù)設(shè)計(jì)的時(shí)序數(shù)據(jù)庫(kù),在數(shù)據(jù)寫(xiě)入方面提供了豐富的功能和極致的性能優(yōu)化。從標(biāo)準(zhǔn)SQL寫(xiě)入到無(wú)模式寫(xiě)入,從WAL預(yù)寫(xiě)日志到批量寫(xiě)入優(yōu)化,TDengine為開(kāi)發(fā)者構(gòu)建高性能數(shù)據(jù)采集系統(tǒng)提供了完整的解決方案。通過(guò)合理配置Buffer、vgroups和WAL參數(shù),結(jié)合taosAdapter的多協(xié)議接入能力,TDengine能夠輕松應(yīng)對(duì)每秒千萬(wàn)級(jí)數(shù)據(jù)點(diǎn)的寫(xiě)入需求,是物聯(lián)網(wǎng)和工業(yè)互聯(lián)網(wǎng)場(chǎng)景下時(shí)序數(shù)據(jù)庫(kù)的理想選擇。



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



-1.png)




.png)


證.png)


伙伴.png)
伙伴.png)
伙伴.png)



