微服務下的數據架構

2021-12-31 架構師



前言

微服務是一個軟體架構模式,對微服務的討論大多集中在容器或其他技術是否能很好的實施微服務,而本文將從以下幾個角度來和大家分享在微服務架構下進行數據設計需要關注的地方,旨在幫助大家在構建微服務架構時,提供一個從數據方面的視角:

微服務定義

微服務的優勢及架構特點

微服務架構下的數據設計

選擇一個合適的資料庫

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

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

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

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

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

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

讓我們來通過一個例子來了解微服務架構的技術特點。

聯邦銀行的架構師 Jonnathan 非常不喜歡他的產品經理 Mandy,因為他覺得 Mandy 永遠有無窮無盡的想法要實現,搞得他成天就在不斷地修改代碼。但是 Mandy 是老闆的紅人,而且用戶對產品的反響也不錯,所以很多時候他只能默默的服從。

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

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

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

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

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

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

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

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

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

微服務架構帶來的一個非常顯著的負面性就是眾多實例的測試發布及管理。傳統應用雖然開發複雜,但是部署和運維相對比較集中,一臺資料庫,2-4 個應用伺服器就差不多了。但是微服務架構下單獨服務的數量輕則 10-20,多則上百個,所以微服務架構一般需要配套的 CI/CD 方法來支撐。

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

從來沒有一個 one-size-fits-all 的架構,所以在微服務架構下面,我們需要了解的,一樣是幾個關鍵的架構考量點。然後針對自己的實際應用,選擇哪些考量點是更加重要。這篇文章的目的,主要就是跟大家來討論從哪幾個角度著手來設計一個符合微服務架構原則的數據架構。比如說,我們可以從一系列的問題來開始這個討論:

這麼多微服務之間,我是否可以用一個資料庫,還是多個資料庫來支持多個微服務?

如果是多個資料庫,我是否為每一個微服務挑選一個最合適的資料庫,還是選擇同一種類型的資料庫?

我如何在微服務架構下擴展我的資料庫?

當一個我依賴的服務需要修改資料庫 Schema 的時候,是否會影響到我?

當微服務應用不斷衍變的時候,我的資料庫是否可以快速的響應應用需求變化?

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

無論是單體應用,還是微服務應用,有一點是肯定的:應用的各個模塊之間都需要進行較為頻繁的通信,通過一起協同合作,來實現應用的整體價值。在單體應用中,這種通信是通過方法調用來完成的。在微服務中,則通過 API 調用來完成。這些模塊或者服務間調用,大部分時候是為了共享數據。共享數據最賤的方式當然就是採用一種共享資料庫的模式,也就是單體應用常用的方式 - 應用可以有多個系統模塊,但一般都是只有一個資料庫。如下圖左邊,3 個微服務模塊,後面共享一個資料庫,簡稱一庫多服務:

這種架構模式通常會被認為是微服務架構下的反範式,它的問題在於:

單點故障:一個資料庫倒下,整批服務全部停止。何來的服務獨立性?

數據在同一個地方,會給貪圖方便的開發或者 DBA 工程師編寫很多數據間高度依賴的程序或者工具;

無法針對某一個服務進行精準優化或擴展,如上文所講的 Snapchat 的例子。

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

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

混合持久化 - Polyglot Persistence

多模資料庫 - Multi-model Database

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

多模資料庫的特徵是:

依然是一庫一服務(為一個服務部署一個單獨的資料庫);

但是使用的是同一種類型,支持多種場景的資料庫,如 NoSQL 中間為功能最全面的 MongoDB;

雖然是多實例,但是只需維護一種類型的資料庫,管理上和人員配備上都較為簡單。

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

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

· X-軸, 系統複製(橫向擴展)

· Y-軸, 非重疊功能的拆分(微服務)

· Z-軸, 數據的分區 (Sharding)

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

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

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

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

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

MongoDB 是一個分布式文檔型資料庫,它有以下一些特性使它非常適合於微服務架構:

MongoDB 從 3.4 版本起在多模資料庫場景上提供了不少功能模塊,比如說,使用聚合框架 (Aggregation Framework) 現在開發者可以使用

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

這一點一直是 MongoDB 獲得開發者青睞的主要原因之一。MongoDB 無須顯式的定義數據模式即可讓你開始往資料庫寫入。當數據模型有變化時候,比如說在迭代式開發中非常常見的就是增加一些欄位,MongoDB 資料庫不需要對其進行修改 schema 操作,而是可以直接在同一個集合(表)裡直接寫入新版本的文檔。這個對於需要實現快速迭代,快速交付的微服務應用開發是一個非常重要的特性。

