10.16 巨頭垂涎卻不能染指,loT 數據庫風口已至

巨頭垂涎卻不能染指,loT 數據庫風口已至

作者 | 馬超

出品 | CSDN(ID:CSDNnews)

隨著移動端發展走向飽和,現在整個IT行業都期待著“萬物互聯”的物聯網時代所帶來的流量紅利,前期筆者也曾經撰文介紹國產物聯網操作系統的情況(https://blog.csdn.net/BEYONDMA/article/details/101147942),我們可以看到BAT等巨頭們的邏輯是要讓其它公司免費使用其OS上車控制住入口,引導使用物聯網行業新秀接入其loT雲平臺,創業成者直接收購,無縫整合進入自身體系;失敗者任其自生自滅,從而讓巨頭自身完全立於不敗之地。

一般物聯網的信息傳遞流程如下,先由終端接入層完成數據的採集,再插入數據庫,然後再進行展示及後續的大數據分析。

在終端入口層我們可以看到國內廠商相繼發佈並開源了鴻蒙LiteOS、Tencent Tiny OS、Ali Things 3.0,展示分析及大數據層各巨頭不缺少相應強大手段,不過在承上啟下的物聯網數據層還是巨頭們的留白,所以目前還沒有哪家巨頭能夠完全控制整個物聯網的信息鏈條,物聯網數據庫將會迎來一波巨大的發展機遇。

巨头垂涎却不能染指,loT 数据库风口已至
巨头垂涎却不能染指,loT 数据库风口已至

天下武功唯快不破,傳統數據庫沒有物聯網的速度基因

BAT們並不是沒有殺手組級的數據庫產品,比如前幾天阿里的OceanBase就以很好的成績在TPC-C測試中奪冠,筆者也曾經撰文介紹過OceanBase的相應情況(https://blog.csdn.net/BEYONDMA/article/details/102089673),不過傳統數據庫其底層邏輯是不能錯,比如在“雙十一”秒殺時,在併發請求超限的極端情況下,數據庫可以放棄處理某些請求,但是已經處理的請求是絕不能允許出錯的。

而且“增刪改查”是傳統數據庫的最基本任務,在執行上述任務的過程中對於準確性的要求是第一位的。

而物聯網時代產生的數據量比互聯時代時代大了一個數量級,但是其數據的價值密度,也相對較低,loT終端往往都是一些傳感器,其自身單點設備可靠性有限,一般都是靠多點這冗餘相互驗證來保證整體穩定性的,但如果數據不能及時採集就會丟失,因此物聯網時對於數據庫的要求聚焦於速度與效率,這正是時序數據庫所擅長的。

如果用汽車類比,傳統數據庫的最高目標是做類似邁巴赫、賓利這樣的頂級家用轎車以安全優先;而物聯網則要做類似於法拉利這樣為速度而生的跑車。

巨头垂涎却不能染指,loT 数据库风口已至

時序數據庫的數據存儲設計

在典型的物聯網場景中,往往有許多各類不同的終端設備,佈署在不同的位置,去採集各種數據,比如某一生產區有5萬個終端,每個終端每10秒發送一次數據。那麼每年會產生1600億個數據點。

而這些數據都是順序產生的,並且每次監測產生數據的格式全部是一致的、結構化的,並且沒有刪除和修改的需求,所以時序數據庫一般使用LSM Tree模型,從而將隨機寫轉化為順利寫,以提升效率。典型的LSM模型如下:

巨头垂涎却不能染指,loT 数据库风口已至

WAL:在設計數據庫的時候經常被使用,當插入一條數據時,數據先順序寫入 WAL 文件中,之後插入到內存中的 MemTable 中。這樣就保證了數據的持久化,不會丟失數據,並且都是順序寫,速度很快。當程序掛掉重啟時,可以從 WAL 文件中重新恢復內存中的 Cache。

Cache(MemTable):Cache 對應的就是 WAL 文件,是該文件內容在內存中的存儲結構,通常用 SkipList 來實現。Cache一般 k-v 數據的寫入、刪除以及讀取的操作接口。其內部將 k-v 對按照 key 值有序存儲,這樣方便之後快速序列化到 SSTable 文件中,仍然保持數據的有序性。

TSM File:由於內存是有限的,通常時序數據庫會設一個閥值,當Cache佔用的內存達到閥值後就自動轉換為TSM File,一般來說TSM file會使用與Cache不同的文件格式,對查詢及壓縮進行優化。

Compactor:一般就是壓縮轉存的模塊,當Cache到達閾值後使用Compactor將其轉錄到TSM File中。

寫操作過程:在這種模型下寫入是相當快速的,只需要在 WAL 文件中順序寫入本輪採集的數據,然後轉錄入內存Cache,而在Cache到達閾值後的轉錄為TSM File操作,不是每輪數據採集都需要執行,效率比傳統關係型數據庫的存儲方式肯定高得多。

巨头垂涎却不能染指,loT 数据库风口已至

當然以上是時序數據庫的通用做法,而某些時序數據庫針對物聯網場景,有針對性的做了很多優化工作,其中TDEngine就使用了數據時序性和結構化的特點,要求對每個採集設備單獨建表。

其實我們剛剛也提到了每個物聯終端所產生的數據其實都是時序且結構化的,所以對每個設備單獨建表能夠充分發揮出數據時序化的優勢,進一步提升效率。

Prometheus為了效率則更是隻支持Numeric data的處理,字符串類型是不被支持的,不過想想這也合理,因為物聯網所採集的數據一般都不是文字型的,放棄對於字符串的支持也未嘗不可。

巨头垂涎却不能染指,loT 数据库风口已至

古老的話題:時序數據庫編程語言之爭

我們前文也提到了可以把時序數據庫比做以速度為生的跑車,不過之前主流的時序數據庫一般都是用Go或者Java開發的。

其中使用C開發的TimescaleDB還是基於傳統關係型數據庫PostgreSQL 進行的二次開發,本質上並不是完整的時序數據庫。

巨头垂涎却不能染指,loT 数据库风口已至

所以前一段時間使用C語言開發的國產時序數據庫TDEngine宣佈開源並正式發佈後,在性能上對於其它時序數據庫形成全面碾壓的態勢其實並不奇怪。原因無外乎有以下兩點:

1.數據庫做為一種特殊的應用軟件,需要更多的底層操作:我在之前的文章中也曾經介紹過TDEngine為了減少線程數量,降低上下文切換的損耗,自身實現了一個定時器服務,詳見(https://blog.csdn.net/BEYONDMA/article/details/98473143)。

也就是數據庫在很多時候不能直接使用系統調用,那樣效率太低。而在實現系統級功能時C語言的優勢非常明顯。

2.大量的數據讀寫及索引操作,會頻繁觸發GC:我們知道無論是GO還是JAVA都會有自動垃圾的清理機制(GC),雖然據稱華為方舟編譯器的出現將大幅提升GC的效率,不過無論如何物聯網天量的數據讀取,尤其是索引操作,肯定會頻繁觸發GC,而這也必將犧牲一部分性能。

其實以速度至上的物聯網時序數據庫,並不太能發揮出GO及JAVA等高級語言的長處,而C語言在這種平臺級軟件的開發上反而有得天獨厚的優勢。

巨头垂涎却不能染指,loT 数据库风口已至

時序數據庫整合趨勢明顯

TDEngine這種C語言的數據庫能夠戰勝InfluxDB、OpenTSDB我並不感到奇怪,不過當我看到測試報告(https://www.taosdata.com/downloads/TDengine_Testing_Report_cn.pdf)發現在單機環境下連接數增加到20個TDengine的處理還能遊刃有餘,而openTSDB等數據庫達到3個連接就出現crash現象,這個情況讓筆者感到特別好奇,由於以上項目都是開源的,所以我又翻閱了一下相關代碼發現最重要的原因是TDengine使用線程處理連接,而其它時序庫大多通過folk進程處理連接。

巨头垂涎却不能染指,loT 数据库风口已至

當然TD將緩存、消息隊列等功能整合的設計也非常值得稱道,其架構如下所示:

巨头垂涎却不能染指,loT 数据库风口已至

從https://github.com/taosdata/TDengine/blob/master/src/client/src/tscServer.c中的函數tscGetConnToMgmt,

其實是使用taosGetConnFromCache函數從緩存中取鏈接,這樣速度肯定會提高,具體代碼如下:

void tscGetConnToMgmt(SSqlObj *pSql, uint8_t *pCode) {

STscObj *pTscObj = pSql->pTscObj;

if (pSql->retry < 1) {

*pCode = 0;

pSql->retry++;

void *thandle = taosGetConnFromCache(tscConnCache, tsServerIp, TSC_MGMT_VNODE, pTscObj->user);//有緩存層

if (thandle == ) {

SRpcConnInit connInit;

memset(&connInit, 0, sizeof(connInit));

connInit.cid = 0;

connInit.sid = 0;

connInit.meterId = pSql->pTscObj->user;

connInit.peerId = 0;

connInit.shandle = pTscMgmtConn;

connInit.ahandle = pSql;

connInit.peerPort = tsMgmtShellPort;

connInit.spi = 1;

connInit.encrypt = 0;

connInit.secret = pSql->pTscObj->pass;

connInit.peerIp = tsServerIpStr;

thandle = taosOpenRpcConn(&connInit, pCode);

}

pSql->thandle = thandle;

pSql->ip = tsServerIp;

pSql->vnode = TSC_MGMT_VNODE;

}

}

TDengine緩存功能實現的https://github.com/taosdata/TDengine/blob/master/src/client/src/tscCache.c,其基本的工作原理總結是這樣,有空建議大家細讀:

1.初始化:首先初始化緩存對象SConnCache,再初始化哈希表connHashList,並調用taosTmrReset,重置timer(這也就是咱們上次解讀的timer)

2.鏈接加入緩存:首先通過ip、port、username計算其哈希值(hash),然後將此鏈接(connInfo)加入connHashList[hash]對應的pNode節點,pNode本身又是一個雙鏈表,也會根據添加時間將哈希值相同的connInfo排序,放入pNode雙鏈表中。注意這裡pNode是哈希表connHashList的一個節點,而其自身也是一個鏈表。

3.將鏈接由緩存中取出:根據ip、port、username計算其哈希值(hash),取出connHashList[hash]對應的pNode節點,再從pNode當中取出ip、port與需求相同的元素。

而這樣的設計,對比建立幾個鏈接就會崩潰的OpenTSDB真是要高出幾個數量級。

巨头垂涎却不能染指,loT 数据库风口已至

寫在最後

隨著物聯網時代的到來,國產操作lot操作系統迎來一波集體的強勢崛起,但是國產IoT數據庫卻不似那麼興旺,除了Tdengine外,只有百度雲TSDB產品有對外發布,不過也不成熟。由於和傳統關係型數據庫底層邏輯不同,時序數據庫還屬於新興事物,這恰恰也是給我國相關產業彎道超車的一次機會。

而且筆者在本文中也提到了,時序數據庫在物聯網應用中還大有整合其它中間件的趨勢,可謂是風口已至,但巨頭未至,今後必將迎來巨大機遇期。

作者簡介:本文為CSDN博主馬超(ID:beyondma)的原創約稿文章。

【END】


分享到:


相關文章: