无码人妻精品一区二区三18禁,影音先锋男人AV橹橹色,污污污污污污www网站免费,日韩成人av无码一区二区三区,欧美性受xxxx狂喷水

深入探索 Schemaless 寫入:優化技術與實踐

物聯網應用常常需要收集大量的數據,用以支持智能控制、業務分析和設備監控等功能。然而,應用邏輯的更新或硬件的調整可能會導致數據采集項頻繁變化,這是時序數據庫(Time Series Database,TSDB)面臨的一大挑戰。

為了(le)適應這種動(dong)態變化(hua),TDengine 提(ti)供(gong)了(le)一種無需預先定義(yi)表結構的(de) Schemaless 寫入模式。這種模式允許開發者直(zhi)接通過寫入接口送入數(shu)據(ju),系(xi)統會自(zi)動(dong)建(jian)立(li)對應的(de)數(shu)據(ju)存儲結構。在數(shu)據(ju)結構需要(yao)(yao)調整時(shi),Schemaless 模式也能(neng)自(zi)動(dong)添(tian)加新的(de)數(shu)據(ju)列,確(que)保(bao)所有數(shu)據(ju)都能(neng)被(bei)準(zhun)確(que)記錄(lu)。如果大(da)家(jia)想要(yao)(yao)詳細了(le)解 Schemaless 寫入的(de)主(zhu)要(yao)(yao)處理(li)邏(luo)輯(ji)、映射(she)規則與(yu)變更處理(li)等(deng)機制,可以進入 直(zhi)接查看。

TDengine 對(dui) Schemaless 寫(xie)入功能(neng)(neng)進(jin)行了(le)深入優(you)化(hua),以提(ti)高其(qi)靈活性和(he)效率。本(ben)文將(jiang)介紹其(qi)中(zhong)部分優(you)化(hua)措施(shi)的(de)詳細過(guo)程和(he)技(ji)術方法,幫(bang)助開發者(zhe)更好(hao)地理解和(he)利用這一(yi)功能(neng)(neng),從而提(ti)升應用性能(neng)(neng)。同時,我們也希望這些分享能(neng)(neng)幫(bang)助開發人員在性能(neng)(neng)優(you)化(hua)方面邁向新的(de)高度。

性能優化流程

分析性能瓶頸在哪里?

通過分(fen)析下文中數據(ju)寫入的(de)火焰圖,我們會發現(xian) parser 部分(fen)和 insert 部分(fen)占用的(de)耗時都很高,并且主(zhu)要集(ji)中在 parseSmlKey、parseSmlValue、addChildTableDataPointsIntoSql、taos_query_a、buildDataPointSchema 幾個函數中。

深入探索 Schemaless 寫入:優化技術與實踐 - TDengine Database 時序數據庫

性能瓶頸如何解決?

針對上面火焰圖分析的情景,對于(yu)每個函數,我們有兩種方法來優化——要么去掉要么縮短(duan)。

如何(he)去(qu)掉?能否(fou)去(qu)掉?

首先(xian)(xian)我們需要先(xian)(xian)詳細了解現有的解析(xi)處理框架(jia)。下圖是現有框架(jia)的處理流程圖:

深入探索 Schemaless 寫入:優化技術與實踐 - TDengine Database 時序數據庫

從圖中我們能夠發現存(cun)在一(yi)些不合理的地方,如下:

  • 行協議解析析(Parser)

在處(chu)理數(shu)據(ju)時,系統會遍歷每(mei)(mei)條記錄(lu),提取出測量(liang)值(zhi)(measure)、標簽(qian)(tag)以及(ji)列(col)的(de)鍵(jian)值(zhi)對(dui),并將(jiang)這(zhe)些信息存儲于定制的(de)結(jie)構(gou)體中。此外,系統還會對(dui)每(mei)(mei)條記錄(lu)中的(de)標簽(qian)鍵(jian)進行排序,并依照既定規則生成對(dui)應的(de)子表名(ming)稱(cheng)(cheng)。然而(er),此流程中對(dui)標簽(qian)的(de)解析、排序及(ji)子表名(ming)稱(cheng)(cheng)生成的(de)重復(fu)執行,增加了處(chu)理時間和計算(suan)復(fu)雜度。

  • schema 處理

在(zai)獲取測量(liang)值(zhi)(measure)的架(jia)構元數(shu)據(ju)(schema meta)之后,系(xi)統會對該(gai)測量(liang)值(zhi)下的每一條數(shu)據(ju)執行以(yi)下操(cao)(cao)作(zuo):遍歷(li)其標簽(tag)和列(col),并(bing)檢查現有(you)架(jia)構是否需要更新,更新操(cao)(cao)作(zuo)可能(neng)包含 create stable, add col, add tag, modify col, modify tag。

  • insert 數據