微服務架構中由於其分布特性,傳統的強事務機制不再適用。數據的一致性一般需要通過一些基於 Event Sourcing 或者事件驅動模型的解決方案。MongoDB 3.6 版本推出的數據更改流,可以用來實現一個類似於 Kafak 一樣的 Message Queue,為各個微服務間的數據協調提供一個簡單易用的線程方案。

MongoDB 一向以其強大的橫向擴展能力著稱。不少 MongoDB 用戶遷移的主要原因就是使用 MongoDB 的 sharding 技術可以突破關係型資料庫在數據量和性能上的瓶頸。MongoDB 的 sharding 有幾個特徵使得其非常適合微服務架構考慮使用:

一個基於 MongoDB 的微服務參考架構圖

分享人簡介:

TJ(唐建法),MongoDB 中文社區輪值主席,MongoDB 官方大中華區首席架構師。

如喜歡本文,請點擊右上角,把文章分享到朋友圈
如有想了解學習的技術點,請留言給若飛安排分享

·END·

相關閱讀:

作者:唐建法

來源:Mongoing中文社區

版權申明:內容來源網絡,版權歸原創者所有。除非無法確認,我們都會標明作者及出處,如有侵權煩請告知,我們會立即刪除並表示歉意。謝謝!

我們都是架構師!

關注架構師(JiaGouX),添加「星標」

獲取每天技術乾貨,一起成為牛逼架構師

技術群請加若飛:1321113940 進架構師群

投稿、合作、版權等郵箱:admin@137x.com

