導(dǎo)讀:作為一家業(yè)務(wù)遍及多個(gè)國家及地區(qū)的物流公司,貨拉拉面臨的技術(shù)環(huán)境是非常復(fù)雜的,在云時(shí)代浪潮下基于混合云快速構(gòu)建環(huán)境搭建系統(tǒng)成為其必然的選擇。
作為一家業(yè)務(wù)遍及多個(gè)國家及地區(qū)的物流公司,貨拉拉面臨的技術(shù)環(huán)境是非常復(fù)雜的,在云時(shí)代浪潮下基于混合云快速構(gòu)建環(huán)境搭建系統(tǒng)成為其必然的選擇。但是在混合云上如何對基于各家云構(gòu)建的系統(tǒng)進(jìn)行有效的管理是個(gè)挑戰(zhàn),尤其對處于系統(tǒng)最底層的數(shù)據(jù)庫層面臨的問題、業(yè)務(wù)訴求、各方痛點(diǎn),是貨拉拉DBA團(tuán)隊(duì)現(xiàn)下所需要重點(diǎn)解決的。
目前DBA團(tuán)隊(duì)管理的數(shù)據(jù)存儲包括MySQL、Redis、Elasticsearch、Kafka、MQ、Canal等,為了保證監(jiān)控采樣的實(shí)時(shí)性,我們自研的監(jiān)控系統(tǒng)設(shè)置的采樣間隔為10秒,這樣每天都會(huì)產(chǎn)生龐大的監(jiān)控?cái)?shù)據(jù),監(jiān)控指標(biāo)的數(shù)據(jù)量達(dá)到20億+。前期由于管理實(shí)例少,監(jiān)控?cái)?shù)據(jù)量也少,所有數(shù)據(jù)都被存放到了MySQL中;之后隨著管理實(shí)例越來越多,使用MySQL來存儲規(guī)模日益龐大的監(jiān)控?cái)?shù)據(jù)越發(fā)力不從心,急需進(jìn)行升級改造。結(jié)合實(shí)際具體需求,通過對不同時(shí)序數(shù)據(jù)庫進(jìn)行調(diào)研,最終我們選擇了TDengine,順利完成了數(shù)據(jù)存儲監(jiān)控的升級改造。
一、監(jiān)控系統(tǒng)開發(fā)中遇到的問題
從存儲路徑來看,每種數(shù)據(jù)存儲都分布在多個(gè)區(qū)域,每個(gè)區(qū)域?qū)⒈O(jiān)控采樣數(shù)據(jù)投遞上報(bào)到消息總線,然后由消費(fèi)程序統(tǒng)?消費(fèi),消費(fèi)程序會(huì)將必要的告警數(shù)據(jù)更新到告警表,同時(shí)將監(jiān)控原始數(shù)據(jù)存儲到MySQL。比如,針對Redis這款數(shù)據(jù)存儲,監(jiān)控采樣間隔設(shè)置10秒,那么每天實(shí)例采樣次數(shù)就會(huì)達(dá)到3000萬+,監(jiān)控指標(biāo)累計(jì)6億+,數(shù)據(jù)量之龐大可見一斑。早期為了將數(shù)據(jù)存儲到MySQL中,同時(shí)也能很好地支持監(jiān)控繪圖的使用,每?次實(shí)例監(jiān)控采樣時(shí)都會(huì)計(jì)算出該實(shí)例全量監(jiān)控項(xiàng)采樣數(shù)據(jù),然后將本次采樣的結(jié)果作為?條記錄存儲下來。
即使通過這樣的優(yōu)化處理,在做時(shí)間跨度大的監(jiān)控繪圖時(shí),前端依然會(huì)出現(xiàn)延遲卡頓的問題,后端監(jiān)控?cái)?shù)據(jù)存儲的MySQL也壓力山大,經(jīng)常滿載,天天被吐槽。因此針對這種時(shí)間跨度大的查詢,我們專門開發(fā)了?系列的數(shù)據(jù)聚合調(diào)度任務(wù)——按照不同的時(shí)間跨度,提前將10秒采集間隔的監(jiān)控?cái)?shù)據(jù)做好聚合,監(jiān)控繪圖程序再根據(jù)不同的時(shí)間跨度選取不同的聚合數(shù)據(jù)表繪圖,以此解決長時(shí)間跨度監(jiān)控繪圖展示延遲卡頓的問題。
但這仍然治標(biāo)不治本。為了壓縮監(jiān)控?cái)?shù)據(jù)存儲空間,原始10秒間隔的監(jiān)控?cái)?shù)據(jù)表只能歸檔保留3天時(shí)間的監(jiān)控?cái)?shù)據(jù),但存儲大小也將近有200GB,加上與之相關(guān)的不同時(shí)間段的數(shù)據(jù)聚合表,存儲一下子突破300GB。這還只是Redis監(jiān)控?cái)?shù)據(jù)的存儲大小,加上其它數(shù)據(jù)存儲的監(jiān)控?cái)?shù)據(jù),至少需要1TB+空間的MySQL存儲。
數(shù)據(jù)集合任務(wù)管理復(fù)雜、后期監(jiān)控原數(shù)據(jù)回溯缺失、MySQL存儲空間日益增長帶來的隱患,都是亟待解決的問題。
二、時(shí)序數(shù)據(jù)庫選型
為了解決MySQL監(jiān)控?cái)?shù)據(jù)存儲的問題,我們把注意力轉(zhuǎn)移到了適合存儲監(jiān)控?cái)?shù)據(jù)的時(shí)序數(shù)據(jù)庫上。市面上各種時(shí)序數(shù)據(jù)庫產(chǎn)品琳瑯滿目,有老牌的,也有后起之秀,經(jīng)過?系列調(diào)研選型,我們選擇了時(shí)序數(shù)據(jù)庫TDengine,主要是因?yàn)槠渚邆涞娜缦聨状髢?yōu)點(diǎn):
·采用分布式架構(gòu),可支持線性擴(kuò)展
·數(shù)據(jù)存儲壓縮率超高
·集群模式支持多副本,無單點(diǎn)故障
·單機(jī)模式性能強(qiáng)悍
·安裝部署維護(hù)簡單
·SQL?持
·時(shí)間維度聚合查詢
·客戶端支持RESTful API
值得一提的是,TDengine的SQL原生語法支持時(shí)間維度聚合查詢,同時(shí)數(shù)據(jù)存儲壓縮率?存儲空間小,這兩點(diǎn)直接切中了我們的痛點(diǎn)。落地后實(shí)測相同數(shù)據(jù)的存儲空間只有MySQL存儲空間的十分之?甚至更少。還有?個(gè)驚喜是,在現(xiàn)有監(jiān)控?cái)?shù)據(jù)存儲(MySQL)頂不住的情況下,?臺8C16GB的單機(jī)版TDengine輕松就抗下目前所有監(jiān)控流量和存儲壓力,且運(yùn)行穩(wěn)定,基本沒有故障。
三、改造過程
TDengine用于存儲監(jiān)控?cái)?shù)據(jù)的超級表設(shè)計(jì)原則就是簡單高效,字段?般都比較少,每?種監(jiān)控項(xiàng)類型(INT、FLOAT、NCHAR等)的數(shù)據(jù)存儲都需要單獨(dú)建立?個(gè)超級表,超級表?般都有關(guān)鍵的ts、type、value字段,具體監(jiān)控項(xiàng)由type字段標(biāo)識,加上必要的tag及少量其它字段構(gòu)成。
之前監(jiān)控?cái)?shù)據(jù)存儲在MySQL的時(shí)候,每條數(shù)據(jù)記錄包含了該實(shí)例?次監(jiān)控采樣的所有監(jiān)控項(xiàng)(25+)數(shù)據(jù)。如果采用通用的監(jiān)控超級表設(shè)計(jì)原則,就需要改造采樣的數(shù)據(jù)結(jié)構(gòu),改造方式有兩種:
·改造監(jiān)控?cái)?shù)據(jù)投遞的數(shù)據(jù)結(jié)構(gòu)
·改造消費(fèi)程序消費(fèi)邏輯重組數(shù)據(jù)結(jié)構(gòu)
但消費(fèi)端有時(shí)效性要求,改造難度大,生產(chǎn)端涉及范圍大阻力也不小。經(jīng)過綜合考量,最后我們決定采用類似MySQL數(shù)據(jù)存儲的表結(jié)構(gòu)來設(shè)計(jì)超級表,這樣的改造對原來系統(tǒng)入侵最少,改造難度系數(shù)最低,改造大致過程如下:
·TDengine,每種數(shù)據(jù)存儲的監(jiān)控?cái)?shù)據(jù)單獨(dú)建庫存放
1.taos>create database redis;
2.taos>create database es;
3..........
·TDengine,建超級表,以Redis為例
1.taos>useredis;
2.taos>create table redis_node_meters(created_at TIMESTAMP,qps INT,...)TAGS(region NCHAR(10),cluster_name NCHAR(50),ip NCHAR(20),port INT,role NCHAR(15));
·監(jiān)控?cái)?shù)據(jù)消費(fèi),由于新增的實(shí)例節(jié)點(diǎn)是不確定的,比如Redis的節(jié)點(diǎn)資源是由Agent自動(dòng)發(fā)現(xiàn)注冊后自動(dòng)進(jìn)行監(jiān)控指標(biāo)采集,這時(shí)寫入數(shù)據(jù)并不確定某個(gè)子表是否存在,就需要TDengine的自動(dòng)建表語法來創(chuàng)建不存在的子表,若該子表已存在則不會(huì)建立新表只會(huì)寫入數(shù)據(jù)。
1.taos>INTO tablename USING redis_node_meters TAGS('China','t est','127.0.0.3',9200,'master')VALUES('2021-12-02 14:21:14',6490,...)
·繪圖展示,繪圖程序沒有安裝客戶端驅(qū)動(dòng),直接使用了TDengine提供的RESTful API,采用HTTP的方式進(jìn)行數(shù)據(jù)查詢。在SQL查詢上大量使用了TDengine提供的時(shí)間維度聚合函數(shù)INTERVAL,長時(shí)間跨度的數(shù)據(jù)查詢,只需要合理選擇聚合間隔,基本都是毫秒級響應(yīng),保障了前端繪圖的流暢穩(wěn)定。
四、改造后的落地效果
將監(jiān)控的數(shù)據(jù)存儲由MySQL改造為TDengine后,不僅頂住了監(jiān)控?cái)?shù)據(jù)增長所帶來的壓力,還節(jié)約了存儲空間,成本壓縮到了原來的十分之?甚至更低。歷史原生監(jiān)控?cái)?shù)據(jù)可回溯時(shí)間也變得更長,之前存儲3天原生數(shù)據(jù)及聚合數(shù)據(jù)的空間,現(xiàn)在可供原始數(shù)據(jù)存儲45天。
此外,改造之后不再需要維護(hù)復(fù)雜的數(shù)據(jù)聚合調(diào)度任務(wù),大幅降低了監(jiān)控系統(tǒng)、監(jiān)控?cái)?shù)據(jù)管理復(fù)雜度,同時(shí)前端繪圖數(shù)據(jù)查詢也變得更加簡潔高效。
五、寫在最后
隨著對TDengine越發(fā)深入的了解及經(jīng)驗(yàn)累積,后續(xù)我們也會(huì)逐步考慮將貨拉拉大監(jiān)控系統(tǒng)、業(yè)務(wù)數(shù)據(jù)(行車軌跡)等時(shí)序數(shù)據(jù)均遷移至TDengine。為了方便有需要的朋友更好地使用TDengine,在此也分享一下我們的一些使用經(jīng)驗(yàn):
·由于TDengine不支持太復(fù)雜的SQL查詢語法,在設(shè)計(jì)超級表tag的時(shí)候需要充分考慮清楚,目前只有tag的字段支持函數(shù)運(yùn)算結(jié)果的分組(GROUP BY)查詢,普通字段是不支持的。
·子表tag的值是可以改變的,但是同?個(gè)子表tag的值是唯?的,建議用子表tag的組合值來生成子表名。
在本次項(xiàng)目中,TDengine很好地幫助我們實(shí)現(xiàn)了降本增效,是一款值得嘗試的時(shí)序數(shù)據(jù)庫產(chǎn)品,未來也希望其能夠發(fā)揮出越來越豐富的功能和特性,也期待我們之后能有更緊密深入的合作。