微服務下的數據架構

【編者的話】微服務是一個軟件架構模式,對微服務的討論大多集中在容器或其餘技術是否能很好的實施微服務,而本文將從如下幾個角度來和你們分享在微服務架構下進行數據設計須要關注的地方,旨在幫助你們在構建微服務架構時,提供一個從數據方面的視角:
  • 微服務定義
  • 微服務的優點及架構特色
  • 微服務架構下的數據設計
  • 選擇一個合適的數據庫

什麼是微服務?

按照 Martin Fowler 的定義,微服務是一個軟件架構模式,經過開發一系列的小型服務的方式來實現一個應用。每個這樣的小服務一般都是運行在本身的進程裏面,而且經過輕量級的 HTTP API 方式進行通信。這些服務一般會以業務模塊爲界限,可以被單獨開發部署,每每都會用自動化的部署工具來進行產品的發佈。經過使用微服務方法,大公司能夠更快推出新產品和服務,使得開發團隊與業務目標保持一致。

微服務的優點

微服務方法體現出許多優點,包括更快的上線時間、靈活性、彈性、一致性以及相對更低的成本。

更快的上線時間

實施微服務架構可使組織更快地將其應用程序推向市場。對總體應用程序的更改(即便很小)須要從新部署整個應用程序堆棧,從而引入風險和複雜性。相反,服務的更新能夠當即提交、測試和部署,對個別服務的更改不會影響系統的其餘部分。

更好的靈活性和可擴展性

微服務方法在擴展應用程序時也提供了靈活性。單片應用程序要求整個系統(及其全部功能)同時擴展。使用微服務,只須要縮放須要額外性能的組件或功能。能夠經過部署更多微服務實例來擴展服務範圍,從而實現更有效的容量規劃並下降軟件許可成本,從而下降整體擁有成本。

彈性

使用單體應用程序時,組件的故障可能會危及整個應用程序。在微服務中,每項服務都是隔離的,以防止級聯失敗致使整個系統崩潰。若是單個微服務的全部實例均失敗,則總體服務可能會降級,但其餘組件仍可提供有價值的服務。

更容易的規模化

微服務使技術團隊可以與組織需求保持一致,而且能夠調整團隊的大小以匹配所需的任務。一般,微服務團隊規模較小可是跨部門(如通常涵蓋 Ops、Dev、QA),並專一於整個應用程序的單個組件。經過提供對我的服務的全部權,而不是功能區域,微服務還能夠打破團隊之間的孤島,並改善協做。這種方法對於分佈式和遠程團隊尤爲強大。 (例如,不一樣地點的團隊能夠獨立發佈和部署功能。)

微服務的技術特色

讓咱們來經過一個例子來了解微服務架構的技術特色。

聯邦銀行的架構師 Jonnathan 很是不喜歡他的產品經理 Mandy,由於他以爲 Mandy 永遠有無窮無盡的想法要實現,搞得他整天就在不斷地修改代碼。可是 Mandy 是老闆的紅人,並且用戶對產品的反響也不錯,因此不少時候他只能默默的服從。

這一天 Mandy 又成功的說服了老闆要在他們的客戶體驗提高項目中增長輿情分析和 AI 客戶服務模塊,但願經過對社交媒體上有關聯邦銀行的全部評論進行實時的監控和分析來及時發現聯邦銀行的產品反饋或者用戶體驗問題。Jonnathan 已經預感到了這樣史無前例的應用場景,會有太多的未知和太多的改變,因而此次決定嘗試使用 Microservices 來構建這個應用。

這個是 Jonnathan 設計的架構,系統要求對客戶的社交帳號如 Facebook、Twitter、Google+ 及 Snapchat 公開的信息及評論進行收集,並在某些合適的時候使用 AI 技術直接和用戶在經過社交工具進行互動。
1.jpg

在上圖這個架構裏面,Jonnathan 把 4 個不一樣社交媒體的數據採集和交互用 4 個獨立的模塊進行實現,並用一個 Feed Merge 服務,一個 Aggregate Service 把 4 個相似功能的微服務模塊的數據和功能進行整合,提供給分析平臺使用。這裏面每個服務按照微服務的架構,每個都是單獨部署,在一個獨立的容器內執行,並使用本身的一個數據庫。

果不其然,系統上線一段時間,Mandy 說 Google+ 上面幾乎沒有什麼活動,不值得繼續維護這樣的一套系統。Jonnathan 此次毫無抱怨,直接把負責 Google+ 的容器停了,沒有須要任何代碼改動,甚至徹底沒有須要對整個系統進行停機。
2.jpg