相關焦點

  • 微服務架構下,靜態數據通用緩存機制!
    打開網站看更多優質文章本文轉自:波斯碼連結:https://blog.bossma.cn/architecture/microservice-business-static-data-universal-cache-mechanism/在分布式系統中,特別是最近很火的微服務架構下
  • 微服務架構下靜態數據通用緩存機制
    作者:Ala6連結:https://my.oschina.net/u/3971241/blog/2254252在分布式系統中,特別是最近很火的微服務架構下Java架構交流學習圈:874811168 面向1-3年經驗 Java開發人員 幫助突破瓶頸 提升思維能力以及兩個外部定義:下面以問答的形式來說明為什麼是這樣一種機制。為什麼需要業務服務?既然是微服務架構,當然離不開服務了,因為這裡探討的是業務靜態數據,所以是業務服務。
  • 微服務架構下的靜態數據通用緩存機制!
    在分布式系統中,特別是最近很火的微服務架構下,有沒有或者能不能總結出一個業務靜態數據的通用緩存處理機制或方案
  • 微服務架構下該如何技術選型?
    在現有的微服務架構下,Dubbo 只能說是一個服務治理框架,或者說是一個 RPC 框架,是以接口為粒度,一個接口類就就是一個服務。如果直接用 Dubbo 來實現微服務架構,還缺少以下幾個功能:分布式配置:可以使用 Spring Cloud Config、Apollo 等來實現。鏈路追蹤:可以使用 Zipkin、CAT 等來實現。
  • 微服務架構下落地DevOps的經驗總結
    針對這「說說還可以,一深入討論就吵架」的熱點概念,詳解了在產品研發過程中的思考與實踐,通過多維度的架構與技術剖析,與大家深入溝通雲計算的企業級落地思路。本文是從作者這些年的經歷與實踐出發的總結,也歡迎感興趣的同學參與交流、保持溝通與學習。(備註:作者微信二維碼詳見文末)。
  • 微服務架構體系
    前段內部聽了下分享 Service Mesh。做一些總結架構的演進這種東西有點信雅達,沒什麼絕對標準單體應用:在第一階段的單體應用很好理解。垂直應用:接著隨著業務量增大, 將應用拆成互不相干的幾個應用,Web框架(MVC) 是關鍵。
  • 淺談微服務架構設計
    這個步驟很像單體架構下我們所做的系統高層架構設計,通過高層架構設計會識別並定義出各個業務領域模型,這些業務領域模型包含了業務對象的關鍵操作流程,通過這些業務領域模型就可以輔助我們規劃出整個應用架構,即各模塊之間的協作關係。在識別應用中的服務時,應首先專注於業務,通過業務邏輯的視角可以快速有效地將核心微服務識別出來。
  • 微服務架構設計(一):核心概念&從既有的架構遷移到微服務的策略
    所謂的微服務具體應包含哪些核心的概念?既有的架構遷移到微服務的又有哪些策略?微服務設計是架構設計。所以, 微服務設計不應是一個講求標準答案, 簡單粗暴的設計過程。而應該是一個考量各方因素下的一個決策的過程。所以, 在探討微服務設計前, 我們先來探討下, 所謂的微服務具體應包含哪些核心的概念?
  • 擁抱K8s、微服務和通用數據平臺新架構
    LINE下一步,不只要支持更多種外掛,還希望可以開始考慮到AP效能來調度資源。目前LINE微服務架構上已有超過2,500個微服務。採用微服務架構的好處是,可以加快開發速度,減少各服務間的功能衝突,但缺點是網路失效的頻率增加了,服務配置檔的管理複雜度越來越高,甚至潛在雪崩式錯誤的風險也越來越高,光是貼圖小舖的微服務,就需要25個人力來管理。
  • Medium 的微服務架構
    我們已經建立了幾個附屬服務,但我們還沒有制定採用微服架構系統的戰略。隨著系統變得更加複雜和團隊的壯大,我們在 2018年初遷移到了微服務架構。在這篇文章中,我們希望分享我們的經驗,有效地做到這一點,避免微服務症候群。微服務架構是什麼?
  • 微服務架構設計
    相對單體架構,微服務架構是更面向業務創新的一種架構模式。·獨立團隊和自治團隊對服務的整個生命周期負責,工作在獨立的上下文中,自己決策自己治理,而不需要統一的指揮中心。團隊和團隊之間通過鬆散的社區部落進行銜接。
  • 微服務架構-設計總結
    八、微服務的優點和缺點九、思考:意識的轉變十、參考資料和推薦閱讀一、微服務架構介紹微服務架構(Microservice Architecture)是一種架構概念,旨在通過將功能分解到各個離散的服務中以實現對解決方案的解耦
  • 一文看懂Java微服務架構,WEB2.0,垂直架構,分布式架構,微服務架構
    Java微服務架構目錄:了解開發環境&生成環境WEB1.0 & WEB2.0垂直架構
  • 微服務與SOA架構(一)
    理解這些服務特性有助於在特定架構模式下為服務的上下文給出定義。儘管微服務和SOA都有賴於服務作為其主要的架構組件,他們在服務特性上是有很大的差別的。本章將圍繞不同模式下服務如何分類(也就是服務的分類學)、如何基於服務的所有者進行服務之間的協調以及微服務與SOA之間服務粒度上的不同展開討論。服務分類學指的是在某種架構下服務是如何歸類的。
  • 微服務架構-從理想到現實
    也就是說微服務架構實際是傳統組件化架構設計思想的進一步強化,強化的核心就是獨立和解耦。微服務架構思想的一個重點就是單體應用的拆分。那麼一個企業或團隊是什麼原因實踐微服務?僅僅是微服務是一種架構發展趨勢,是技術熱點,是網際網路大廠都在用嗎?而實際對於很多企業應用微服務可以看到,更多是團隊裡面總有一些技術狂熱份子,熱衷於新架構,新技術,但是對於這些技術究竟解決了哪些業務場景下的問題並不關心。這直接就導致了大量技術在不恰當的時候被應用。
  • Medium的微服務架構解析
    何為微服務架構首先,我們來思考微服務之架構是什麼,不是什麼。微服務是拯救那些過載和混亂軟體工程的技術趨勢之一。在Medium團隊,我們認為它是:「在微服務架構中,多個鬆散耦合的服務協同工作。這是實現微服務架構全部潛力的唯一途徑,錯失任何一個都會成為反模式。如果不是單一的目標,每個微服務慢慢就會做越來越多的事情,成長為多個「單片」服務。我們不會從微服務架構中獲得所有的好處,它會增加我們的運維成本。如果沒有做到鬆耦合,對一項目服務的更改就會波及到其它服務,因此我們無法快速並安全的發布更新,這便是微服務架構的核心優勢。
  • 【雲計算】微服務架構設計 (一): 核心概念 & 從既有的架構遷移到微服務的策略
    微服務設計是架構設計。所以, 微服務設計不應是一個講求標準答案, 簡單粗暴的設計過程。
  • 面試:SOA架構和微服務架構的區別是什麼?
    作者:zpoisonblog.csdn.net/zpoison/article/details/807290521.SOA架構和微服務架構的區別首先SOA和微服務架構一個層面的東西,而對於ESB和微服務網關是一個層面的東西,一個談到是架構風格和方法,一個談的是實現工具或組件。
  • 微服務架構雲端應用
    擁有超過12年網際網路產品開發和管理經驗,專注於網際網路技術架構設計,對產品設計、敏捷開發、安全、OKRs、大數據等領域有深入研究。現推崇反應式編程(http://www.reactivemanifesto.org/),並在多個產品中成功應用。劉總在這次分享中主要為大家介紹了什麼是徽服務,實現微服務有哪些架構模式以及微服務在實際中的應用情況。
  • 一文詳解微服務架構
    本文將介紹微服務架構和相關的組件,介紹他們是什麼以及為什麼要使用微服務架構和這些組件。本文側重於簡明地表達微服務架構的全局圖景,因此不會涉及具體如何使用組件等細節。要理解微服務,首先要先理解不是微服務的那些組件概念。