五分鐘技術(shù)趣談 | 時(shí)序數(shù)據(jù)庫(kù)TDengine在和家親上的應(yīng)用實(shí)踐
Part 01
業(yè)務(wù)背景
和家親APP作為中國(guó)移動(dòng)智慧家庭業(yè)務(wù)入口,承載了大量智能設(shè)備告警推送和家庭業(yè)務(wù)推送。到目前為止,平臺(tái)每天產(chǎn)生將近30億的推送量,如何將這些推送數(shù)據(jù)進(jìn)行存儲(chǔ)、查詢和分析是一個(gè)比較棘手的問題。最初我們使用的是mysql集群分庫(kù)分表方案,但隨著數(shù)據(jù)量的增加,遇到了數(shù)據(jù)寫入和查詢的瓶頸,而且運(yùn)維復(fù)雜且不便管理。結(jié)合業(yè)務(wù)特點(diǎn),同時(shí)也是響應(yīng)集團(tuán)去IOE的要求,我們開始調(diào)研新的存儲(chǔ)方案--國(guó)產(chǎn)開源時(shí)序數(shù)據(jù)庫(kù)(Time Series Database)。
圖1 和家親業(yè)務(wù)數(shù)據(jù)存儲(chǔ)方案演進(jìn)
目前國(guó)產(chǎn)時(shí)序數(shù)據(jù)庫(kù)中比較有影響力的就IoTDB和TDengine,經(jīng)過(guò)我們多維度的選型測(cè)試,最終確定選擇TDengine作為新的數(shù)據(jù)存儲(chǔ)引擎,我們發(fā)現(xiàn)業(yè)務(wù)數(shù)據(jù)某些特點(diǎn)非常契合TDengine:
- 高頻寫入,峰值寫入高達(dá)7W條/秒
- 數(shù)據(jù)很少更新且查詢簡(jiǎn)單低頻
- 數(shù)據(jù)存儲(chǔ)周期自動(dòng)調(diào)整
- 數(shù)據(jù)帶有時(shí)間戳
Part 02
數(shù)據(jù)建模
區(qū)別于傳統(tǒng)關(guān)系型數(shù)據(jù)庫(kù),數(shù)據(jù)寫入之前需要提前建表,TDengine有超級(jí)表的概念,具備自動(dòng)建表的功能。這樣業(yè)務(wù)數(shù)據(jù)入庫(kù)只需要建一個(gè)庫(kù)和一張與業(yè)務(wù)需求相關(guān)的超級(jí)表,就可以在數(shù)據(jù)第一次入庫(kù)的時(shí)候自動(dòng)創(chuàng)建子表。自動(dòng)創(chuàng)建子表在第一次入庫(kù)時(shí)會(huì)有性能折損,但是經(jīng)過(guò)測(cè)試TDengine的自動(dòng)建表效率非常高,幾乎可以忽略不計(jì)。在我們的業(yè)務(wù)場(chǎng)景中,我們把每個(gè)用戶對(duì)應(yīng)成一個(gè)設(shè)備一張表,用戶每天產(chǎn)生的告警寫入到自己的表中。
建庫(kù)語(yǔ)句如下:
CREATE DATABASE `hjq_push` BUFFER 900 CACHESIZE 1 CACHEMODEL 'none' COMP 2 DURATION 180m WAL_FSYNC_PERIOD 3000 MAXROWS 4096 MINROWS 10 STT_TRIGGER 16 KEEP 10080m,10080m,10080m PAGES 160 PAGESIZE 128 PRECISION 'ms' REPLICA 3 WAL_LEVEL 1 VGROUPS 200 SINGLE_STABLE 0;
超級(jí)表語(yǔ)句如下:
CREATE STABLE s_push (ts TIMESTAMP, guid BIGINT, source NCHAR(30),msgName NCHAR(64), msgContent NCHAR(1024), status SMALLINT, updateTime TIMESTAMP) TAGS(flag TINYINT);
利用超級(jí)表寫入語(yǔ)句:
INSERT INTO u_#{phone} USING s_push TAGS #{tag} (ts, guid, source, msgName, msgContent, status,updateTime) VALUES(#{ts},#{guid}, #{source}, #{msgName}, #{msgContent}, #{status},#{updateTime});
Part 03
性能表現(xiàn)
3.1 高效寫入
采用時(shí)序數(shù)據(jù)庫(kù)的一個(gè)重要原因就是支持高頻寫入。TDengine寫入速度極高,寫接近硬盤的連續(xù)寫入性能。經(jīng)過(guò)業(yè)務(wù)實(shí)際測(cè)試,峰值寫入7W/s完全沒有壓力。
圖2 業(yè)務(wù)實(shí)測(cè)寫入
當(dāng)然要達(dá)到高效的寫入性能,需要客戶端、數(shù)據(jù)源和服務(wù)端配合調(diào)試才能達(dá)到最優(yōu)狀態(tài)。
從客戶端角度:
- 盡量在一條寫入sql中拼接更多數(shù)據(jù)。
- 寫入方式:參數(shù)綁定>sql寫入(不自動(dòng)建表)>sql寫入(自動(dòng)建表)>無(wú)模式寫入。
從數(shù)據(jù)源角度:
- 通過(guò)隊(duì)列(kafka)方式來(lái)提升數(shù)據(jù)并發(fā)寫入。
- 盡量將同一張子表的數(shù)據(jù)提前匯聚到一起,提高寫入時(shí)數(shù)據(jù)的相鄰性。
從服務(wù)器配置角度:
需要根據(jù)系統(tǒng)磁盤的數(shù)量、I/O 能力及處理器性能在創(chuàng)建數(shù)據(jù)庫(kù)時(shí)設(shè)置適當(dāng)?shù)膙groups數(shù)量以充分發(fā)揮系統(tǒng)性能。如果vgroups過(guò)少,則系統(tǒng)性能無(wú)法發(fā)揮;如果vgroups過(guò)多,會(huì)造成無(wú)謂的資源競(jìng)爭(zhēng)。常規(guī)推薦vgroups數(shù)量為CPU核數(shù)的2倍,但仍然要結(jié)合具體的系統(tǒng)資源配置進(jìn)行調(diào)優(yōu)。
3.2 系統(tǒng)及存儲(chǔ)性能
TDengine已經(jīng)在我們線上業(yè)務(wù)平穩(wěn)運(yùn)行一段時(shí)間,通過(guò)系統(tǒng)監(jiān)控CPU使用率平常不到15%,內(nèi)存使用率穩(wěn)定在10%。另外由于其高效的壓縮算法,可以節(jié)省大量存儲(chǔ)空間,相比于之前MySQL集群存儲(chǔ)只有1/7。下圖為集群中一臺(tái)DNode機(jī)器的監(jiān)控?cái)?shù)據(jù):
圖片
3.3 查詢性能
TDengine對(duì)常見ORM框架和數(shù)據(jù)庫(kù)連接池的支持較好,采用SQL作為查詢語(yǔ)言,開發(fā)簡(jiǎn)單方便,對(duì)于之前使用關(guān)系型數(shù)據(jù)庫(kù)的開發(fā)者可以無(wú)縫切換。經(jīng)過(guò)業(yè)務(wù)測(cè)試,在單個(gè)子表查詢都能達(dá)到ms級(jí)別。
圖3 業(yè)務(wù)查詢測(cè)試
Part 04
遇到的一些問題
在使用TDengine的業(yè)務(wù)實(shí)踐中,也遇到一些問題(可能有些問題在最新的版本更新迭代):
- 空子表無(wú)法自動(dòng)清理,由于我們數(shù)據(jù)存儲(chǔ)有周期性,但目前的TTL策略只是針對(duì)數(shù)據(jù)而不是子表本身,針對(duì)空的子表淘汰還需要腳本介入。
- 缺少簡(jiǎn)潔易操作的可視化界面。
- 數(shù)據(jù)更新會(huì)影響count()函數(shù)性能(商業(yè)版有碎片整理功能,沒試過(guò))
- LAST_ROW函數(shù)返回的數(shù)據(jù)集字段帶有l(wèi)ast_row(row),需要單獨(dú)解析
Part 05
結(jié)語(yǔ)
和家親推送業(yè)務(wù)對(duì)時(shí)序數(shù)據(jù)庫(kù)的使用目前也只是小試牛刀,相信隨著業(yè)務(wù)的發(fā)展,會(huì)使用到更多時(shí)序數(shù)據(jù)庫(kù)的功能特點(diǎn)。當(dāng)然同樣的業(yè)務(wù)數(shù)據(jù)可能還存在更優(yōu)的存儲(chǔ)方案, 無(wú)論是MySQL還是TDengine,都是優(yōu)秀的數(shù)據(jù)庫(kù)產(chǎn)品,最終還是業(yè)務(wù)場(chǎng)景為王,只有適配業(yè)務(wù)數(shù)據(jù)才是好產(chǎn)品。