小T導讀:作為(wei)一家(jia)業(ye)務(wu)遍(bian)及(ji)多個(ge)國家(jia)及(ji)地區的物流(liu)公司,貨(huo)拉拉面臨(lin)的技術環境是非常復雜的,在云(yun)時代浪潮下(xia)(xia)基于(yu)(yu)混合云(yun)快速構建環境搭建系統成為(wei)其必然的選(xuan)擇(ze)。但是在混合云(yun)上如何(he)對基于(yu)(yu)各家(jia)云(yun)構建的系統進行有(you)效的管(guan)理是個(ge)挑戰,尤其對處于(yu)(yu)系統最底層的數據庫層面臨(lin)的問題、業(ye)務(wu)訴(su)求、各方痛點,是貨(huo)拉拉DBA團(tuan)隊(dui)現(xian)下(xia)(xia)所需要(yao)重(zhong)點解決的。
目前DBA團隊管(guan)(guan)理的(de)(de)數(shu)據(ju)(ju)存儲包括MySQL、Redis、Elasticsearch、Kafka、MQ、Canal等,為了保(bao)證監(jian)控(kong)(kong)(kong)采樣的(de)(de)實時(shi)性(xing),我們自研的(de)(de)監(jian)控(kong)(kong)(kong)系統設(she)置的(de)(de)采樣間(jian)隔為10秒,這樣每天都會產生龐大(da)的(de)(de)監(jian)控(kong)(kong)(kong)數(shu)據(ju)(ju),監(jian)控(kong)(kong)(kong)指標的(de)(de)數(shu)據(ju)(ju)量達到(dao)20億(yi)+。前期由(you)于管(guan)(guan)理實例少(shao)(shao),監(jian)控(kong)(kong)(kong)數(shu)據(ju)(ju)量也少(shao)(shao),所有(you)數(shu)據(ju)(ju)都被存放到(dao)了MySQL中(zhong);之后(hou)隨著管(guan)(guan)理實例越來越多(duo),使用MySQL來存儲規(gui)模日(ri)益龐大(da)的(de)(de)監(jian)控(kong)(kong)(kong)數(shu)據(ju)(ju)越發(fa)力(li)不(bu)從(cong)心,急(ji)需進行升級改造(zao)。結合實際(ji)具(ju)體需求,通(tong)過對不(bu)同時(shi)序數(shu)據(ju)(ju)庫進行調研,最終我們選擇了TDengine,順利完成了數(shu)據(ju)(ju)存儲監(jian)控(kong)(kong)(kong)的(de)(de)升級改造(zao)。
一、監控系統開發中遇到的問題
從(cong)存儲(chu)(chu)路徑來看,每(mei)(mei)種數(shu)(shu)據(ju)(ju)存儲(chu)(chu)都(dou)分布在(zai)多個(ge)(ge)區(qu)域,每(mei)(mei)個(ge)(ge)區(qu)域將(jiang)監(jian)控(kong)采(cai)樣(yang)數(shu)(shu)據(ju)(ju)投遞(di)上報到(dao)消息(xi)總線,然后由消費(fei)程序統?消費(fei),消費(fei)程序會將(jiang)必要(yao)的告警(jing)數(shu)(shu)據(ju)(ju)更新到(dao)告警(jing)表,同(tong)時將(jiang)監(jian)控(kong)原始(shi)數(shu)(shu)據(ju)(ju)存儲(chu)(chu)到(dao)MySQL。比如,針對Redis這款數(shu)(shu)據(ju)(ju)存儲(chu)(chu),監(jian)控(kong)采(cai)樣(yang)間(jian)隔設(she)置10秒,那么每(mei)(mei)天實(shi)例采(cai)樣(yang)次數(shu)(shu)就(jiu)會達到(dao)3000萬+,監(jian)控(kong)指標累計6億+,數(shu)(shu)據(ju)(ju)量之龐大可見一斑。早(zao)期為(wei)了將(jiang)數(shu)(shu)據(ju)(ju)存儲(chu)(chu)到(dao)MySQL中,同(tong)時也能很好地(di)支持監(jian)控(kong)繪圖(tu)的使用(yong),每(mei)(mei)?次實(shi)例監(jian)控(kong)采(cai)樣(yang)時都(dou)會計算出該實(shi)例全量監(jian)控(kong)項采(cai)樣(yang)數(shu)(shu)據(ju)(ju),然后將(jiang)本(ben)次采(cai)樣(yang)的結果(guo)作為(wei)?條記(ji)錄存儲(chu)(chu)下(xia)來。

