趙運周 / 轉轉
在(zai)(zai)轉轉的(de)(de)業務中,我(wo)們使用了Nginx作為(wei)我(wo)們的(de)(de)反向代(dai)(dai)理(li),為(wei)保證(zheng)代(dai)(dai)理(li)層可用性,需要對(dui)Nginx進(jin)行實(shi)時(shi)(shi)狀態監控。在(zai)(zai)服(fu)務器的(de)(de)基礎監控的(de)(de)選擇上,我(wo)們將OpenFalcon逐步替換為(wei)夜(ye)鶯,對(dui)Nginx 的(de)(de)reqstat監控最初也使用了這兩(liang)種。但是這兩(liang)大監控都有一個(ge)共同(tong)缺點(dian),即在(zai)(zai)展示時(shi)(shi)有條(tiao)數(shu)限制,導致域名數(shu)量和機器數(shu)量相乘后數(shu)據(ju)量增多(duo)的(de)(de)情況下,無法滿足需求。
為了解決這個問題,我們考慮對現有監控模塊進行升級改造,重新進行數據庫選型,在預研和分析階段,根據當前的業務需求我們從開源的數據庫中選擇了兩款時序數據庫(Time-Series Database),分(fen)別是InfluxDB和TDengine,這兩款都可(ke)以實現(xian)高(gao)性(xing)能地查詢與(yu)存儲時(shi)序性(xing)數據(ju),但TDengine相(xiang)比于InfluxDB還(huan)存在三點優勢:
- 集群功能已經開源,支持橫向擴展以及高可用
- 性能和成本之間的平衡達到最優化,運維難度顯著降低
- 其超級表特別適合我們這個以域名為維度的監控方案
通(tong)過綜合(he)對比,我們初步選(xuan)定TDengine作為監控模塊的數據庫(ku)。此外,濤思(si)官方的測試(shi)結果顯示,TDengine的寫入(ru)速度高于InfluxDB,這一點也更加堅定了(le)我們選(xuan)擇TDengine的決定。
而且TDengine支持多種數據接(jie)口(kou),包(bao)含C/C++、Java、Python、Go和RESTful等(deng)。轉轉之(zhi)前(qian)的服務(wu)用的是Python,所以這也方便(bian)我們依舊延續(xu)使用Python connector。
使用TDengine進行數據庫建模
作為一款(kuan)結構化的(de)時序數據(ju)庫,為了(le)能夠達(da)到最(zui)優的(de)性能表現,TDengine在(zai)接入數據(ju)前需要根(gen)據(ju)數據(ju)的(de)特(te)性設計(ji)schema。 Nginx監控功能數據(ju)特(te)性如下:
- 數據格式固定:配置好req_status_zone之后,日志文件就固定住了,但總的字段數是有限的,樣例如下:
zone_name key max_active max_bw traffic requests active bandwidth
server_addr 192.168.187.164 2 432 17K 18 1 0
server_name 192.168.187.164 2 432 17K 18 1 0
server_url 192.168.187.164/ 1 0 0 8 0 0
server_url 192.168.187.164/index.html 1 0 11K 8 0 0
server_url 192.168.187.164/req-status 1 0 0 1 1 0
server_url 192.168.187.164/req_status 1 0 5680 1 0 0
- 數據極少需要更新或刪除
- 屬于服務訪問的事實數據,只要不是臟數據,就不會刪除
- 需要采集的數據標簽不多,而且固定
- 單條數據量約在1KB
- 保存6個月以上
此外(wai),TDengine的(de)文檔顯示:
TDengine 對每(mei)(mei)個數據采集(ji)點單獨建表(biao),但(dan)在實際應用中(zhong)經常需(xu)要對不同的(de)(de)(de)采集(ji)點數據進行聚合(he)(he)。為高效的(de)(de)(de)進行聚合(he)(he)操作,TDengine 引入超(chao)(chao)級(ji)表(biao)(STable)的(de)(de)(de)概念。超(chao)(chao)級(ji)表(biao)用來代表(biao)一(yi)(yi)特定類型的(de)(de)(de)數據采集(ji)點,它是包含多張表(biao)的(de)(de)(de)表(biao)集(ji)合(he)(he),集(ji)合(he)(he)里每(mei)(mei)張表(biao)的(de)(de)(de)模式(schema)完(wan)全一(yi)(yi)致(zhi),但(dan)每(mei)(mei)張表(biao)都帶有自(zi)己的(de)(de)(de)靜(jing)態標簽(qian),標簽(qian)可以有多個,可以隨時增加、刪除和修改。
按照其建(jian)議(yi)的數據模型(xing),我們需要建(jian)立一個超級表。結合我們的數據特點和使(shi)用場(chang)景,創建(jian)數據模型(xing)如下:
- 超級表:以指標作為超級表
- 子表:每個域名做一個子表
- 標簽tag:直接將標簽信息作為超級表的標簽列
- 列column:監控數據本身除去標簽部分
具體示例如下:

