微服務真的不挑數據庫嗎?如何選擇?
微服務架構的應用具有很好的擴展性,因此似乎微服務并不挑數據庫,在微服務中使用哪種數據庫問題都不是很大。事實真的如此嗎?也許對于一些研發能力很強的隊伍來說,為微服務選擇數據庫是很容易的事情,因為選擇的數據庫無論存在哪方面的缺陷,他們都有辦法通過應用方面的優化去解決它。而對于一些普通的研發隊伍來說,有時候還真的搞不定。
很多企業剛剛轉向微服務架構的時候也是交了大量的學費的,很多企業的微服務架構轉型是:“開發一時爽,運維兩眼淚”。實際上很多設計和開發的缺陷最后都是讓運維來想辦法填坑的。與傳統的集中架構不同,微服務的坑,運維填起來難度大多了。如果微服務應用將一個大數據庫拆分成多個小型的領域數據庫,那么一條重要的原則就是要永遠確保這些數據庫是小型數據庫,其數據量的增長是緩慢的,隨著每年業務的增長率稍微增長一點點的,歷史數據一定是能夠及時歸檔的。這樣的小型數據庫才會在長期運行的時間里保證較好的性能,不會給運維人員帶來太大的負擔。
從另外一個角度來講,微服務的數據應該存儲到適當的數據庫中,而不是在沒有掌握數據存取特點的情況下,隨意選擇一個數據庫。目前數據庫可選擇的種類太多了,以阿里云等云廠商為例,他們就已經為微服務開發者提供了眼花繚亂的選項。
不同的應用場景選擇不同的數據庫產品,才能讓項目今后的發展路徑更為順暢。這么多的數據庫產品,我們該如何來選擇呢?雖然微應用已經弱化了數據庫的很多特性,大大減少了跨服務的數據融合計算,不過針對不同類型的微服務,我們仍然需要十分謹慎的來選擇數據庫產品。
我們該如何為自己的微服務選擇適當的數據庫產品呢?這就需要從幾個方面去考慮了。
首先要考慮的是你的微服務中對數據的訪問方式。選擇數據庫的最重要的因素是你的查詢的模式是什么樣的。如果你只需要存儲某些鍵值,那么KV數據庫可能是比較好的選擇,比如你可以選擇Redis;如果你的應用基本上都是基于主鍵查詢,附加一些主鍵關聯的其他字段,那么一些寬列數據庫可能很適合你的微服務,比如Cassandra;如果你的應用主要是訪問一些單表中的數據,不過檢索條件可能會比較豐富,模式不是十分固定,那么使用文檔數據庫可能比較好,MongoDB、CouchDB等可能比較對你的胃口;如果你的應用經常有一些多表關聯的關系型訪問,那么關系型數據庫,比如PostgreSQL、MySQLl等可能更適合;如果你的應用主要是根據主鍵做模糊查詢,全文檢索,那么ES可能會優于其他數據庫。
如果有一個場景有多種數據庫適合,那么可以根據數據一致性等要求來做出進一步的篩選,比如你的場景中MySQL和MongoDB都比較適合,那么如果在要求強一致性的情況下,傾向于選擇MySQL,否則可以考慮MongoDB。
實際上,在你的應用系統中,不同的微服務可以選擇不同類型的數據庫,從而最大限度的優化數據訪問。比如你的有很多視頻要存儲,那么選擇S3對象存儲來存儲視頻肯定比把視頻存儲到關系型數據庫的LOB字段中要好得多,在關系型數據庫中只需要保存對象的ID就可以了。
在一個應用系統中使用多種數據庫也不是多多益善,數據庫種類太多會導致系統架構變得臃腫,運維的成本也會大大增加。因此適當的選擇幾種數據庫才是較好的設計方案。這種情況下,一些多模數據庫就比較具有優勢了。比如說在系統中以RDBMS為主,稍微有一些JSON數據存儲、還有少量應用會使用一些時序數據和一些GIS數據,那么選擇PostgreSQL就可以滿足這些綜合要求。
實際上為微服務選擇數據庫產品不僅僅要考慮這些因素,開發團隊的經驗、運維能力、成本等因素也是要考慮的。因為微服務架構的特點,我們通過領域建模會將一個大型系統的數據拆分為多個不同的子領域,因此高并發支持能力,性能,大數據量下的復雜SQL性能等方面需要考慮的因素相對少一些。不過對于一些稍微極端一些的應用場景,可能我們需要考慮的會更為復雜一些。
另外一點就是聚合計算的問題,任何應用都有聚合計算的問題,特別是一些實時聚合計算的需求,我們也必須滿足。因此在領域建模將數據拆分之后我們依然需要將這些數據匯聚起來進行計算。雖然我們也可以使用ShardingSphere這樣的數據庫網關來實現一定的聚合計算,不過大數據量的分布式環境的聚合計算在性能上往往會遇到一些問題。解決此類問題的方法不外乎兩個,一個是在微服務層面,對明細數據進行準實時匯總,這樣聚合計算不需要針對明細數據進行。另外一種方法就是使用ODS或者數據中臺作為聚合計算的平臺,從而減輕微服務數據層的負擔。
原本一個大型數據庫拆分為很多個小庫后會不會給運維帶來壓力呢?答案是肯定的,因此微服務的架構師應該對這些小型數據庫做一個很好的架構設計,包括高可用、災備,數據歸檔,數據自動清理,這些工作運維人員可以參與設計,但是必須在應用中實現自動化的管理,否則這一堆堆的小庫上來,運維人員平時要是去監控巡檢,平時也沒啥事,還浪費時間,一旦出了問題,還不太好處置。
如果你的應用是托管在公有云上的,并且你的每個庫的容量、負載都可以比較好的控制,那么采購公有云的RDS是比較省事的做法,不過公有云的特點是入門很便宜,一旦你的庫變大了,服務要升級了,那么價錢絕對不是簡單的乘以某個倍數的問題。公有云上,大的主機和數據庫服務價格會有一個跳躍式的提升,應用架構師要十分注意這一點。私有云對費用相對沒有那么敏感,使用私有云的RDS服務可以大大的降低運維的壓力。在這方面,微服務的架構師一定要先和云平臺部門做好溝通。
如果你不希望管理碎片化的小型數據庫(無論是RDS還是運行在容器中的數據庫),那么帶有多租戶、多模存儲能力的分布式數據庫也許是你喜歡的選擇。運維一個大型的云數據庫可能比運維幾十個小數據庫更合你的胃口。這種選擇也是合適的,只要和你的企業的整體IT政策與IT基礎架構相吻合,那也是不錯的選擇。