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