即使通過這(zhe)樣的(de)優化(hua)處理,在(zai)做(zuo)(zuo)時(shi)(shi)間跨度(du)大的(de)監(jian)(jian)控(kong)(kong)繪(hui)圖時(shi)(shi),前(qian)端依(yi)然(ran)會出現延遲卡(ka)頓的(de)問題,后端監(jian)(jian)控(kong)(kong)數(shu)據(ju)存儲的(de)MySQL也(ye)壓力山大,經常滿載,天天被吐槽。因此針(zhen)對這(zhe)種(zhong)時(shi)(shi)間跨度(du)大的(de)查詢,我們專門開(kai)發了?系列的(de)數(shu)據(ju)聚(ju)合(he)(he)調度(du)任務——按(an)照不同的(de)時(shi)(shi)間跨度(du),提前(qian)將10秒采(cai)集間隔的(de)監(jian)(jian)控(kong)(kong)數(shu)據(ju)做(zuo)(zuo)好(hao)聚(ju)合(he)(he),監(jian)(jian)控(kong)(kong)繪(hui)圖程序再根(gen)據(ju)不同的(de)時(shi)(shi)間跨度(du)選取(qu)不同的(de)聚(ju)合(he)(he)數(shu)據(ju)表(biao)繪(hui)圖,以此解決長時(shi)(shi)間跨度(du)監(jian)(jian)控(kong)(kong)繪(hui)圖展(zhan)示延遲卡(ka)頓的(de)問題。
但這仍(reng)然治標不治本。為了壓縮監(jian)控(kong)數據(ju)存(cun)(cun)儲(chu)(chu)空(kong)間(jian)(jian),原始(shi)10秒(miao)間(jian)(jian)隔的監(jian)控(kong)數據(ju)表只能歸檔保(bao)留3天時間(jian)(jian)的監(jian)控(kong)數據(ju),但存(cun)(cun)儲(chu)(chu)大小也將近有200GB, 加(jia)上(shang)與之相關的不同時間(jian)(jian)段的數據(ju)聚合(he)表,存(cun)(cun)儲(chu)(chu)一下(xia)子突破300GB。這還(huan)只是Redis監(jian)控(kong)數據(ju)的存(cun)(cun)儲(chu)(chu)大小,加(jia)上(shang)其(qi)它數據(ju)存(cun)(cun)儲(chu)(chu)的監(jian)控(kong)數據(ju),至(zhi)少需要1TB+空(kong)間(jian)(jian)的MySQL存(cun)(cun)儲(chu)(chu)。
數據集合任務管理復雜(za)、后期(qi)監控原數據回溯缺失(shi)、MySQL存儲空間日益增長帶來的隱患,都是亟待解決的問題(ti)。
二、時序數據庫選型
為了解決MySQL監控數據存儲的問題,我們把注意力轉移到了適合存儲監控數據的時序數據庫上。市面上各種時序數據庫產品琳瑯滿目,有老牌的,也有后起之秀,經過?系列調研選型,我們選擇了時序數據庫TDengine,主(zhu)要是(shi)因為其具備的(de)如(ru)下(xia)幾大優(you)點(dian):
- 采用分布式架構,可支持線性擴展
- 數據存儲壓縮率超高
- 集群模式支持多副本,無單點故障
- 單機模式性能強悍
- 安裝部署維護簡單
- SQL?持
- 時間維度聚合查詢
- 客戶端支持RESTful API
值得一提的是,TDengine的SQL原生語法支持時間維度聚合查詢,同時數據存儲壓縮率?存儲空間小, 這兩點直接切中了我們的痛點。落地后實測相同數據的存儲空間只有MySQL存儲空間的十分之?甚至更少。還有?個驚喜是,在現有監控數據存儲(MySQL)頂不住的情況下,?臺8C16GB的單機版TDengine輕松就抗下目前所有監控流量和存儲壓力,且(qie)運行穩定,基本沒有故障。
三、改造過程
TDengine用于存儲監控數據的超級表設計原則就是簡單高效,字段?般都比較少,每?種監控項類型(INT、FLOAT、NCHAR等)的數據存儲都需要單獨建立?個超級表,超級表(biao)?般都有關鍵(jian)的ts、type、value字段(duan),具體(ti)監控項由type字段(duan)標識,加上必要的tag及(ji)少量其它(ta)字段(duan)構成。
之(zhi)前(qian)監控(kong)數據存儲在(zai)MySQL的(de)(de)時(shi)候(hou),每條(tiao)數據記錄(lu)包含了該實例?次(ci)監控(kong)采樣的(de)(de)所有(you)監控(kong)項(25+)數據。如果采用通用的(de)(de)監控(kong)超級表設(she)計原則,就需(xu)要改造采樣的(de)(de)數據結(jie)構,改造方式有(you)兩(liang)種:
- 改造監控數據投遞的數據結構
- 改造消費程序消費邏輯重組數據結構
但消費端有時效性要求,改造難度大,生產端涉及范圍大阻力也不小。經過綜合考量,最后我們決定采用類似MySQL數據存儲的表結構來設計超級表,這樣的改造對原來系統入侵最少,改造難度系數最低,改(gai)造大致過程(cheng)如下:
- TDengine,每種數據存儲的監控數據單獨建庫存放
taos> create database redis;
taos> create database es;
... ... ...
- TDengine,建超級表,以Redis為例
taos> use redis;
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));
- 監控數據消費,由于新增的實例節點是不確定的,比如Redis的節點資源是由Agent自動發現注冊后自動進行監控指標采集,這時寫入數據并不確定某個子表是否存在,就需要TDengine的自動建表語法來創建不存在的子表,若該子表已存在則不會建立新表只會寫入數據。
taos > INSERT INTO tablename USING redis_node_meters TAGS ('China', 't est', '127.0.0.3', 9200, 'master') VALUES ('2021-12-02 14:21:14', 6490 , ...)
- 繪圖展示,繪圖程序沒有安裝客戶端驅動,直接使用了TDengine提供的RESTful API,采用HTTP的方式進行數據查詢。在SQL查詢上大量使用了TDengine提供的時間維度聚合函數INTERVAL,長時間跨度的數據查詢,只需要合理選擇聚合間隔,基本都是毫秒級響應,保障了前端繪圖的流暢穩定。
四、改造后的落地效果
將監控的數據存儲由MySQL改造為TDengine后,不僅頂住了監控數據增長所帶來的壓力,還節約了存儲空間,成本壓縮到了原來的十分之?甚至更低。歷史原生監控數據可回溯時間也變得更長,之前存儲3天原生數據及聚合數據的空間,現在可供原始數據存儲45天。
此外,改造(zao)之后不再需要維(wei)護復雜(za)的數(shu)據(ju)(ju)聚合調度任務,大(da)幅降低了(le)監控系統、監控數(shu)據(ju)(ju)管理復雜(za)度,同時前(qian)端繪圖數(shu)據(ju)(ju)查詢(xun)也變得更加簡潔高(gao)效。

