小 T 導(dǎo)讀:此前有人在某問(wèn)答網(wǎng)站上發(fā)布了這樣一個(gè)問(wèn)題:既然部分時(shí)序數(shù)據(jù)庫(kù)如 InfluxDB、TimescaleDB 是基于關(guān)系型、非時(shí)序數(shù)據(jù)庫(kù) PostgreSQL 開發(fā)而來(lái),那在時(shí)序數(shù)據(jù)場(chǎng)景下,能否用 MySQL/MongoDB 這類數(shù)據(jù)庫(kù)去代替時(shí)序數(shù)據(jù)庫(kù)(Time-Series Database)使用?對(duì)于此問(wèn)題,濤思數(shù)據(jù)資深研發(fā)工程師試圖從原理和實(shí)踐出發(fā)為同樣有此疑問(wèn)的朋友作出解答。
從數(shù)據(jù)庫(kù)的定義來(lái)看,數(shù)據(jù)庫(kù)就是一個(gè)數(shù)據(jù)管理系統(tǒng),是用來(lái)存放數(shù)據(jù)文件的一個(gè)軟件,它能夠支持用戶的添加、修改、刪除、查詢等操作。因此從定義上講,時(shí)序數(shù)據(jù)庫(kù)和關(guān)系/非關(guān)系型數(shù)據(jù)庫(kù)是一樣的,都是用來(lái)存放數(shù)據(jù)的。但因?yàn)榇鎯?chǔ)的數(shù)據(jù)特點(diǎn)不同,這兩類數(shù)據(jù)庫(kù)的應(yīng)用場(chǎng)景也不盡相同:
- 關(guān)系型數(shù)據(jù)庫(kù):主要用來(lái)存儲(chǔ)結(jié)構(gòu)化數(shù)據(jù),使用實(shí)物保證數(shù)據(jù)一致性,使用 SQL 語(yǔ)言來(lái)進(jìn)行查詢操作。這類數(shù)據(jù)庫(kù)的典型代表主要包括 MySQL、Oracle、SQL Server 等。
- 非關(guān)系型數(shù)據(jù)庫(kù):主要用來(lái)存儲(chǔ)非結(jié)構(gòu)化數(shù)據(jù),數(shù)據(jù)可以不通過(guò)驗(yàn)證進(jìn)行存儲(chǔ),使用 JSON 數(shù)據(jù)對(duì)象進(jìn)行查詢操作。其典型代表主要有 MongoDB、Redis 等。
而時(shí)序數(shù)據(jù)庫(kù)主要用于存儲(chǔ)實(shí)時(shí)數(shù)據(jù),最明顯的特點(diǎn)就是每條數(shù)據(jù)都會(huì)帶有時(shí)間戳屬性,在電力、石化、冶金、智能汽車、監(jiān)控等領(lǐng)域應(yīng)用較為廣泛。這類 Database 的典型代表主要包括 TDengine、InfluxDB、TimescaleDB 等。下面直切主題,我們來(lái)討論一下關(guān)系/非關(guān)系型數(shù)據(jù)庫(kù)是否能替代時(shí)序數(shù)據(jù)庫(kù)。
能否用關(guān)系/非關(guān)系型數(shù)據(jù)庫(kù)代替時(shí)序數(shù)據(jù)庫(kù) ?
事實(shí)上,如果數(shù)據(jù)采集頻率少,數(shù)據(jù)量不大的話,使用關(guān)系/非關(guān)系型數(shù)據(jù)庫(kù)代替時(shí)序數(shù)據(jù)庫(kù)是完全沒(méi)有問(wèn)題的。但如果從長(zhǎng)遠(yuǎn)角度來(lái)看,這種做法卻存在著很大的風(fēng)險(xiǎn),具體原因還要從時(shí)序數(shù)據(jù)庫(kù)的特點(diǎn)講起。
時(shí)序數(shù)據(jù)具備采集頻率高、數(shù)據(jù)量大、寫操作為主讀操作為輔、很少有更新或刪除操作、卻有統(tǒng)計(jì)聚合等實(shí)時(shí)計(jì)算操作等特點(diǎn),關(guān)系/非關(guān)系型數(shù)據(jù)庫(kù)很難滿足這樣高的性能需求。在大數(shù)據(jù)場(chǎng)景下,如果性能達(dá)不到要求,數(shù)據(jù)沒(méi)有辦法被有效存儲(chǔ)的話,那么這樣的數(shù)據(jù)庫(kù)是無(wú)法代替時(shí)序數(shù)據(jù)庫(kù)的。
舉一個(gè)簡(jiǎn)單的例子,在相同的測(cè)試環(huán)境(16 核 64G 內(nèi)存)下,以傳統(tǒng)的關(guān)系型數(shù)據(jù)庫(kù) MySQL 和時(shí)序數(shù)據(jù)庫(kù) TDengine 為例,做一下 benchmark 的對(duì)比測(cè)試 :
分別使用 MySQL 自帶的 benchmark 工具 mysqlslap 和 TDengine 自帶的 benchmark 工具taosbenchmark,設(shè)置 16 個(gè)線程,寫入單表 10 萬(wàn)條記錄,表結(jié)構(gòu)為 1 個(gè) timestamp 類型,2 個(gè) int 類型,2 個(gè)字符串類型,測(cè)試結(jié)果如下:
MySQL——
mysqlslap -uroot -p1234 –concurrency=16 –number-of-queries=100000 –create-sc hema=tests –query=”INSERT INTO meters(c0, c1, c2, c3) VALUES (RAND() * 100, RAND() * 100, uuid(), uuid())”
TDengine——
taosBenchmark -b int,int,binary(128),binary(128) -n 100000 -t 1 -T 16
從以上對(duì)比測(cè)試結(jié)果可以看出在同樣寫入 10 萬(wàn)條記錄的情況下,MySQL 使用自帶的 mysqlslap 工具需要 75 秒完成,而 TDengine 使用自帶的 taosBenchmark 只需要不到 1 秒。在差距如此巨大的結(jié)果中,我們可以得出一個(gè)結(jié)論——使用 MySQL 代替時(shí)序數(shù)據(jù)庫(kù)處理時(shí)序數(shù)據(jù)是比較困難的。當(dāng)然由于測(cè)試工具不同,這里只是做一個(gè)示例,測(cè)試本身算不上嚴(yán)謹(jǐn)。下面我會(huì)從一些具體的企業(yè)案例出發(fā),再為大家做下分析。
從具體的案例看大數(shù)據(jù)的存儲(chǔ)問(wèn)題
其實(shí),想要回答這個(gè)問(wèn)題,具體的企業(yè)案例實(shí)踐才是最好、最真實(shí)的答案。業(yè)內(nèi)人應(yīng)該都知道,時(shí)序數(shù)據(jù)庫(kù)是近幾年隨著物聯(lián)網(wǎng)等技術(shù)的發(fā)展才逐漸流行起來(lái)的,在此之前,各行各業(yè)的企業(yè)可選的數(shù)據(jù)庫(kù)方案都十分有限,以車聯(lián)網(wǎng)企業(yè)為例,行業(yè)中最普遍的選擇就是 MongoDB、HBase 一類的傳統(tǒng)大數(shù)據(jù)解決方案。
但隨著業(yè)務(wù)的發(fā)展,數(shù)據(jù)量的不斷攀升,這些企業(yè)或多或少都遭遇了數(shù)據(jù)架構(gòu)危機(jī),甚至阻礙了業(yè)務(wù)的發(fā)展,不得不考慮進(jìn)行數(shù)據(jù)架構(gòu)的迭代和遷移。下面我從 MySQL、MongoDB、HBase 三個(gè) database 維度列舉企業(yè)案例,進(jìn)行說(shuō)明。
MySQL
在柳工的工業(yè)車聯(lián)網(wǎng)應(yīng)用 LiuGong iLink 中,由于應(yīng)用層不合理的復(fù)雜查詢和歷史數(shù)據(jù)的高頻寫入,導(dǎo)致 MySQL 處理速度緩慢,甚至容易宕機(jī),嚴(yán)重影響用戶體驗(yàn)。在分析原因后,他們得出了一個(gè)結(jié)論:關(guān)系型數(shù)據(jù)庫(kù)并不適用于存儲(chǔ)海量的時(shí)序數(shù)據(jù),在海量數(shù)據(jù)聚合計(jì)算、抽稀等業(yè)務(wù)中效率很低。從這個(gè)結(jié)論出發(fā),他們開始針對(duì)時(shí)序數(shù)據(jù)庫(kù)進(jìn)行選型。
由于其業(yè)務(wù)場(chǎng)景與 TDengine 的“一個(gè)設(shè)備采集點(diǎn)一張表”的理念十分吻合,且 TDengine 可以支持對(duì)大數(shù)據(jù)進(jìn)行聚合和降采樣查詢等操作,能夠經(jīng)有效改善 MySQL 的數(shù)據(jù)痛點(diǎn)問(wèn)題,又經(jīng)過(guò)嚴(yán)謹(jǐn)?shù)恼{(diào)研和測(cè)試,最終他們決定遷移至 TDengine。
以一個(gè)真實(shí)場(chǎng)景看一下遷移效果:在替換 TDengine 之前,該項(xiàng)目每天都有一些業(yè)務(wù)報(bào)表需要展示,每一小時(shí)需統(tǒng)計(jì)一次下一個(gè)時(shí)區(qū)內(nèi)所有設(shè)備的數(shù)據(jù),這個(gè)流程在 MySQL 中經(jīng)常需要耗時(shí)1小時(shí)以上,無(wú)法正常執(zhí)行后續(xù)業(yè)務(wù)。而換到TDengine后,整個(gè)出表流程只需要 10 秒左右。
查詢對(duì)比如下圖所示:
參考資料:https://www.taosdata.com/blog/2022/05/17/8473.html
MongoDB & HBase
對(duì)于這兩大數(shù)據(jù)庫(kù)的應(yīng)用坑點(diǎn),零跑汽車可以說(shuō)是相當(dāng)有發(fā)言權(quán)了。作為一家典型的新能源車企,零跑汽車在數(shù)據(jù)存儲(chǔ)選擇上一直都是 MongoDB 和 HBase,隨著業(yè)務(wù)的加速擴(kuò)張,出現(xiàn)了寫入速度太慢、支撐成本過(guò)高等問(wèn)題。
用 MongoDB 存儲(chǔ)數(shù)據(jù)會(huì)將數(shù)據(jù)全部存儲(chǔ)在內(nèi)存中,過(guò)高的存儲(chǔ)成本導(dǎo)致只能存儲(chǔ)一段時(shí)間內(nèi)的數(shù)據(jù),且存儲(chǔ)的數(shù)據(jù)格式需要經(jīng)過(guò)業(yè)務(wù)組織處理,不僅業(yè)務(wù)變更不靈活,可以做的業(yè)務(wù)也非常有限,而 HBase 本身就是一個(gè)很重的數(shù)據(jù)庫(kù),搭建 HBase 需要整套 HDFS 做支撐,使用、運(yùn)維、人力等成本都很高。
在應(yīng)用 TDengine 進(jìn)行架構(gòu)升級(jí)后,壓縮性能直接提升了 10 到 20 倍,降低存儲(chǔ)壓力的同時(shí)解決了數(shù)據(jù)存儲(chǔ)成本高的問(wèn)題,也解決了以前 HBase 入庫(kù)不及時(shí)的問(wèn)題,可以用更少的服務(wù)器資源入庫(kù)更多的數(shù)據(jù),節(jié)省更多成本。同時(shí)業(yè)務(wù)靈活性也有了極大提升,不用再像 MongoDB 一樣,在查詢前還需要根據(jù)業(yè)務(wù)加工出需求數(shù)據(jù),TDengine 的列式存儲(chǔ),直接以 SQL 計(jì)算即可。
寫在最后
從上面的諸多論證中我們可以得出最終結(jié)論,如果你面對(duì)的也是時(shí)序大數(shù)據(jù)場(chǎng)景,時(shí)序數(shù)據(jù)庫(kù)才是最正確、最合理的選擇,如果因?yàn)閿?shù)據(jù)量尚小就選擇通用數(shù)據(jù)庫(kù),那后面各種棘手問(wèn)題也會(huì)接踵而至,包括開發(fā)效率慢、運(yùn)行效率低、運(yùn)維成本高、應(yīng)用推出慢、小數(shù)據(jù)量場(chǎng)景下私有化部署太重等諸多問(wèn)題。在數(shù)據(jù)庫(kù)的選型上,“對(duì)癥下藥”才是有利于業(yè)務(wù)發(fā)展的良策。
TDengine | 時(shí)序數(shù)據(jù)庫(kù)_開源時(shí)序數(shù)據(jù)庫(kù)_實(shí)時(shí)數(shù)據(jù)庫(kù) – 濤思數(shù)據(jù)點(diǎn)擊了解更多 TDengine Database 的具體細(xì)節(jié)。