Timestream开发最佳实践
背景
Timestream模型是針對時序場景設計的特有模型,可以讓用戶快速完成業務代碼的開發,實現相關業務需求。但是,如果業務系統不僅想實現基礎的相關業務功能,還要達到最佳的性能,并且兼顧到未來的擴展性的話,就不是一件特別容易的事情。
本文會以共享汽車管理平臺為例,介紹一系列的timestream最佳設計和使用,給業務設計和使用提供一些參考。
場景和模型簡介
在共享汽車管理平臺這個場景中,主要是對車輛的狀態軌跡監控、車倆元數據以及訂單元數據進行管理。另外,還會對相關的數據進行計算分析并存儲相關結果:
- 車輛狀態軌跡:記錄了車輛的狀態監控,比如車速、位置、續航等數據,另外還需要記錄車輛行駛過程中的違章記錄,比如:是否超速、是否闖紅燈等等;
- 車輛元數據:記錄車輛的基本屬性信息,便于用戶進行車輛檢索,比如:車型、車牌、顏色等;
- 訂單元數據:訂單相關信息記錄,包含行程的起止時間、車輛、用戶、費用等信息
業務主要是對上面三部分數據進行查詢和檢索,滿足業務場景的需求。其中車輛元數據以及狀態軌跡數據是典型的時序序列,可以很方便的映射到Timestream模型中。
下圖是數據模型的映射:
下面介紹一下模型設計的細節以及設計中需要注意的一些優化點,這些優化點對于業務功能以及性能上都有一定的提升。
業務模型設計
在Timestream模型中,主要包含了元數據和數據點兩部分數據,分別使用一個元數據表以及若干個數據表進行存儲。下面介紹這兩類數據在存儲設計的關鍵點。
元數據表設計
在共享汽車這個場景下,元數據表主要存儲兩類數據:車輛的基本信息、車輛的最近狀態數據(位置、續航、狀態、違章統計等),業務會根據各類信息進行多條件的組合查詢符合條件的車輛。
如上圖所示,Timestream的元數據表會通過多元索引來提供豐富的數據檢索能力。在Timestream模型的元數據中,包含了name、tags、attributes三類數據,其中name、tags默認會提供數據檢索能力,attributes則需要在創建Meta表的時候指定需要索引的attributes字段以及相關信息,默認attributes并不支持檢索。
需要注意的是,目前并不支持動態修改Meta表的索引字段,所以最好能在設計之初能夠考慮到當前以及未來的功能需求,下面介紹一下相關信息是如何映射到模型以及相關的設計。
name設計
name字段的選取是很關鍵的,是數據檢索性能的一個重要影響因素,不同的name字段設計可能會導致查詢延時相差一個數量級。name字段的選取建議滿足以下條件:
- 絕大多數查詢場景都會對該字段進行精確查詢
- 該字段單個取值下的最大記錄數不宜過多,比如說不超過一千萬條記錄
在共享汽車管理平臺這個場景下,管理的是各個平臺的車輛,而在車輛檢索的時候,一定會指定的條件是平臺的名字,并且某個平臺的車輛其實也不會太多,一般也就百萬量級,所以這里可以將平臺作為name。
tags設計
在Timestream模型中,Name和Tags可以唯一確定某個元數據,在這個場景中,唯一確定某輛車的信息是:平臺、車輛ID,其中平臺是name,所以,tags中只需要存儲ID即可。
tags設計需要注意:
- tags的總長度盡可能的短,只把唯一確定主體的信息放到tag中,其余信息均放到attributes中
- tag只支持string類型的數據,如果業務字段是數值類型,需要將其轉成string進行存儲
attributes設計
attributes是主體的可變屬性,也可以用來存儲主體的非唯一屬性。在這個場景中,車輛的基本信息以及當前狀態都是用attributes來進行存儲。attributes設計關鍵點:
- 創建meta表的時候需要指定有檢索需求的attributes以及相關屬性,默認attributes是不支持索引的
- 數值型數據盡可能使用int來存儲,attribute支持多類型的數據,但在數據檢索過程中,int類型的數據檢索效率比string類型高的多,建議使用int,索引類型為LONG
- 考慮未來系統的擴展性,可以預留一列作為擴展字段,索引類型為KEYWORD,并且是Array
索引創建示例代碼:
public void createMetaTable() {db.createMetaTable(Arrays.asList(new AttributeIndexSchema("地區", AttributeIndexSchema.Type.KEYWORD),...// 數值類型索引new AttributeIndexSchema("座位", AttributeIndexSchema.Type.LONG), ...// 擴展字段,數組類型索引new AttributeIndexSchema("配置1", AttributeIndexSchema.Type.KEYWORD).isArray() ));數據表設計
Timestream可以支持多個數據表的存儲,來滿足不同的業務場景需求。另外,為了能夠利用底層引擎所做的性能優化,我們推薦append的寫入方式,即不會對已有數據進行修改,所以在以下場景中,我們建議業務將數據分到不同數據表中進行存儲:
- 數據精度不同,特別是在監控場景下,這個需求更加突出。按數據精度分表便于后續數據的查詢,如果查詢長周期的數據可以去查詢低精度的表,減少查詢的數據量,提高查詢效率
- 需要對數據進行加工處理,也就是會對數據進行更新,建議將處理之后的數據寫到另外一張表中
在共享汽車這個場景中,需要對車輛的狀態軌跡數據進行流式處理,比如檢測是否超速等違章、車輛狀態軌跡是否異常等,然后將處理之后的數據寫到另外一張表中,提供給業務進行查詢。
sdk使用
前面介紹了業務模型設計需要注意的地方,對業務功能拓展能力以及性能都有一定的提升。下面介紹一下timestream sdk使用的一些性能優化點。
數據寫入
元數據
元數據寫入支持兩種方式:put和update。其中put會刪除老的記錄,并且插入一個全新行;update則是對原有記錄的部分attributes進行更新。建議盡量使用Put的方式進行寫入。
示例代碼:
數據點
數據點寫入也提供了兩種方式:同步和異步。其中異步接口底層是通過TableStoreWriter進行異步寫入,其寫入吞吐能力更高,對寫入延時不是特別敏感的業務建議使用異步方式。
示例代碼:
數據查詢
元數據查詢
元數據查詢的時候,建議指定需要返回的列名。如果沒有顯示指定列名的話,會去讀主表以獲取完整的信息,這樣每一行元數據都會反查一次主表,查詢性能會更差一些。
示例代碼:
總結
本文介紹了Tablestore Timestream在模型設計以及sdk使用中的一些優化點,對于業務現有功能實現、未來拓展以及性能提升都有很好的作用
原文鏈接
本文為云棲社區原創內容,未經允許不得轉載。
總結
以上是生活随笔為你收集整理的Timestream开发最佳实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 轻松构建基于 Serverless 架构
- 下一篇: 阿里技术专家详解 DDD 系列- Dom