小 T 導讀:眾所周知,TDengine 支持多(duo)種寫(xie)(xie)入(ru)協(xie)議(yi),包括 SQL、InfluxDB Line 協(xie)議(yi)、OpenTSDB Telnet 協(xie)議(yi)、OpenTSDB JSON 格式協(xie)議(yi)。但說到如何進行(xing)寫(xie)(xie)入(ru)操作,很多(duo)讀者可能都是一頭霧水,本篇文章(zhang)為(wei)大家匯總(zong)了一系(xi)列(lie)的(de)寫(xie)(xie)入(ru)教程,方便有需要(yao)的(de)開發者作為(wei)寫(xie)(xie)入(ru)指南收藏(zang)使用。
TDengine 中的(de)(de)(de) SQL 寫入即模式化寫入,在(zai)(zai)寫入到 Database 之前,需要(yao)預先定義好數(shu)據(ju)(ju)表(biao)(biao)的(de)(de)(de) Schema 模式,具體來說就是(shi)數(shu)據(ju)(ju)表(biao)(biao)包含多(duo)少列,每列存放的(de)(de)(de)數(shu)據(ju)(ju)類型是(shi)什(shen)么。即在(zai)(zai)建(jian)表(biao)(biao)時使用標(biao)準的(de)(de)(de) SQL 語句指定表(biao)(biao)的(de)(de)(de) Schema,再(zai)遵照(zhao)預先建(jian)好的(de)(de)(de)列跟(gen)標(biao)簽值的(de)(de)(de)數(shu)量和類型進行數(shu)據(ju)(ju)寫入。
除了(le) SQL 寫(xie)入外, TDengine 還(huan)支持三種(zhong)(zhong)無(wu)(wu)模(mo)式寫(xie)入協(xie)(xie)(xie)議(yi),分別是 InfluxDB Line 協(xie)(xie)(xie)議(yi)、OpenTSDB Telnet 協(xie)(xie)(xie)議(yi)和 OpenTSDB JSON 格(ge)式協(xie)(xie)(xie)議(yi)。如果你對 NoSQL 比較熟悉,那對無(wu)(wu)模(mo)式寫(xie)入應該就不會陌生了(le)。通俗(su)來講,無(wu)(wu)模(mo)式寫(xie)入為用戶提供了(le)一種(zhong)(zhong)以(yi)文本格(ge)式將(jiang)數據寫(xie)入到(dao) TDengine 的(de)方(fang)式,更加便捷。
物聯(lian)網場景中(zhong)的(de)應用(yong)經常需要采集比(bi)較多的(de)數(shu)(shu)(shu)據(ju)項,用(yong)于實現智能(neng)控制、業(ye)務(wu)分析和(he)設備監控等,由于應用(yong)邏輯的(de)版本(ben)(ben)升級(ji),或者設備自(zi)身的(de)硬件調整等原因,數(shu)(shu)(shu)據(ju)采集項有(you)可能(neng)比(bi)較頻繁(fan)地出現變動,為了(le)在這種情況下仍能(neng)方(fang)便地完成數(shu)(shu)(shu)據(ju)記錄工作,TDengine 從(cong) 2.2 版本(ben)(ben)開(kai)始就提供了(le)無模(mo)式寫(xie)入(ru)方(fang)式,寫(xie)入(ru)時(shi)無需提前創建(jian)超(chao)級(ji)表(biao)和(he)子表(biao),其引擎(qing)能(neng)自(zi)適應數(shu)(shu)(shu)據(ju)并對(dui)表(biao)結(jie)構進行調整。
在使(shi)用 TDengine 寫入(ru)數(shu)據(ju)時(shi),數(shu)據(ju)可以單條插(cha)(cha)入(ru),也(ye)可以批量(liang)插(cha)(cha)入(ru),可以插(cha)(cha)入(ru)一個(ge)數(shu)據(ju)采集(ji)點(dian)的數(shu)據(ju),也(ye)可以同時(shi)插(cha)(cha)入(ru)多個(ge)數(shu)據(ju)采集(ji)點(dian)的數(shu)據(ju)。此外(wai),TDengine 不僅支(zhi)持多線(xian)程插(cha)(cha)入(ru)、時(shi)間亂(luan)序數(shu)據(ju)插(cha)(cha)入(ru),也(ye)支(zhi)持歷史數(shu)據(ju)插(cha)(cha)入(ru)。下面將對四種寫入(ru)協議進行說明(ming),以供參考(kao)。
SQL 寫入
用戶可以(yi)讓應用通過連接器(qi)執行 INSERT 語句來插入數據,還可以(yi)通過 TAOS Shell,手動輸(shu)入 INSERT 語句來實現。
- 一次寫入一條
下(xia)面這條 INSERT 就將一條記錄寫入(ru)到表 d1001 中:
INSERT INTO d1001 VALUES (1538548685000, 10.3, 219, 0.31);
- 一次寫入多條
TDengine 支持一(yi)次寫入(ru)多條(tiao)(tiao)記(ji)錄,比如(ru)下面這條(tiao)(tiao)命令(ling)就將兩條(tiao)(tiao)記(ji)錄寫入(ru)到表 d1001 中(zhong):
INSERT INTO d1001 VALUES (1538548684000, 10.2, 220, 0.23) (1538548696650, 10.3, 218, 0.25);
- 一次寫入多表
TDengine 也支(zhi)持一次向多個(ge)表寫(xie)入(ru)數據,比(bi)如下面這條(tiao)命(ming)令就向 d1001 寫(xie)入(ru)兩條(tiao)記(ji)錄,向 d1002 寫(xie)入(ru)一條(tiao)記(ji)錄:
INSERT INTO d1001 VALUES (1538548685000, 10.3, 219, 0.31) (1538548695000, 12.6, 218, 0.33) d1002 VALUES (1538548696800, 12.3, 221, 0.31);
- 注意事項
如(ru)果(guo)想要(yao)(yao)提高(gao)寫(xie)(xie)入(ru)效(xiao)率,我(wo)們可(ke)以(yi)(yi)使用(yong)批(pi)量寫(xie)(xie)入(ru),這樣一批(pi)寫(xie)(xie)入(ru)的(de)(de)記錄條數(shu)越多,插入(ru)效(xiao)率就會越高(gao),但(dan)需要(yao)(yao)注意的(de)(de)是(shi),一條記錄不能(neng)(neng)超(chao)過 48 KB,一條 SQL 語句總長度不能(neng)(neng)超(chao)過 1MB。此外,TDengine 支持(chi)多線(xian)(xian)程(cheng)(cheng)同時(shi)寫(xie)(xie)入(ru),如(ru)果(guo)要(yao)(yao)進一步提高(gao)寫(xie)(xie)入(ru)速度,一個客戶端需要(yao)(yao)打開(kai) 20 個以(yi)(yi)上的(de)(de)線(xian)(xian)程(cheng)(cheng)同時(shi)寫(xie)(xie)。但(dan)要(yao)(yao)注意,線(xian)(xian)程(cheng)(cheng)數(shu)達到一定數(shu)量后(hou)將(jiang)無法再提高(gao),甚至還會下降,因(yin)為線(xian)(xian)程(cheng)(cheng)頻(pin)繁切換(huan)會帶來額外開(kai)銷。
對同一張表來說,如(ru)果(guo)新插(cha)入記(ji)錄(lu)的(de)時(shi)間戳(chuo)已經存在,那(nei)默認情形下(UPDATE=0)新記(ji)錄(lu)將被(bei)直接拋棄,也(ye)就(jiu)是說,在一張表里時(shi)間戳(chuo)必須是唯一的(de)。如(ru)果(guo)讓應用自動生成記(ji)錄(lu),很可(ke)能生成的(de)時(shi)間戳(chuo)是一樣的(de),這樣一來,成功插(cha)入的(de)記(ji)錄(lu)條數(shu)(shu)就(jiu)會小于應用插(cha)入的(de)記(ji)錄(lu)條數(shu)(shu)。如(ru)果(guo)在創建(jian) Database 時(shi)使用了 UPDATE 為 1 的(de)選項(xiang),插(cha)入相(xiang)同時(shi)間戳(chuo)的(de)新記(ji)錄(lu)將覆蓋原有(you)記(ji)錄(lu)。
最后一點(dian),寫(xie)(xie)入(ru)數(shu)(shu)據的時(shi)間戳必(bi)須大于當(dang)前時(shi)間減去配(pei)置參(can)數(shu)(shu) keep 的時(shi)間,如(ru)果 keep 配(pei)置為 3650 天(tian),那么將無法(fa)寫(xie)(xie)入(ru)比 3650 天(tian)還早的數(shu)(shu)據;而且(qie)寫(xie)(xie)入(ru)數(shu)(shu)據的時(shi)間戳也不能大于當(dang)前時(shi)間加(jia)配(pei)置參(can)數(shu)(shu) days,即如(ru)果 days 為 2,那么也將無法(fa)寫(xie)(xie)入(ru)比當(dang)前時(shi)間還晚 2 天(tian)的數(shu)(shu)據。
關于 SQL 寫入的更詳細語法規則可參考此前發布的使用 TDengine 如何進行 SQL 寫入 一文。
InfluxDB 行協議
InfluxDB Line 協議采用一(yi)行字符串來表示一(yi)行數據。分為四部(bu)分:
measurement,tag_set field_set timestamp
- measurement 將作為超級表名。它與 tag_set 之間使用一個英文逗號來分隔。
- tag_set 將作為標簽數據,其格式形如
<tag_key>=<tag_value>,<tag_key>=<tag_value>,也即可以使用英文逗號來分隔多個標簽數據。它與 field_set 之間使用一個半角空格來分隔。 - field_set 將作為普通列數據,其格式形如
<field_key>=<field_value>,<field_key>=<field_value>,同樣是使用英文逗號來分隔多個普通列的數據。它與 timestamp 之間使用一個半角空格來分隔。 - timestamp 即本行數據對應的主鍵時間戳。
例如:
meters,location=California.LosAngeles,groupid=2 current=13.4,voltage=223,phase=0.29 1648432611249500
- 注意事項
- tag_set 中的所有數據會自動轉化為 nchar 數據類型;
- field_set 中的每個數據項都需要對自身的數據類型進行描述,比如 1.2f32 代表 float 類型的數值 1.2,如果不帶類型后綴會被當作 double 處理;
- timestamp 支持多種時間精度。寫入數據時需要用參數指定時間精度,支持從小時到納秒的 6 種時間精度。
OpenTSDB 行協議
OpenTSDB 行(xing)協議(yi)(yi)同(tong)(tong)樣采用(yong)一(yi)(yi)(yi)行(xing)字符串來表示一(yi)(yi)(yi)行(xing)數(shu)據。由于 OpenTSDB 采用(yong)的是單列(lie)(lie)模型,因此(ci)一(yi)(yi)(yi)行(xing)只能(neng)包(bao)含一(yi)(yi)(yi)個普通數(shu)據列(lie)(lie),但標(biao)簽(qian)列(lie)(lie)依然可以(yi)有(you)多(duo)個。該協議(yi)(yi)同(tong)(tong)樣分(fen)為四(si)部分(fen),具體格式約(yue)定如下:
<metric> <timestamp> <value> <tagk_1>=<tagv_1>[ <tagk_n>=<tagv_n>]
需要注意的是:
- metric 將作為超級表名。
- timestamp 為本行數據對應的時間戳。根據時間戳的長度自動識別時間精度。支持秒和毫秒兩種時間精度
- value 為度量值,必須為一個數值。對應的列名也是 “value”。
- 最后一部分是標簽集, 用空格分隔不同標簽, 所有標簽自動轉化為 nchar 數據類型;
例如:
meters.current 1648432611250 11.3 location=California.LosAngeles groupid=3
具體可(ke)以參考 OpenTSDB Telnet API 文(wen)檔:
OpenTSDB JSON 格式協議
OpenTSDB JSON 格(ge)式協議采(cai)用一個 JSON 字符(fu)串表示一行或(huo)多行數據。例如(ru):
[
{
"metric": "sys.cpu.nice",
"timestamp": 1346846400,
"value": 18,
"tags": {
"host": "web01",
"dc": "lga"
}
},
{
"metric": "sys.cpu.nice",
"timestamp": 1346846400,
"value": 9,
"tags": {
"host": "web02",
"dc": "lga"
}
}
]
與 OpenTSDB 行協(xie)議類似,在(zai)此種寫(xie)入協(xie)議中,metric 將作為超級表(biao)名, timestamp 表(biao)示時間戳,value 表(biao)示度量值, tags 表(biao)示標(biao)簽集。具體可以參考 OpenTSDB HTTP API 文檔:
- 注意事項
- 對于 JSON 格式協議,TDengine 并不會自動把所有標簽轉成 nchar 類型,僅會將字符串轉為 nchar 類型, 數值將轉換為 double 類型。
- TDengine 只接收 JSON 數組格式的字符串,即使一行數據也需要轉換成數組形式。
寫在最后
為(wei)了更高(gao)效(xiao)地(di)(di)向(xiang) TDengine 寫(xie)(xie)入(ru)(ru)數(shu)(shu)據(ju),客戶(hu)端程序要充(chong)分且恰當地(di)(di)利(li)用以(yi)下幾個(ge)因素:數(shu)(shu)據(ju)在不同表(biao)(或(huo)子表(biao))之間的分布(bu),即(ji)要寫(xie)(xie)入(ru)(ru)數(shu)(shu)據(ju)的相鄰性(xing);單次(ci)(ci)寫(xie)(xie)入(ru)(ru)的數(shu)(shu)據(ju)量;并發連接數(shu)(shu)。在單次(ci)(ci)寫(xie)(xie)入(ru)(ru)中(zhong)(zhong)盡(jin)量只向(xiang)同一(yi)張表(biao)(或(huo)子表(biao))寫(xie)(xie)入(ru)(ru)數(shu)(shu)據(ju),每批(pi)次(ci)(ci)寫(xie)(xie)入(ru)(ru)的數(shu)(shu)據(ju)量經過(guo)測(ce)試和調(diao)優,設(she)定(ding)為(wei)一(yi)個(ge)最適合當前系(xi)統處(chu)理能(neng)力(li)(li)的數(shu)(shu)值(zhi),并發寫(xie)(xie)入(ru)(ru)的連接數(shu)(shu)同樣(yang)經過(guo)測(ce)試和調(diao)優后,設(she)定(ding)為(wei)一(yi)個(ge)最適合當前系(xi)統處(chu)理能(neng)力(li)(li)的數(shu)(shu)值(zhi),以(yi)實現在當前系(xi)統中(zhong)(zhong)的最佳寫(xie)(xie)入(ru)(ru)速度。此外,TDengine 提(ti)供的獨特(te)參數(shu)(shu)綁定(ding)寫(xie)(xie)入(ru)(ru),也是一(yi)個(ge)有助(zhu)于(yu)實現高(gao)效(xiao)寫(xie)(xie)入(ru)(ru)的方法。
但要(yao)注意的是,如(ru)(ru)果無(wu)論(lun)怎么(me)調節客(ke)戶(hu)端(duan)程(cheng)(cheng)序,taosd 進程(cheng)(cheng)的 CPU 使用率始(shi)終都很低(di),那很可能需要(yao)增(zeng)加 vgroup 的數(shu)量,服務(wu)端(duan)的配置同樣重要(yao)。如(ru)(ru)果大(da)家(jia)在寫入(ru)操(cao)作(zuo)時(shi)遇到了困難,首先可以(yi)進入(ru) TDengine 官網-技術文檔頁面進行查詢,如(ru)(ru)果依然無(wu)法解(jie)(jie)決,我們還有專門的社區(qu)技術人員能夠為(wei)你答疑解(jie)(jie)惑。
此外,如(ru)果大家想了解 Java、Python、Go、Rust、Node.js、C#、C 不同語言(yan)的寫入(ru)示例代碼,也可以進入(ru) TDengine 官網-頁(ye)面查(cha)看(kan)更多詳情(qing)。


























