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

TDengine 上關于 Lua 連接器開發的一些總結和思考

李振鵬

2022-02-14 /

為什么是 TDengine

首先,TDengine Database 符合我的審美。盡管我一直在關注時序數據庫(Time-Series Database,TSDB)這(zhe)個(ge)(ge)領域,但直到遇見 TDengine 才算找到符合預期的(de)(de)(de)產品(pin)。理想(xiang)中的(de)(de)(de)產品(pin)所采用(yong)的(de)(de)(de)語(yu)言應(ying)該自(zi)帶運行(xing)時,屬于強類型(xing)的(de)(de)(de)編(bian)譯(yi)語(yu)言,這(zhe)樣打包編(bian)譯(yi)后(hou)對(dui)環境的(de)(de)(de)依賴(lai)比(bi)較(jiao)小,用(yong)起來比(bi)較(jiao)方(fang)便;代碼工程(cheng)應(ying)該盡可能精巧(qiao),便于理解掌握;產品(pin)運行(xing)起來要(yao)快(kuai),資源消耗相對(dui)較(jiao)小。如果(guo)一個(ge)(ge)產品(pin)像一輛卡車(che),載重 10 噸(dun),自(zi)重 5 噸(dun),它顯然不是(shi)(shi)理想(xiang)選(xuan)項。以上解釋都是(shi)(shi)先射箭后(hou)畫(hua)靶,當然 C 語(yu)言才是(shi)(shi)決定(ding)項,這(zhe)是(shi)(shi)我在 emacs 環境中配置最完善的(de)(de)(de)語(yu)言。

TDengine Database 的每個 Dnode 節點既負(fu)責存儲(chu)也負(fu)責計(ji)算,在(zai)時興“計(ji)算與存儲(chu)分離”的當下,這(zhe)個技術方案(an)顯(xian)得有些另類。不過實踐才是(shi)檢(jian)驗真理的標(biao)準,目(mu)前還沒看到明顯(xian)問題,我們會在(zai) K8s 的 CSI 方案(an)中繼續測試。

Lua連接器

我為 TDengine 編寫了 Lua 版的連接器,主要面向兩個用戶群體,一是 OpenResty(Nginx+Lua),另一個是 Skynet。這兩個產品(pin)(pin)也(ye)是我格外欣賞(shang)的(de)兩款開源(yuan)產品(pin)(pin)。經過測(ce)試(shi),在我的(de)個人筆記本(ben)電腦(SSD 硬盤、8G RAM)上,基于 TDengine 2.0.18,用我自己編寫(xie)的(de) Lua 連接器單線程(cheng)寫(xie)入只有 3 個列(lie)的(de)記錄(lu)(時間戳、整數、tag),平均每秒可寫(xie)入 1 萬(wan)條,見下圖。我已提交(jiao)了 benchmark 測(ce)試(shi)代碼,大家(jia)可以在自己的(de)工作(zuo)環境(jing)下測(ce)試(shi)感興趣的(de)條目。

Lua demo

目前(qian)社區里(li)看(kan)到(dao)(dao)的(de) Lua 連接器分別基于 Lua5.1 和(he) Lua5.3,這主要(yao)是因(yin)為 OpenResty 采用的(de)是基于 5.1 版本的(de) LuaJIT,而 skynet 雖然(ran)跟(gen)隨 Lua 社區升級到(dao)(dao)了(le) Lua5.4,但(dan)我并(bing)沒用遇到(dao)(dao)兼容問題,所以(yi)只在(zai)本地針(zhen)對 Lua5.4 的(de)兼容性進行了(le)驗(yan)證,并(bing)沒有提(ti)交。

從(cong) Lua 角(jiao)度(du)來看(kan),Lua5.1 和 Lua5.2 及以上版(ban)本屬(shu)于(yu)兩(liang)個世界。這主要是(shi)因(yin)為 Lua5.2 版(ban)本上的(de)(de)(de)一個重(zhong)要改進——“yieldable pcall and metamethods”。Lua5.2 這個改進允許調用(yong) C 函數時不馬上返回,而這是(shi)異步操作(zuo)必須(xu)的(de)(de)(de)特性。所以大家在基于(yu) Lua5.1 API 的(de)(de)(de) OpenResty 社區(qu)里經(jing)常看(kan)到有人(ren)在問如何(he)解決“attempt to yield across C-call boundary”問題。

我在實現連接器時(shi)也必須(xu)面(mian)對這(zhe)個問題,當然也有其他 API 差(cha)異,所(suo)以(yi)編寫了兩個版本(ben)的(de)代碼,而不是用編譯開(kai)關控制。事實上,有別于 OpenResty 過度依賴 LuaJIT,我更贊同云風的(de)觀點(dian),跟隨(sui)主流社區升級版本(ben)帶來的(de)綜合收益應該高于在某個版本(ben)上定制。