當數據量小于 10 條時,系統將逐條構造 SQL 語句,并通過調用taos_query函數逐一插入數據。對于超過 10 條的數據集,系統將構建stmt結構體,并利用stmt接口批量插入數據。

  • 一些關鍵的代碼如下圖。

(主要函(han)數為(wei) tscParseLine/parseSmlKvPairs/tscSmlInsert/buildDataPointSchemas/modifyDBSchemas/applyDataPointsWithSqlInsert 等)

深入探索 Schemaless 寫入:優化技術與實踐 - TDengine Database 時序數據庫

詳細代(dai)碼請見如下鏈接(jie):

針對以上問題,我(wo)們首先可以從架構(gou)上面進行大的優化(hua)。

深入探索 Schemaless 寫入:優化技術與實踐 - TDengine Database 時序數據庫

主要包括(kuo)如(ru)下幾個方面:

行協議解析

分析(xi)數據可以看出,相(xiang)同的標簽(qian)(qian)(tag)前綴通常保持一致,所以可以對數據的標簽(qian)(qian)字符串進(jin)行預分組(zu),將具有相(xiang)同前綴的標簽(qian)(qian)歸入同一組(zu)。在每個分組(zu)內,只需對標簽(qian)(qian)進(jin)行一次(ci)解析(xi),減少重復解析(xi)的操作。

檢查數據(ju)的(de)順序,如果順序相(xiang)同,則可以(yi)直接(jie)按照順序進行數據(ju)綁定,避免(mian)使用哈希查找,從(cong)而(er)減少計算(suan)量和提高處(chu)理速度。

schema 處理

提前在(zai)解析時判(pan)斷(duan)是否(fou)需要變更架構(gou)(schema),檢查是否(fou)存在(zai)列的(de)增(zeng)加或列長度的(de)變更。如果需要變更,再走(zou)修改(gai)架構(gou)(modify schema)的(de)邏(luo)輯。

insert 數據

數據(ju)構(gou)造直(zhi)接(jie)(jie)在(zai)解析每行(xing)時實現,直(zhi)接(jie)(jie)將數據(ju)綁定(ding)到最終(zhong)的 STableDataCxt 結構(gou)中。這種(zhong)做法可以避免在(zai)后續階段再次(ci)進行(xing)數據(ju)綁定(ding)和二(er)次(ci)拷(kao)貝。

改進數據寫入(ru)方(fang)法,采(cai)用直接構造 BuildRow 的方(fang)式,避(bi)免(mian)使用 SQL 或(huo) stmt 接口而產生二次解析。

一些關鍵的代(dai)碼(ma)如下圖(主(zhu)要函數為smlParseInfluxString/smlParseTagKv/smlParseColKv/smlParseLineBottom/smlModifyDBSchemas/smlInsertData)

深入探索 Schemaless 寫入:優化技術與實踐 - TDengine Database 時序數據庫

深入探索 Schemaless 寫入:優化技術與實踐 - TDengine Database 時序數據庫

詳細代碼見如下鏈接:

在架構(gou)優化過程中,我們還發現內存使用(yong)也可以進行優化。

在數據解析過程中,將數據轉換為無(wu)架構(schemaless)格式(shi)時(shi),對測量值(measure)、標簽(tag)和(he)列(col)進行(xing)了(le)大量的內存(cun)分(fen)配和(he)拷貝操(cao)作。這些操(cao)作雖然常見,但并非必要(yao),存(cun)在優化(hua)空間:

  • 在解析數據時,不直接進行數據的拷貝和內存分配。而是記錄下每個數據項在原始數據中的指針位置和長度。
  • 在數據需要最終寫入數據庫前,再根據這些記錄的位置和長度信息,從原始數據中直接拷貝相關數據。

如下:

st,t1=3,t2=4,t3=t3 c1=3i64,c3="passit",c2=false,c4=4    1626006833639000000

1)t1/t2/t3/c1/c3/c2 全部?calloc,拷貝(bei)到(dao)新的內存(cun)

typedef struct {
char*    key;
uint8_t  type;
uint16_t length;
char*    value;
uint32_t fieldSchemaIdx;
} TAOS_SML_KV;
深入探索 Schemaless 寫入:優化技術與實踐 - TDengine Database 時序數據庫