剛下線 Google+,Mandy 又來提需求說最近合併了另外一家銀行,客戶不少使用 Whatsapp。二話不說,Jonnathan 直接上了一個新的模塊來處理 Whatsapp:
3.jpg

又過了一段時間,這一次是 Jonnathan 本身要對系統作調整了,原來 Snapchat 最近大火,他部署的系統頻受壓力,性能降低。爲了解決這個問題,Jonnathan 果斷增長了額外 2 臺容器來同時支撐 Snapchat 信息的採集和處理。
4.jpg

感謝微服務架構,Jonnathan 在一系列的產品需求變化以及系統擴容需求下,能夠從容應付。要實現微服務架構,須要你銘記如下幾個微服務架構的應用設計原則:
5.jpg

文章中涉及到的技術點我都分享在羣 697579751 裏,錄製成視頻供你們免費下載,但願能夠幫助在這個行業發展的朋友和童鞋們,在論壇博客等地方少花些時間找資料,把有限的時間,真正花在學習上,因此我把這些資料,分享出來。相信對於已經工做和遇到技術瓶頸或者寫博客碼友,在這份資料中必定都有你須要的內容。數據庫


Decouple 解耦

在微服務架構中,應用程序被分解爲小型的獨立服務。服務一般專一於特定的離散目標或功能,並沿着業務邊界解耦。按業務界限分離服務可以讓團隊專一於正確的目標,並確保服務之間的自主性。每項服務都是獨立開發,測試和部署的,服務一般是做爲獨立的進程或軟件容器分開的,經過網絡和商定的 API 進行通訊,儘管在某些狀況下,網絡可能在本地。一般部署相同微服務的多個實例,從而提供冗餘和可擴展性。

Dump Pipes 輕量級 API

微服務之間的通訊要使用輕量級 API,如 HTTP RESTful API。這樣可使得服務對 API 通訊方案的依賴減到最小。複雜的通訊處理要在服務端進行,而不是像 ESB 或者 Data Pipeline 處理總線那樣在數據傳輸過程當中引入很是多的邏輯,致使微服務模塊牢牢的綁定在這個數據管道上。

DevOps 持續集成

微服務架構帶來的一個很是顯著的負面性就是衆多實例的測試發佈及管理。傳統應用雖然開發複雜,可是部署和運維相對比較集中,一臺數據庫,2-4 個應用服務器就差很少了。可是微服務架構下單獨服務的數量輕則 10-20,多則上百個,因此微服務架構通常須要配套的 CI/CD 方法來支撐。

Decentralized 去中心數據治理

數據的管理在微服務架構下也是和傳統單體有很大的不一樣考量。大部分時候咱們但願數據就和服務同樣,要有充分的獨立性,能夠和某個服務一塊兒部署,一塊兒擴展,或者一塊兒重構。這一般意味着咱們可能要在一個微服務架構應用內使用多個數據庫實例。可是一樣須要考慮到數據分佈在多實例之間之後,每每還須要一些冗餘,以及如何保持這些數據在這些系統中的一致性等問題。下面一章,咱們就着重來討論微服務架構下的數據設計的一些考量因素。

微服務的數據設計考量

歷來沒有一個 one-size-fits-all 的架構,因此在微服務架構下面,咱們須要瞭解的,同樣是幾個關鍵的架構考量點。而後針對本身的實際應用,選擇哪些考量點是更加劇要。這篇文章的目的,主要就是跟你們來討論從哪幾個角度着手來設計一個符合微服務架構原則的數據架構。好比說,咱們能夠從一系列的問題來開始這個討論:
  • 這麼多微服務之間,我是否能夠用一個數據庫,仍是多個數據庫來支持多個微服務?
  • 若是是多個數據庫,我是否爲每個微服務挑選一個最合適的數據庫,仍是選擇同一種類型的數據庫?
  • 我如何在微服務架構下擴展個人數據庫?
  • 當一個我依賴的服務須要修改數據庫 Schema 的時候,是否會影響到我?
  • 當微服務應用不斷衍變的時候,個人數據庫是否能夠快速的響應應用需求變化?

這些就是咱們在微服務數據架構時候要關注的地方。

一庫一服仍是一庫多服

不管是單體應用,仍是微服務應用,有一點是確定的:應用的各個模塊之間都須要進行較爲頻繁的通訊,經過一塊兒協同合做,來實現應用的總體價值。在單體應用中,這種通訊是經過方法調用來完成的。在微服務中,則經過 API 調用來完成。這些模塊或者服務間調用,大部分時候是爲了共享數據。 共享數據最賤的方式固然就是採用一種共享數據庫的模式,也就是單體應用經常使用的方式 - 應用能夠有多個系統模塊,但通常都是隻有一個數據庫。以下圖左邊,3 個微服務模塊,後面共享一個數據庫,簡稱一庫多服務:
6.jpg

