【深智書摘】從「應用」與「叢集」理解分散式系統

更新 發佈閱讀 8 分鐘

隨著軟體複雜度的增加和使用者規模的增長,分散式系統獲得了廣泛應用。對於軟體開發者而言,掌握分散式系統的相關知識是十分必要的。

但分散式系統包括理論、實踐、專案等多方面內容。這些內容往往交織穿插在一起,給軟體開發者的學習帶來了不少困難,讓許多軟體開發者在學習過程中感到混亂和迷茫。

有鑑於此,本文將從應用結構的演進歷程談起,分析分散式系統是如何產生的,並列出判斷系統是否為分散式系統的依據。

概述

隨著軟體規模、性能要求的不斷提升,分散式系統得到快速發展。分散式系統透過許多低成本節點的協作來完成原本需要龐大單體應用才能實現的功能,在降低硬體成本的基礎上,提升了軟體的可靠性、擴充性、靈活性。

然而,分散式系統在帶來上述優點的同時,也帶來了許多技術問題。

首先,分散式系統的架構和實現需要許多分散式理論和演算法作為基礎,如CAP 定理、BASE 定理、Paxos 演算法、兩階段提交演算法、三階段提交演算法等。如果不能了解這些演算法的具體含義,則會給架構和開發工作帶來困擾。

其次,分散式系統的實現依賴大量的技術方案,如分散式鎖、分散式交易、服務發現、服務呼叫、服務保護、服務閘道等。如果對這些技術的具體實施方案和關鍵點了解不透徹,則可能會在專案中引入漏洞。

最後,分散式系統的部署需要依賴許多中介軟體,如訊息系統中介軟體、分散式協調中介軟體等。如果對這些中介軟體的功能和實現原理不清楚,則可能會導致選型和使用上的錯誤,增加應用的開發成本。

應用的演進歷程

單體應用

單體應用是最簡單和最純粹的應用形式,它就是部署在一台機器上的單一應用。單體應用中可以包含很多模組,模組之間會互相呼叫。這些呼叫都在應用內展開,十分方便。因此,單體應用是一個高度內聚的個體,其內部各個模組間是高度耦合的。

單體應用的開發、維護、部署成本低廉,適合實現一些功能簡單、併發數低、容量小的應用的開發需求。

當應用的功能變得複雜、併發數不斷增高、容量不斷變大時,單體應用的規模也會不斷擴大。這會帶來以下兩個方面的挑戰。

■硬體方面。龐大的單體應用需要與之對應的伺服器提供支援,這種伺服器被稱為「大型主機」,其購買、維護費用都極其高昂。

■軟體方面。單體應用內模組間是高度耦合的,應用規模的增大讓這種耦合變得極為複雜,這使得應用軟體的開發維護變得困難。

因此,當應用的功能足夠複雜、併發數足夠高、容量足夠大時,就需要對單體應用進行拆分,以便於對功能、併發數、容量進行分散。這就演變成了叢集應用。

叢集應用

叢集應用可以對應用的併發數、容量進行分散。叢集應用包含多個同質的應用節點,這些節點組成叢集共同對外提供服務。這裡說的「同質」是指每個應用節點執行同樣的程式、具有同樣的設定,它們像是從一個範本中複製出來的一樣。

為了讓叢集應用中的每個節點都承擔一部分併發數和容量,可以透過反向代理等手段將外界請求分散到應用的多個節點上。叢集應用的結構如圖1所示。

raw-image

但叢集應用帶來的最明顯的問題是同一個使用者發出的多個請求可能會落在不同的節點上,打破了服務的連貫性。

舉例來說,使用者發出R1、R2兩個請求,且R2的執行要依賴R1的資訊(如R1 觸發一個任務,R2用來查詢任務的執行結果)。如果R1和R2被分配到不同的節點上,則R2的操作可能無法正常執行。

為了解決上述問題,演化出以下幾種叢集方案。

▨ 無狀態的節點叢集

無狀態應用是最容易從單體形式擴充到叢集形式的一類應用。對於無狀態應用而言,假設使用者先後發出R1、R2 兩個請求,則無狀態應用無論是否在之前接收過請求R1,總對請求R2 傳回同樣的結果。即無狀態應用列出的任何一個請求的結果都和該應用之前收到的請求無關。

要想讓應用滿足無狀態,必須保證應用的狀態不會因為介面的呼叫而發生變化。查詢介面能滿足這點,舉例來說,對於使用者而言,一個新聞展示應用是無狀態的。