落地實施和最終效果展示
因為(wei)是融合一(yi)個(ge)全新的(de)(de)數(shu)據庫,在真正的(de)(de)落地實施時不可避(bi)免會遇(yu)到一(yi)些問(wen)題點(dian),以(yi)下三點(dian)是我(wo)們(men)匯總的(de)(de)實施經驗(yan),放在本篇(pian)文章中(zhong)給大家做參考(kao):
- 數據寫入
在數據(ju)寫入(ru)的(de)階段,我們開(kai)始設(she)計(ji)的(de)是一(yi)個域(yu)名一(yi)個子表,但是直接(jie)使用域(yu)名做表名不符(fu)(fu)合保留(liu)字符(fu)(fu)的(de)規范,所以需要將域(yu)名轉換一(yi)下。
- 查詢問題
由(you)于(yu)寫入的(de)數據是實時的(de)值(zhi)(zhi),而監控業務更(geng)多地是需(xu)要(yao)獲取(qu)前后差值(zhi)(zhi),因此需(xu)要(yao)用(yong)上(shang)TDengine自帶(dai)的(de)函數DIFF。官方從2.1.3.0 版(ban)本開始,DIFF 函數可(ke)以由(you)GROUP BY 劃分出單(dan)獨(du)時間線的(de)情況下用(yong)于(yu)超級表(也(ye)即 GROUP BY TBNAME)。而且TDengine的(de)超級表極大程度上(shang)簡化了查(cha)(cha)詢代碼,其分片特(te)性也(ye)保證了同時查(cha)(cha)詢多個域名(ming)能(neng)夠做到充分地多核并發(fa)。
- 容量規劃
在落地過程中,我們發現數據類型、數據規模對TDengine的性能影(ying)響(xiang)比較大,最好根據每個場景的特性進行容量規劃,影(ying)響(xiang)因素包括(kuo):
- 表數量
- 數據長度
- 副本數
- 表活躍度等
從(cong)這些(xie)因素出發調整配(pei)置參數能(neng)夠確保最佳性能(neng),在(zai)與濤(tao)思(si)數據工(gong)程師溝通后(hou),我們確定了(le)現在(zai)的容量規(gui)劃計算模型。值(zhi)得(de)注意(yi)的是,TDengine容量規(gui)劃的難點在(zai)于內存的規(gui)劃,需要在(zai)內存的使用和讀寫性能(neng)之間進行平衡(heng)。 連接(jie)TDengine后(hou),我們目(mu)前(qian)系統的拓撲結構如(ru)下:

使用TDengine完成(cheng)改造后,線上(shang)的監控狀態達(da)到(dao)預期(qi),滿足當前(qian)(qian)業務需求,目前(qian)(qian)運(yun)行非常穩(wen)定(ding)。且(qie)配合Grafana后,每個域名的流量、連(lian)接數(shu)、響(xiang)應時(shi)間等信息都能夠實(shi)時(shi)監控到(dao)。

寫在最后
總而言之,無論是在成(cheng)本和性能(neng)層(ceng)面,還是在使(shi)用的(de)(de)便(bian)利性方面,TDengine Database都(dou)具(ju)有非(fei)(fei)常(chang)大的(de)(de)優勢,在我們(men)的(de)(de)實踐中也(ye)(ye)(ye)得到了證明,尤其是成(cheng)本管控(kong)上效果非(fei)(fei)常(chang)顯著。同時,也(ye)(ye)(ye)非(fei)(fei)常(chang)感謝濤思數(shu)據(ju)的(de)(de)小(xiao)伙伴們(men)提(ti)供的(de)(de)專業(ye)、及時的(de)(de)幫助(zhu),我們(men)也(ye)(ye)(ye)希望未來(lai)TDengine Database能(neng)夠開(kai)拓出更多更加優秀的(de)(de)新(xin)特性。當(dang)然(ran),作為TDengine的(de)(de)使(shi)用者,我們(men)也(ye)(ye)(ye)會(hui)在上為TDengine做代碼貢獻。
此(ci)外,從(cong)自身(shen)項(xiang)目和實踐(jian)出發,我們也有一些針(zhen)對于TDengine Database期(qi)盼(pan)改進(jin)的(de)功(gong)能點:
- 對表名支持更友好:能夠減少對特殊字符的屏蔽(據說在后續版本中會實現,這樣就更貼近場景,省去了應用端的特殊處理)
- 支持更加豐富的SQL語句:能夠針對少有的場景,提供更加靈活的SQL語句,便于做更加復雜的計算分析,這也是AIOps的進階部分
- 灰度平滑升級:目前TDengine保持著2周一次的發版節奏,還是期望能夠快速用上新的特性。但是每次停機升級又會是一個麻煩的事情,期待官方早日支持滾動升級
- 可實現自定義聚合方法:由于時間問題,沒趕上官方的UDF特性。期望官方的UDF能夠早日發布,好實現更加復雜的聚合計算
- 子表自動清理功能:由于域名會存在下線問題,目前的TTL策略只是針對數據而不是Table本身,淘汰子表還需要人工運維介入
盡管還存在不足,但作(zuo)為首次嘗試,TDengine的表(biao)現可以(yi)說是相當(dang)不錯了,我們也很期待未來(lai)能夠在更多場景中和TDengine展開(kai)合作(zuo),包括更多監控項以(yi)及業務時序數據庫需求的接入嘗試。
最后(hou),衷心祝愿TDengine越(yue)(yue)來越(yue)(yue)好(hao)!


