這種架構模式一般會被認爲是微服務架構下的反範式,它的問題在於:
  • 單點故障:一個數據庫倒下,整批服務所有中止。何來的服務獨立性?
  • 數據在同一個地方,會給貪圖方便的開發或者 DBA 工程師編寫不少數據間高度依賴的程序或者工具;
  • 沒法針對某一個服務進行精準優化或擴展,如上文所講的 Snapchat 的例子。

因此通常推薦的作法,是爲每個微服務準備一個單獨的數據庫,也即一庫一服(database per service)模式。如上圖右側所示。這種模式更加適合微服務架構 - 它知足每個服務是獨立開發、獨立部署、獨立擴展的特性。當須要對一個服務進行升級或者數據架構改動的時候,無須影響到其餘的服務。須要對某個服務進行擴展的時候,也能夠手術式的對某一個服務進行局部擴容。另外,若是某些服務對數據庫有特殊的需求,這種模式也爲下文所講的混合持久化(Polyglot Persistence)提供了可能性。

混合持久化 vs. 多模數據庫

混合持久化在大型互聯網公司是一個比較風行的模式。它秉承的原則就是爲特別的任務提供最好的工具。好比說,若是我但願提供一個高併發低延遲的共享用戶會話方案(shared session storage), Redis 多是一個很是理想的選擇。若是我是在實現一個產品目錄,涉及到大量不定結構的商品數據及屬性的建模管理,我可能會採用模式靈活,動態 schema 的 MongoDB 來做爲個人數據庫解決方案。若是我但願支持很是強大的全文搜索,ElasticSearch 則是行業中的佼佼者。微服務的功能分塊獨立部署爲這種架構模式提供了很是好的基礎,以下圖左側所示就是個典型的混合持久化的案例:
  • 混合持久化 - Polyglot Persistence
  • 多模數據庫 - Multi-model Database

7.jpg

固然,有句話說的是架構師的工做就是天天作不斷的取捨 (trade off),由於選擇每每是讓人很糾結。混合持久化的優點很明顯,可讓每一個單獨的服務使用到最佳的工具和技術。可是它的弊端也是不容忽視。部署、監控、備份、升級等數據庫管理工做歷來都是一件困難可是重要的任務。引入多個不一樣的數據庫,也意味着對系統管理維護的複雜度和成本提升了不少。這種狀況下可能須要比較有資源的公司或者團隊纔可使用。這也解釋了這個模式在大型互聯網公司獲得較多的採用與推廣。針對於其餘小型規模的用戶,或者是缺少足夠掌握各類新型技術人才的公司來講,另外一種更爲可行的模式多是多模數據庫(Multi-model)。如上圖右側所示。

多模數據庫的特徵是:
  • 依然是一庫一服務(爲一個服務部署一個單獨的數據庫);
  • 可是使用的是同一種類型,支持多種場景的數據庫,如 NoSQL 中間爲功能最全面的 MongoDB;
  • 雖然是多實例,可是隻需維護一種類型的數據庫,管理上和人員配備上都較爲簡單。

若是你在開發的應用是一款企業級產品,會交付到客戶環境部署安裝,則運維管理的簡單性將在技術選型中佔據很是重要的一個比重,無疑這種狀況下多模數據庫更加適用。

微服務擴展你的數據

微服務架構的一大裨益是其靈活的擴展性。以上面的 Snapchat 爲例,若是須要採集或處理的數據量快速增加,在咱們增長應用服務實例的同時,支撐數據存儲的模塊也要相應擴充。AFK Partners 在他們的 Scale Cube 一文裏對性能擴展提出了這樣的觀點:要設計一個真正意義上的可擴展系統,咱們必須考慮 3 個維度,以下所示:
8.jpg

  • X-軸, 系統複製(橫向擴展)
  • Y-軸, 非重疊功能的拆分(微服務)
  • Z-軸, 數據的分區 (Sharding)

一個好的數據架構,在微服務體系內,應該具備一樣的可擴展、易擴展性質,從而不給微服務架構拖後腿。關於數據分區擴展有兩種作法:
  • 應用數據分區
  • 數據庫分區

應用數據分區,顧名思義,就是在應用端對數據的存儲進行分區管理。好比說,一個社交應用能夠按國家或地區爲界把用戶的數據分發到不一樣數據庫實例裏面。這樣的話每一個數據庫實例只須要存儲一部分數據,從而實現海量的數據管理能力。數據庫分區,就是由數據庫的路由節點來完成數據分區的任務。數據庫分區的優點是顯然的 - 對應用透明、擴展快速、無須下線等。 若是你的應用有潛在擴充的需求,選擇一個可以自動擴展的分佈式數據庫是一個比較明智的選擇。