2)直(zhi)接(jie)指(zhi)針記錄位置,避免內存分配拷貝(bei)

typedef struct {
char *measure;
char *tags;
char *cols;
char *timestamp;
char *measureTag;

int32_t measureLen;
int32_t measureTagsLen;
int32_t tagsLen;
int32_t colsLen;
int32_t timestampLen;

  SArray colArray;
} SSmlLineInfo;
深入探索 Schemaless 寫入:優化技術與實踐 - TDengine Database 時序數據庫

如何縮短?

  • 時間精度轉換優化

直(zhi)接尋址代替條件判斷,注意溢出的(de)處理。

if(fromPrecision == ){}
else if( fromPrecision == ){}
else {}
int64_t smlToMilli[3] = {3600000LL, 60000LL, 1000LL};
int64_t unit = smlToMilli[fromPrecision - TSDB_TIME_PRECISION_HOURS];
if (unit > INT64_MAX / tsInt64) {
return -1;
}
tsInt64 *= unit;
  • Json 解析優化

因(yin)為寫入(ru)的 Json 數據(ju)格(ge)式基本固定,所以(yi)(yi)可以(yi)(yi)提前計算出(chu)各個(ge)元素(metric, timestamp, value, tags)的偏移(yi)位置,直接(jie)偏移(yi)到相應位置處理。

[
{ 
"metric": "meter_current",
"timestamp" : 1346846400,
"value": 18,
"tags": {
"location": "上海",  
"id": "d1001"
    }
},
{}
]
  • 判斷邏輯優化

每次判斷最大限度(du)的減少信息熵,將概率最大的 if 條件放(fang)在前面判斷。(i64 / u64 / i8 / u8 / true / L”” )

if( str equals "i64"){}
else if( str equals "i32"){}
else if( str equals "u8"){}
···
if(str[0] equals "i"){}
else if(str[0] equals "u"){}
...

其他優化

  • likely / unlikely

根(gen)據代碼(ma)執(zhi)行的概(gai)率(lv),指導編(bian)譯(yi)器優(you)化指令流水(shui)線的加載順(shun)序(xu)。

if(unlikely(len == 0 || (len == 1 && data[0] == '0'))){
return taosGetTimestampNs()/smlFactorNS[toPrecision];
}

程序日志(zhi)頻繁打印,也會導致(zhi)性能下降。我們在測試中發現,每批的統計(ji)信息打印會導致(zhi)耗時(shi)占用上升 10% 左右。

性能優化對比

深入探索 Schemaless 寫入:優化技術與實踐 - TDengine Database 時序數據庫

在 TDengine 3.0 版(ban)本(ben)與 2.6 版(ban)本(ben)的對比(bi)中,可以看到,line 協議性能(neng)提升了(le) 2.5 倍,telnet 提升了(le) 2 倍,而 json 的提升接(jie)近 5 倍。

性能分析工具

火焰圖

深入探索 Schemaless 寫入:優化技術與實踐 - TDengine Database 時序數據庫

perf 工具

通過 perf top -p 111290 -g 分析,可以看到 CPU 占用率(lv)很高(gao)。

深入探索 Schemaless 寫入:優化技術與實踐 - TDengine Database 時序數據庫

深入探索 Schemaless 寫入:優化技術與實踐 - TDengine Database 時序數據庫

結語

我們在進行性(xing)能(neng)優化前,首先需全面了解系統的流程(cheng)和(he)架構,確保對其有深刻認(ren)識。性(xing)能(neng)優化應著重關注以下三個方面:

  1. 架構評估:優秀的性能建立在合理且高效的架構之上。首先檢查架構設計的合理性和效率,這是提升性能的基礎。
  2. 識別并解決性能瓶頸:在良好的架構基礎上,應優先解決主要的性能瓶頸,逐步優化次要問題,以實現持續的性能提升。
  3. 性能分析方法:利用火焰圖分析各函數的調用耗時(寬度),對于一些看不到調用棧的地方可以添加日志打印每步驟的耗時,以精確地識別和分析性能瓶頸。

通過綜合(he)考慮 CPU、存(cun)儲、網絡、編譯器及硬件等(deng)多(duo)個方(fang)面,并結合(he)程序本(ben)身的特點,大(da)家(jia)就可以實現有效的性(xing)能(neng)優化了(le)。最后,希(xi)望本(ben)篇(pian)文章能(neng)夠幫助到有需要的開發(fa)者,也歡(huan)迎大(da)家(jia)體驗 TDengine 的 Schemaless 寫入性(xing)能(neng)。