OpenResty 用戶可以直接在 http 請求處理中通過 Lua 連接器訪問 TDengine Database,如同使用 MySQL 的體驗一樣,不需要交給服務器處理,整體架構非常簡潔。由于在此 Lua 版本上只能實現同步訪問數據庫,出于性能考慮,我試驗了一個連接池,避免頻繁地建立然后釋放數據庫連接。很遺憾的是,Lua 的非搶占特性導致一段代碼未執行完時不會釋放 CPU,所以并沒有機會處理其他請求,觀察到的 WaterMark 也一直是 1,這個問題如何解決,暫時還沒有結論。如果在目前基礎上想盡可能地多榨出一點性能來,我的建議是盡可能推遲從連接池里申請連接,并盡可能提前歸還連接。

Skynet 用(yong)戶也可(ke)以(yi)(yi)仿照(zhao) MySQL 的(de)使用(yong)方式來(lai)使用(yong) Lua 連(lian)接(jie)器,不(bu)過我(wo)建(jian)議(yi)遵(zun)從(cong) Skynet 的(de)建(jian)議(yi),在 simpledb 這樣的(de)服務(wu)中保持連(lian)接(jie),做具體的(de)請求處理工作。因(yin)為 Skynet 本身實現了比較完善的(de) Actor 模型,所(suo)以(yi)(yi)我(wo)并不(bu)確(que)定目前的(de)方案有(you)沒有(you)帶(dai)來(lai)瓶頸(jing)(jing)。如果同(tong)步訪問帶(dai)來(lai)瓶頸(jing)(jing),可(ke)以(yi)(yi)嘗試一下異(yi)步調用(yong),但因(yin)為 TDengine 關于異(yi)步的(de)設計中要求前一個(ge)訪問結果返回后才(cai)能執行下一個(ge)訪問,所(suo)以(yi)(yi)異(yi)步調用(yong)帶(dai)來(lai)的(de)瓶頸(jing)(jing)會向哪(na)里轉(zhuan)移,目前也不(bu)清楚。

盡管可能性很小,但是連接器不能回避數據庫連接失效的問題。幸好 TDengine 提供了一個心跳機制,用來檢測連接是否有效。目前實現(xian)的連接器還沒有(you)完(wan)善這(zhe)個(ge)功能,所以(yi)如果通往數(shu)據庫(ku)的鏈路失效,需要應用重建連接。

在實際生產環境中,我們發現 TDengine Dnode 向 Client 端返回的字符串類型的數據并沒有附加結尾符,而出于性能考慮,在向連接器返回數據時也沒有重新申請內存做一次拷貝以追加結束符,進而導致往數據庫中存入網絡類型 4G 和 WIFI,在查詢時返回“4GFI”這樣的結果。這是一個隱蔽性很強的默認規則,其他語言連接器的設計者注意提前規避潛在問題。

自定義函數

自定義函數UDF)能降(jiang)低應(ying)用的復雜度(du),或(huo)者(zhe)(zhe)實現(xian)預置(zhi)查詢函數無法實現(xian)的功能,我判斷 Lua 是最適合承(cheng)擔這個使命的語言。因為(wei) Lua 的設計初衷就是與 C 語言集成,兩(liang)者(zhe)(zhe)堪稱(cheng)倚天屠龍。

目前 TDengine 官方已經實現了用戶自定義函數的框架,基于 Lua5.1 實現了基礎模型,并集成了 Lua5.1。因(yin)為(wei) Lua 社區的(de)(de)分裂狀(zhuang)態,預置的(de)(de) Lua 開(kai)發庫給我的(de)(de)開(kai)發工作帶來一(yi)些小麻(ma)煩,用戶肯定不(bu)能同時使(shi)用兩個 Lua 版(ban)本,最(zui)終還是要在 TDengine 中同時集成 Lua5.1 和一(yi)個高版(ban)本(即將發布版(ban)本為(wei) Lua5.4.4),靠宏開(kai)關選(xuan)擇一(yi)個 Lua 版(ban)本參與編譯。

具體實現起來,需(xu)要分別為兩個版(ban)本(ben)的(de) C API 設計接口(kou),Lua 每個版(ban)本(ben)升級都會帶來一(yi)(yi)些功能上的(de)變化和升級,因此能否(fou)抽(chou)象(xiang)出一(yi)(yi)套通用接口(kou)對 Lua 用戶屏(ping)蔽差異,對于這(zhe)個問題的(de)答案(an)我是持比較悲觀的(de)態度的(de)。

展望

以上就是我在使用 TDengine 時的經驗匯總。目前,連接器已部署在我們的生產環境上,并經歷了兩次較大規模的生產活動,輕松完成了使命。接下來會在項目應用中繼續完善上面提到的問題,支持用 Lua 實現UDF是我的下一個工作重點,這將進一步降低應用的復雜度。