現(xiàn)在系統(tǒng)中有一張表存了設備的各種運行狀態(tài),比如 CPU 溫度祥绞、使用率诀豁、負載等窄刘,以及一些埋點事件信息,這些其實歸納起來都可以作為 metric 來進行收集舷胜,業(yè)界現(xiàn)在的答案基本就是 Prometheus。而 Prometheus 底層的存儲就是一個時序數(shù)據(jù)庫,所以很自然的烹骨,我們也想將這些數(shù)據(jù)存儲到一個時序數(shù)據(jù)庫中翻伺。首先是想到了 TSDB,本來阿里云也有相關的產(chǎn)品沮焕,但后來停止維護了吨岭,提供了 Lindorm 的時序引擎實現(xiàn)。所以就了解了下 Lindorm 的時序引擎峦树,這個引擎實現(xiàn)了多值模型辣辫,看起來可以很好的替換 TSDB,但是后來折騰下來發(fā)現(xiàn)魁巩,并不適合我們的業(yè)務模型急灭。
數(shù)據(jù)模型
時序數(shù)據(jù)元素說明
Lindorm 時序引擎相比 OpenTSDB,在概念上還是有一些不同谷遂,比如在 OpenTSDB 中的 Metric 概念葬馋,在 Lindorm 時序引擎中就不存在了,咨詢了下同學肾扰,應該就是對應 Lindorm 中表的概念畴嘶,但是感覺與官網(wǎng)中的介紹又不大相同。其他的基本類似集晚。
元素 | 描述 |
---|---|
表名(Table) | 時序表代表一系列同類時序數(shù)據(jù)的集合窗悯,例如為空氣質(zhì)量傳感器建立一個Table,存儲所有傳感器的監(jiān)測數(shù)據(jù)偷拔。 |
標簽(Tag) | Tag描述數(shù)據(jù)源的特征蒋院,通常不隨時間變化,例如傳感器設備条摸,包含設備DeviceId悦污、設備所在的Region等Tag信息,數(shù)據(jù)庫內(nèi)部會自動為Tag建立索引钉蒲,支持根據(jù)Tag來進行多維檢索查詢切端。Tag由Tag Key、Tag Value組成顷啼,兩者均為String類型踏枣。 在定義時序數(shù)據(jù)表時,還可以指定特定標簽列作為Primary Key來顯式指定數(shù)據(jù)在多個節(jié)點上分片(Data Sharding)時的分片規(guī)則钙蒙,從而實現(xiàn)貼合業(yè)務場景的性能提升茵瀑。 |
時間戳(Timestamp) | Timestamp代表數(shù)據(jù)產(chǎn)生的時間點,可以寫入時指定躬厌,也可由系統(tǒng)自動生成马昨。 |
量測值(Field) | Field描述數(shù)據(jù)源的量測指標,通常隨著時間不斷變化,例如傳感器設備包含溫度鸿捧、濕度等Field屹篓,F(xiàn)ield列無需提前創(chuàng)建固定的Schema,可以在運行過程中動態(tài)增減匙奴;Field由Field名和Field值組成堆巧,F(xiàn)ield名為字符串類型,F(xiàn)ield值支持多種數(shù)據(jù)類型泼菌。 |
數(shù)據(jù)點(Data Point) | 數(shù)據(jù)源在某個時間產(chǎn)生的某個量測指標值(Field值)稱為一個數(shù)據(jù)點谍肤,數(shù)據(jù)庫查詢、寫入時按數(shù)據(jù)點數(shù)來作為統(tǒng)計指標哗伯。 |
時間線(Time Series) | 數(shù)據(jù)源的某一個指標隨時間變化荒揣,形成時間線,Tag的組合確定一條時間線笋颤。針對時序數(shù)據(jù)的計算包括降采樣乳附、聚合(sum、count伴澄、max赋除、min等)、插值等都基于時間線維度進行非凌; 數(shù)據(jù)庫在存儲數(shù)據(jù)時举农,會將同一條時間線的數(shù)據(jù)盡量聚類存儲,提升時間線數(shù)據(jù)訪問效率敞嗡,同時更好的支持時序數(shù)據(jù)壓縮颁糟。 在時序表中,Tag列的值都相同的一系列數(shù)據(jù)行構成了一條時間線喉悴。 |
時間線
例如:某風力電廠包含一系列的智能風力發(fā)電機設備棱貌,創(chuàng)建名為 Wind-generators 的 table 來存儲所有設備的信息,設備由 ID箕肃、型號婚脱、廠商等 Tag 信息描述,每個設備會持續(xù)上報功率勺像、風速等 Field 指標障贸,指標數(shù)據(jù)通過時序數(shù)據(jù)庫的 API 實時寫入到云端時序數(shù)據(jù)庫。
Schema 約束
與傳統(tǒng)關系型數(shù)據(jù)庫不一樣吟宦,Lindorm 時序引擎提供三種不同的 Schema 約束方式篮洁,以支持業(yè)務的快速變化。
- 強約束
與傳統(tǒng)關系型數(shù)據(jù)庫類似殃姓,時序引擎會嚴格依據(jù)預先定義的表結(jié)構對寫入數(shù)據(jù)的表名袁波、字段名瓦阐、類型進行校驗。不符合即出錯锋叨。 - 弱約束
寫入數(shù)據(jù)的所屬表不存在時引擎不會報錯垄分,而是會自動創(chuàng)建對應的表宛篇。
寫入數(shù)據(jù)的新增一個標簽或字段時娃磺,引擎不會校驗報錯,而是會在對應的時序數(shù)據(jù)表中自動添加一個TAG列或FIELD列叫倍。
寫入數(shù)據(jù)的相同字段的數(shù)據(jù)類型發(fā)生變化時時序引擎會檢測到字段的數(shù)據(jù)類型不匹配而寫入失敗偷卧,需要使用ALTER TABLE語句手動修改字段的數(shù)據(jù)類型。 - 無約束
不做任何約束吆倦。代價是無法直接通過SQL查詢寫入的數(shù)據(jù)听诸。
數(shù)據(jù)寫入方式與Schema約束的選擇
寫入方式 | Schema約束策略 | 備注 |
---|---|---|
通過JDBC API寫入數(shù)據(jù) | 強約束 | 不涉及。 |
通過教程:通過Java Native SDK連接并使用Lindorm時序引擎寫入數(shù)據(jù) | 可選項蚕泽。支持強約束和弱約束晌梨。 | 策略配置方法請參見Java Native SDK使用手冊。 不配置時的默認約束是弱約束须妻。 |
通過api/v2/sql使用INSERT寫入數(shù)據(jù) | 強約束 | 不涉及仔蝌。 |
通過行協(xié)議寫入數(shù)據(jù) | 可選項。支持強約束和弱約束荒吏。 | 策略配置方法請參見行協(xié)議寫入敛惊。 不配置時的默認約束是弱約束。 |
使用約束
數(shù)據(jù)庫對象 | 說明 |
---|---|
database名稱 | 由大寫字母绰更、小寫字母瞧挤、數(shù)字、下劃線其中的一種或多種組成儡湾,長度為2~64個字符特恬。 |
database數(shù)量 | 一個實例最多創(chuàng)建16個數(shù)據(jù)庫(包含default數(shù)據(jù)庫)。 |
table名稱 | 由大寫字母徐钠、小寫字母癌刽、數(shù)字、下劃線其中的一種或多種組成丹皱,最大長度為128個字符妒穴。 |
table數(shù)量 | 一個數(shù)據(jù)庫最多創(chuàng)建10000個數(shù)據(jù)表。 |
tag列名稱 | 可見字符摊崭,最大長度為200個字符讼油。 |
tag列值 | 可見字符,最大長度為20480個字符呢簸。 |
field列名稱 | 可見字符矮台,最大長度為200個字符乏屯。 |
field列值 | 可見字符,最大長度為20480個字符瘦赫。 |
timestamp列名稱 | 可見字符辰晕,最大長度為200個字符,一張表只能有一個timestamp列确虱,默認作為時間索引含友。 |
timestamp列值 | 單位為毫秒。 |
列數(shù)量 | 一張表最多可創(chuàng)建1024列校辩,其中包含tag列窘问、timestamp列、field列宜咒。 |
使用說明
由上面的介紹可以看出來 Lindorm 時序引擎更像是一張普通的 MySql 表惠赫,只是會自動在 Tag 列上加索引。我們現(xiàn)在系統(tǒng)中存儲的指標項已經(jīng)有 200+故黑,如果按照這種模型來建表儿咱,意味著需要建一個超過 200 列的表。雖然數(shù)據(jù)庫限制上是支持的(最大 1024 列)场晶,并且 Native SDK 還支持動態(tài)列混埠,也不需要預先 DDL。但是在使用上實在是個難題峰搪,難道也建一個 200+ 字段的對象進行映射嗎岔冀?
最初想到的解決方案是在 Tag 列中加一個 metric 字段,用來存儲各種指標的名稱概耻,這樣跟現(xiàn)在的數(shù)據(jù)庫存儲模型基本一致使套。但咨詢過 Lindorm 的同學,告知每單位 CPU 最大支撐同時 10w 時間線 (推薦 4w 時間線)鞠柄。而我們現(xiàn)在有 2W 設備侦高,如果將 metirc 作為 Tag,意味著將有超過 400W 時間線厌杜,這個成本有點高奉呛。由于絕大多數(shù)查詢是通過設備 ID + metric + ts,所以 metric 也無法作為普通的 Field 列做存儲夯尽,而且同一時間可能有多個 metric瞧壮。
看官網(wǎng)上的介紹,對 TSDB 的兼容匙握,是通過 table 與 metric 做對應的咆槽。這個實際操作起來太麻煩,首先表的數(shù)量太多圈纺,其次就是后續(xù)表數(shù)據(jù)同步都是問題秦忿。
其實對監(jiān)控麦射、指標收集類型的業(yè)務來說,還是 TSDB 這樣的模型比較適合灯谣。因為指標項有可能很多潜秋,而且隨著業(yè)務的擴展也會不斷增加。Lindorm 的時序引擎胎许,也支持單值模型峻呛,但是看官網(wǎng)上的介紹,應該是支持有限也不推薦使用呐萨,所以也就沒有再去嘗試使用杀饵。
Lindorm 的時序引擎選擇的這個多值模型,我猜想可能是跟底層使用列式存儲有關系谬擦。這個多值模型適合于有少量固定列的情況,相比較 MySql 數(shù)據(jù)庫提供更加高效的寫入能力朽缎,提供了降采樣惨远、插值等高級能力。其他基本與 MySql 模型沒有差別话肖。