五、寫在最后
隨著對TDengine越(yue)發(fa)深入的(de)(de)了解及經(jing)驗(yan)累積,后續我(wo)們也會(hui)逐步考慮將(jiang)貨拉拉大監控系統、業務(wu)數據(行(xing)車(che)軌(gui)跡(ji))等時序(xu)數據均遷移至TDengine。為了方便有需要的(de)(de)朋友更(geng)好地(di)使用(yong)TDengine,在此也分(fen)享(xiang)一下我(wo)們的(de)(de)一些使用(yong)經(jing)驗(yan):
- 由于TDengine不支持太復雜的SQL查詢語法,在設計超級表tag的時候需要充分考慮清楚,目前只有tag的字段支持函數運算結果的分組(GROUP BY)查詢,普通字段是不支持的。
- 子表tag的值是可以改變的,但是同?個子表tag的值是唯?的,建議用子表tag的組合值來生成子表名。
在本(ben)次項(xiang)目中(zhong),TDengine很好地幫助我們實現(xian)了降本(ben)增效,是(shi)一款(kuan)值(zhi)得嘗(chang)試(shi)的時序(xu)數據(ju)庫產品(pin),未來(lai)也希望(wang)其能夠發(fa)揮出越來(lai)越豐富的功能和(he)特性,也期待我們之后(hou)能有更(geng)緊密深入的合作(zuo)。


























