在分佈式系統中,每一臺服務器都須要訪問本地緩存、分佈式MC緩存、分佈式後臺數據庫,對於同一個業務模塊,隨着業務變複雜,須要定義愈來愈多的數據Model,按照必定的規則存儲在本地緩存、分佈式緩存以及後臺數據庫中。前端
目前,業界的數據訪問層定位於應用程序與持久化數據庫之間,好比淘寶的TDDL、IBatis Sharding等,主要完成數據的分庫分表、讀寫分離等,本文的數據存儲涵蓋緩存、數據庫、文件系統,現有的數據庫DAL中間件、Redis客戶端、MC客戶端將做爲本文的水平維度的Adaptor,主要解決的問題:數據庫
數據訪問在水平數據存儲維度的一致性問題。後端
快速增長數據Model的能力。緩存
優雅、清晰、模塊化的數據訪問層代碼。服務器
對於上節的問題,下面列舉了水平和垂直維度抽象思考的例子。微信
假設水平維度:架構
部分熱數據存儲在本地緩存,本文使用EhCache。框架
部分熱數據存儲在前端緩存,本文使用MC。異步
全量數據存儲在數據庫緩存,本文使用MySQL。分佈式
假設垂直維度:
數據模型FileMeta,須要同時存儲在LocalCache、Redis和MySQL中。
數據模型BlockMeta,須要存儲在LocalCache、MC中。
數據模型Context,須要存儲在MC、MySQL中。
按照上面的分析,咱們畫出系統兩個維度正交設計圖,以下:
咱們能夠想到垂直維度定義N = 3個數據模型接口,水平維度定義N = 3個分層接口,可是水平維度和垂直維度是什麼關係呢?
在本文的設計中,對問題作了進一步思考,水平維度的接口所有由垂直維度的數據模型接口組合(Composition)而成,完成全部業務只須要定義N + M + 1個接口,而不是N * M + 1個接口,多餘的那個是DAL接口,完成數據訪問層封裝工做,第一節例子中的接口定義見下圖:
上節主要介紹了接口設計,這裏說一下實現,數據模型類很是簡單,只要MC Client、TDDL、EhCache在不一樣層完成相應接口實現,最重要的是DAL實現類,須要完成水平各個維度的策略存儲,好比對一個Model,順序寫入MC和MySQL,根據業務實踐經驗,總結出3條設計原則:
每個數據模型都有CRUD方法,即數據操做的增刪改查,對於MC或者LocalCache來講,增長操做和修改操做多是一致的,這種狀況也必須嚴格定義CRUD方法。
DAL層封裝全部的數據訪問,保證數據的一致性存儲和可靠性,DAL層的實現調用ILocalCacheService、IMCService、IDAOService,根據不一樣數據模型的存儲策略,分別去調用緩存和數據庫服務,數據模型若是僅存在MySQL或者MC,也須要在DAL層作封裝,這樣雖然對開發效率有必定影響,可是總體開發和維護成本下降不少。
DAL實現抽象出一個DALContext和一個Executor,對於不一樣的數據模型,配置出不一樣的DALContext,好比順序存儲在MC和MySQL或者同步寫入MC異步寫入MySQL,DAL也須要負責出錯處理、水平維度的容災切換等。
對於互聯網後端應用來講,最主要的功能就是處理數據,對DAL層的探索與優化是很是有價值的,基於本文提出的2-3法則,感興趣的讀者能夠構建一個DAL開源項目,有兩種思路。
第一種思路是:
定義數據模型以及存儲配置策略規範,可使用相似protobuf的規範。
根據業務定義的數據模型和存儲配置策略,生成業務代碼。
開發者在此基礎上擴充完善業務代碼。
第二種思路是:
定義數據模型以及存儲配置策略規範,可使用相似protobuf的規範。
開發DAL中間件(容器),根據業務定義的數據模型和存儲配置策略,運行時完成全部的數據訪問操做代理。
第一種相對容易,第二種比較複雜,讀者能夠本身選擇其中一種。
本文首發於「微博平臺架構」微信公衆號,發佈時有少許的文字潤色和調整。
衛向軍(@衛向軍_微博),畢業於北京郵電大學,現任微博平臺架構師,前後在微軟、金山雲、新浪微博從事技術研發工做,專一於系統架構設計、音視頻通信系統、分佈式文件系統和數據挖掘等領域。