即使是無狀態的節點叢集,也要面對協作問題。平行喚醒問題就是一個典型的協作問題,舉例來說,一個無狀態節點叢集需要在每天淩晨對外發送一封郵件,我們會發現該叢集中的所有節點會在淩晨同時被喚醒並各自發送一封郵件。

我們希望整個節點叢集對外發送一封郵件而非讓每個節點都發送一封郵件。

在這種情況下,可以透過外部請求喚醒來解決無狀態節點叢集的平行喚醒問題。在指定時刻由外部應用發送一個請求給服務叢集觸發任務,該請求最終只會交給一個節點處理,因此實現了獨立喚醒。

無狀態節點叢集設計簡單,可以方便地進行擴充,較少遇到協作問題,但只適合無狀態應用,有很大的局限性。

很多應用是有狀態的,如某個節點接收到外部請求後修改了某物件的屬性,後面的請求再查詢物件屬性時便應該讀取到修改後的結果。如果後面的請求落到了其他節點上,則可能讀取到修改前的結果。這類應用無法擴充為無狀態的節點叢集。

▨ 單一服務的節點叢集

許多服務是有狀態的,使用者的歷史請求在應用中組成了上下文,應用必須結合上下文對使用者的請求進行回覆。舉例來說,在聊天應用中,使用者之前的對話(透過過去的請求實現)便是上下文;在遊戲應用中,使用者之前購買的裝備、晉升的等級(透過過去的請求實現)便是上下文。

有狀態的服務在處理使用者的每個請求時必須讀取和修改使用者的上下文資訊,這在單體應用中是容易實現的,但在節點叢集中,這一切就變得複雜起來。其中一個最簡單的辦法是在節點和使用者之間建立對應關係:

■任意使用者都有一個對應的節點,該節點上保存該使用者的上下文資訊。

■某個使用者的請求總落在與之對應的節點上。

使用者與指定節點的對應關係如圖2 所示。其典型特點就是各個節點是完全隔離的。這些節點執行同樣的程式,具有同樣的設定,然而卻保存了不同使用者的上下文資訊,各自服務自身對應的使用者。

raw-image

雖然叢集包含多個節點,但是從使用者角度來看,服務某個使用者的始終是同一個節點,因此我們將這種叢集稱為單一服務的節點叢集。

實現單一服務的節點叢集要解決的問題是,如何建立和維護使用者與節點之間的對應關係。具體的實現有很多種,我們列舉常用的幾種。

■在使用者註冊帳號時由使用者自由選擇節點。很多遊戲服務就採用這種方式,讓使用者自由選擇帳號所在的區。

■在使用者註冊帳號時根據使用者所處的網路分配節點。一些郵件服務就採用這種方式。

■在使用者註冊帳號時根據使用者 ID 隨機分配節點。許多聊天應用就採用這種方式。

■在使用者登入帳號時隨機或使用規則分配節點,然後將分配結果寫入cookie,接下來根據請求中的cookie 將使用者請求分配到指定節點。

其中,最後一種方式與前幾種方式略有不同。前幾種方式能保證使用者對應的節點在整個使用者週期內不改變,而最後一種方式則只保證使用者對應的節點在一次階段週期內不改變。最後一種方式適合用在兩次階段之間無上下文關係的場景中,如一些登入應用、許可權應用等,它則只需要維護使用者這次階段內的上下文資訊。

無論採用了哪種方式,使用者的請求都會被路由傳輸到其對應的節點上。根據應用分流方案的不同,該路由操作可以由反向代理、閘道等元件完成。

單一服務的節點叢集能夠解決有狀態服務的問題,但因為各個節點之間是隔離的,無法互相備份。當某個服務節點崩潰時,會使得該節點對應的使用者失去服務。因此,這種設計方案的容錯性比較差。

看完了以上的教學,想必讀者對分散式系統會有更多的認識。

raw-image

本文節錄自深智數位出版之《最新世代平行運算 - 分散式系統主流框架實作指南》

留言
avatar-img
深智數位的沙龍
11會員
25內容數
深智數位的沙龍的其他內容
2023/08/02
在機器學習中,我們的目標是找到一種能夠最好地描述數據的模型。例如,在迴歸問題中,我們希望找到一種函數,該函數能以一種對我們的目標變數(例如:銷售量、股票價格等) 的最佳估計的方式,描述輸入特徵(例如:廣告支出、市場狀況等)。
Thumbnail
2023/08/02
在機器學習中,我們的目標是找到一種能夠最好地描述數據的模型。例如,在迴歸問題中,我們希望找到一種函數,該函數能以一種對我們的目標變數(例如:銷售量、股票價格等) 的最佳估計的方式,描述輸入特徵(例如:廣告支出、市場狀況等)。
Thumbnail
2023/07/21
  在程式設計中,變數(Variable)是一個代表內存位置的符號,用於存儲和操作數據。它是一個內存單元,可以存儲各種類型的數據,例如整數、浮點數、字符串等。變數的值可以在程式執行時改變,並在需要時被讀取。 變數是暫時存放資料用的,可以將變數想像成是一個箱子,箱子裡面可以是空的,