動態模式支持及快速開發能力

這是一個不少架構師可能會忽略,可是很是重要的關注點。咱們在迭代式開發 DevOps 微服務上的不少努力,都是爲了快速開發,快速上線,以及快速響應變化的需求。從數據架構師的角度來看,如何不成爲在這個快速開發方法模式中的一個瓶頸,有一個很重要的環節就是是否有一個可以及時響應變化的數據模型。傳統的數據庫都是強模式,須要對 schema 進行清晰定義, 在需求修改致使模型修改的時候須要對數據庫進行模式升級,是一個須要下線、耗時而且是高成本的運維操做。
9.jpg

在新一代的 NoSQL 數據庫產生以前,咱們並不須要考慮這個問題,可是以 MongoDB、Cassandra 等爲表明的 NoSQL 表明的是靈活建模,動態支持模式變化的特徵使得它們成爲敏捷開發和微服務體系內一個有力的競爭者,在選型的時候也是一個重要的考量因素之一。咱們說一庫一服的架構使得對一個服務的數據庫模式修改不會影響到其餘服務。可是若是使用一個動態模式(有時候有人會說無模式)的數據庫,則在該服務自己模式修改時候也能夠最小化其最小化的維運成本。

一個適合微服務架構的數據庫

紅杉資本的合夥人 Matt Miller 是公認的微服務技術領域專家。他的廣被傳播的「微服務生態圖」詳盡的列出了微服務架構的相關技術棧。在這裏他推薦了 MongoDB 做爲主要的數據管理方案。
10.jpg

MongoDB 是一個分佈式文檔型數據庫,它有如下一些特性使它很是適合於微服務架構:
  • 多模數據庫(Multi-model)
  • 原生 JSON 數據結構 - API
  • 動態模式、無模式(Dynamic schema / Schemaless)
  • 數據變化流(Change Stream)
  • 橫向擴展能力(Sharding)

多模數據庫

MongoDB 從 3.4 版本起在多模數據庫場景上提供了很多功能模塊,好比說,使用聚合框架(Aggregation Framework)如今開發者可使用:
  • $graphLookup 來實現相似於圖數據庫的查詢
  • $facet 來實現分面搜索。
  • 內存引擎功能,用於支持相似於 Redis 的高速緩存
  • 全文檢索,用於實現搜索類型場景

JSON 數據結構

因爲 MongoDB 原生就是 JSON 數據模型,正好是微服務架構中用於模塊間通訊的 HTTP RESTful API 調用的主要數模型。事實上,你可使用一些開源中間件,快速的來構建起微服務之間的 API 服務。

動態模式

這一點一直是 MongoDB 得到開發者青睞的主要緣由之一。MongoDB 無須顯式的定義數據模式便可讓你開始往數據庫寫入。當數據模型有變化時候,好比說在迭代式開發中很是常見的就是增長一些字段,MongoDB 數據庫不須要對其進行修改 schema 操做,而是能夠直接在同一個集合(表)裏直接寫入新版本的文檔。這個對於須要實現快速迭代,快速交付的微服務應用開發是一個很是重要的特性。
11.jpg

數據更改流

微服務架構中因爲其分佈特性,傳統的強事務機制再也不適用。數據的一致性通常須要經過一些基於 Event Sourcing 或者事件驅動模型的解決方案。MongoDB 3.6 版本推出的數據更改流,能夠用來實現一個相似於 Kafak 同樣的 Message Queue,爲各個微服務間的數據協調提供一個簡單易用的線程方案。

橫向擴展能力

MongoDB 一貫以其強大的橫向擴展能力著稱。很多 MongoDB 用戶遷移的主要緣由就是使用 MongoDB 的 sharding 技術能夠突破關係型數據庫在數據量和性能上的瓶頸。MongoDB 的 sharding 有幾個特徵使得其很是適合微服務架構考慮使用:
  • 彈性擴展:能夠擴容也能夠縮容;
  • 無縫擴展:無須停機,就可在線擴容;
  • 自動均衡:無須應用參與便可實現數據的自動均衡,徹底透明。

12.jpg

一個基於 MongoDB 的微服務參考架構圖:
13.jpg

文章中涉及到的技術點我都分享在羣 697579751 裏,錄製成視頻供你們免費下載,但願能夠幫助在這個行業發展的朋友和童鞋們,在論壇博客等地方少花些時間找資料,把有限的時間,真正花在學習上,因此我把這些資料,分享出來。相信對於已經工做和遇到技術瓶頸或者寫博客碼友,在這份資料中必定都有你須要的內容。緩存

相關文章
相關標籤/搜索