Thumbnail
2023/07/21
  在程式設計中,變數(Variable)是一個代表內存位置的符號,用於存儲和操作數據。它是一個內存單元,可以存儲各種類型的數據,例如整數、浮點數、字符串等。變數的值可以在程式執行時改變,並在需要時被讀取。 變數是暫時存放資料用的,可以將變數想像成是一個箱子,箱子裡面可以是空的,
Thumbnail
2023/05/17
新手在使用ChatGPT 時,對於ChatGPT的回答普遍印象是廢話連篇,而這通常是因為沒有給出足夠清晰的指示所導致,以下將介紹3個讓你跟ChatGPT溝通更有效的提示技巧,幫助讀者快速掌握提升回答品質的秘訣!
Thumbnail
2023/05/17
新手在使用ChatGPT 時,對於ChatGPT的回答普遍印象是廢話連篇,而這通常是因為沒有給出足夠清晰的指示所導致,以下將介紹3個讓你跟ChatGPT溝通更有效的提示技巧,幫助讀者快速掌握提升回答品質的秘訣!
Thumbnail
看更多
你可能也想看
Thumbnail
在 vocus 與你一起探索內容、發掘靈感的路上,我們又將啟動新的冒險——vocus App 正式推出! 現在起,你可以在 iOS App Store 下載全新上架的 vocus App。 無論是在通勤路上、日常空檔,或一天結束後的放鬆時刻,都能自在沈浸在內容宇宙中。
Thumbnail
在 vocus 與你一起探索內容、發掘靈感的路上,我們又將啟動新的冒險——vocus App 正式推出! 現在起,你可以在 iOS App Store 下載全新上架的 vocus App。 無論是在通勤路上、日常空檔,或一天結束後的放鬆時刻,都能自在沈浸在內容宇宙中。
Thumbnail
vocus 慶祝推出 App,舉辦 2026 全站慶。推出精選內容與數位商品折扣,訂單免費與紅包抽獎、新註冊會員專屬活動、Boba Boost 贊助抽紅包,以及全站徵文,並邀請你一起來回顧過去的一年, vocus 與創作者共同留下了哪些精彩創作。
Thumbnail
vocus 慶祝推出 App,舉辦 2026 全站慶。推出精選內容與數位商品折扣,訂單免費與紅包抽獎、新註冊會員專屬活動、Boba Boost 贊助抽紅包,以及全站徵文,並邀請你一起來回顧過去的一年, vocus 與創作者共同留下了哪些精彩創作。
Thumbnail
什麼是集中式系統架構 簡單來說就是,應用程式和數據庫都集中在一台中心端Server身上,而使用者通過終端設備來訪問這個中心化系統。
Thumbnail
什麼是集中式系統架構 簡單來說就是,應用程式和數據庫都集中在一台中心端Server身上,而使用者通過終端設備來訪問這個中心化系統。
Thumbnail
本篇文章將會繼續上一篇的內容,還沒看過上一篇的朋友,記得先看完上一篇再繼續本篇的閱讀唷。 連結﹔談談軟體元件的內聚與耦合(1) 前一篇我們提到了元件的內聚,以及用來衡量內聚性的三個標準,CCP、CRP與REP。 在這篇中,我們要來繼續談談軟體的耦合性。
Thumbnail
本篇文章將會繼續上一篇的內容,還沒看過上一篇的朋友,記得先看完上一篇再繼續本篇的閱讀唷。 連結﹔談談軟體元件的內聚與耦合(1) 前一篇我們提到了元件的內聚,以及用來衡量內聚性的三個標準,CCP、CRP與REP。 在這篇中,我們要來繼續談談軟體的耦合性。
Thumbnail
介紹兩個系統創造思維模式 - 任務一體化和屬性相依。 系統創造思維的特點和限制
Thumbnail
介紹兩個系統創造思維模式 - 任務一體化和屬性相依。 系統創造思維的特點和限制
Thumbnail
人月神話一書中提到軟體工程的任務有兩種性質:本質性與附屬性。後者可能會隨著工具改良(如更好的程式語言及 IDE)而逐步改善,但前者才是真正複雜且難以攻克的困難點。 而系統串接亦然,其本身很常同時參雜著這兩種問題。或許在我們一切任務開展之前都順著這兩個大類對子分項做規劃會是個不錯的思路方向。說到底所
Thumbnail
人月神話一書中提到軟體工程的任務有兩種性質:本質性與附屬性。後者可能會隨著工具改良(如更好的程式語言及 IDE)而逐步改善,但前者才是真正複雜且難以攻克的困難點。 而系統串接亦然,其本身很常同時參雜著這兩種問題。或許在我們一切任務開展之前都順著這兩個大類對子分項做規劃會是個不錯的思路方向。說到底所
Thumbnail
這篇分享希望能讓你了解 目前企業在資訊基礎設施上有哪些常用架構,彼此之間又有甚麼樣的差異, 而企業又要如何選擇出適合自己的架構呢? 本篇會分享三種主流架構: 1.三層式架構 2.超融合架構 3.非聚合式超融合架構 4.總結
Thumbnail
這篇分享希望能讓你了解 目前企業在資訊基礎設施上有哪些常用架構,彼此之間又有甚麼樣的差異, 而企業又要如何選擇出適合自己的架構呢? 本篇會分享三種主流架構: 1.三層式架構 2.超融合架構 3.非聚合式超融合架構 4.總結
Thumbnail
隨著軟體規模、性能要求的不斷提升,分散式系統得到快速發展。分散式系統透過許多低成本節點的協作來完成原本需要龐大單體應用才能實現的功能,在降低硬體成本的基礎上,提升了軟體的可靠性、擴充性、靈活性。
Thumbnail
隨著軟體規模、性能要求的不斷提升,分散式系統得到快速發展。分散式系統透過許多低成本節點的協作來完成原本需要龐大單體應用才能實現的功能,在降低硬體成本的基礎上,提升了軟體的可靠性、擴充性、靈活性。
Thumbnail
軟體開發一個很迷人的地方是可以在架空的世界(電腦世界)中重新思考、解構並處理真實世界的問題。但要怎樣真正有效的解決問題就很看各家功力了。 這篇文章我們暫且放下溝通及流程規劃的議題,聚焦來看看純粹領域差異造成的困難以及該怎麼面對。 回顧過往曾經觸碰過的領域真的滿多,茲列舉幾個
Thumbnail
軟體開發一個很迷人的地方是可以在架空的世界(電腦世界)中重新思考、解構並處理真實世界的問題。但要怎樣真正有效的解決問題就很看各家功力了。 這篇文章我們暫且放下溝通及流程規劃的議題,聚焦來看看純粹領域差異造成的困難以及該怎麼面對。 回顧過往曾經觸碰過的領域真的滿多,茲列舉幾個
Thumbnail
踏入工程師生涯也十幾個年頭了,這些年工作主體逐漸從開發轉向諮詢規劃。遊走於兩者之間總會碰到一些相持不下的時刻,比如 PM 覺得某某功能很重要,可工程部門一直想要說服說這個做不了。處理得好就是雙贏,處理得不好往往就是不歡而散。 當一個新的產品及服務放到你面前的時候,你是怎麼去理解一個產品的?
Thumbnail
踏入工程師生涯也十幾個年頭了,這些年工作主體逐漸從開發轉向諮詢規劃。遊走於兩者之間總會碰到一些相持不下的時刻,比如 PM 覺得某某功能很重要,可工程部門一直想要說服說這個做不了。處理得好就是雙贏,處理得不好往往就是不歡而散。 當一個新的產品及服務放到你面前的時候,你是怎麼去理解一個產品的?
Thumbnail
回顧過往,參與協作了超過 60 個軟體方案。 曾接觸過合作內容差異頗大,比如 仔細看看也還蠻多面向的,未來好像可以就這些部分做些分享交流。但總會想到一件事,到底這些開發裡頭到底都在做些什麼? 身為設計師是否常常覺得某些著名產品的體驗不好?比如該對齊沒對齊或重要功能拜放在很難找到的地方。
Thumbnail
回顧過往,參與協作了超過 60 個軟體方案。 曾接觸過合作內容差異頗大,比如 仔細看看也還蠻多面向的,未來好像可以就這些部分做些分享交流。但總會想到一件事,到底這些開發裡頭到底都在做些什麼? 身為設計師是否常常覺得某些著名產品的體驗不好?比如該對齊沒對齊或重要功能拜放在很難找到的地方。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News