服務分布式的區別

      網友投稿 929 2025-04-01

      分布式架構是分布式計算技術的應用和工具,目前成熟的技術包括J2EE, CORBA和.NET(DCOM),這些技術牽扯的內容非常廣,相關的書籍也非常多,也沒有涉及這些技術的細節,只是從各種分布式系統平臺產生的背景和在軟件開發中應用的情況來探討它們的主要異同。

      微服務架構是一項在云中部署應用和服務的新技術。大部分圍繞微服務的爭論都集中在容器或其他技術是否能很好的實施微服務,而紅帽說API應該是重點。(推薦學習:Java視頻教程)

      微服務可以在“自己的程序”中運行,并通過“輕量級設備與HTTP型API進行溝通”。關鍵在于該服務可以在自己的程序中運行。通過這一點我們就可以將服務公開與微服務架構(在現有系統中分布一個API)區分開來。在服務公開中,許多服務都可以被內部獨立進程所限制。如果其中任何一個服務需要增加某種功能,那么就必須縮小進程范圍。在微服務架構中,只需要在特定的某種服務中增加所需功能,而不影響整體進程的架構。

      從概念理解,分布式服務架構強調的是服務化以及服務的分散化,微服務則更強調服務的專業化和精細分工;從實踐的角度來看,微服務架構通常是分布式服務架構,反之則未必成立。所以,選擇微服務通常意味著需要解決分布式架構的各種難題。

      區別分布式的方式是根據不同機器不同業務。

      將一個大的系統劃分為多個業務模塊,業務模塊分別部署到不同的機器上,各個業務模塊之間通過接口進行數據交互。區別分布式的方式是根據不同機器不同業務。

      微服務更加強調單一職責、輕量級通信(HTTP)、獨立性并且進程隔離。

      微服務與分布式的細微差別是,微服務的應用不一定是分散在多個服務器上,他也可以是同一個服務器。

      分布式是否屬于微服務?

      不一定,如果一個很大應用,拆分成三個應用,但還是很龐大,雖然分布式了,但不是微服務。。微服務核心要素是微小。。

      微服務架構是分布式服務架構的子集。

      微服務架構通過更細粒度的服務切分,使得整個系統的迭代速度并行程度更高,但是運維的復雜度和性能會隨著服務的粒度更細而增加。

      微服務重在解耦合,使每個模塊都獨立。分布式重在資源共享與加快計算機計算速度。

      分布式:分散壓力。微服務:分散能力。

      課程介紹

      微服務架構的技術體系、社區目前已經越來越成熟。在最初系統架構的搭建,或者當現有架構已到達瓶頸需要進行架構演進時,很多架構師、運維工程師會考慮是否需要搭建微服務架構體系。雖然很多文章都說微服務架構是復雜的、會帶來很多分布式的問題,但只要我們了解這些問題,并找到解法,就會有種撥開云霧的感覺。

      微服務架構也不是完美的,世上沒有完美的架構,微服務架構也是隨著業務、團隊成長而不斷演進的。最開始可能就幾個、十幾個微服務,每個服務是分庫的,通過 API Gateway 并行進行服務數據合并、轉發。隨著業務擴大、不斷地加入搜索引擎、緩存技術、分布式消息隊列、數據存儲層的數據復制、分區、分表等。

      本課程會一一解開微服務架構下分布式場景的問題,以及通過對于一些分布式技術的原理、模型和算法的介紹,來幫助想要實施微服務架構的工程師們知其然并知其所以然。

      課程內容

      微服務架構的演變

      微服務是一種服務間松耦合的、每個服務之間高度自治并且使用輕量級協議進行通信的可持續集成部署的分布式架構體系。這一句包含了微服務的特點,微服務架構和其他架構有什么區別?以下對比一些常見的架構。

      單體架構

      單體架構是最簡單的軟件架構,常用于傳統的應用軟件開發以及傳統 Web 應用。傳統 Web 應用,一般是將所有功能模塊都打包(jar、war)在一個 Web 容器(JBoss、Tomcate)中部署、運行。隨著業務復雜度增加、技術團隊規模擴大,在一個單體應用中維護代碼,會降低開發效率,即使是處理一個小需求,也需要將所有機器上的應用全部部署一遍,增加了運維的復雜度。

      SOA 架構

      當某一天使用單體架構發現很難推進需求的開發、以及日積月累的技術債時,很多企業會開始做單體服務的拆分,拆分的方式一般有水平拆分和垂直拆分。垂直拆分是把一個應用拆成松耦合的多個獨立的應用,讓應用可以獨立部署,有獨立的團隊進行維護;水平拆分是把一些通用的,會被很多上層服務調用的模塊獨立拆分出去,形成一個共享的基礎服務,這樣拆分可以對一些性能瓶頸的應用進行單獨的優化和運維管理,也在一定程度上防止了垂直拆分的重復造輪子。

      SOA 也叫面向服務的架構,從單體服務到 SOA 的演進,需要結合水平拆分及垂直拆分。SOA 強調用統一的協議進行服務間的通信,服務間運行在彼此獨立的硬件平臺但是需通過統一的協議接口相互協作,也即將應用系統服務化。舉個易懂的例子,單體服務如果相當于一個快餐店,所有的服務員職責都是一樣的,又要負責收銀結算,又要負責做漢堡,又要負責端盤子,又要負責打掃,服務員之間不需要有交流,用戶來了后,服務員從前到后負責到底。SOA 相當于讓服務員有職責分工,收銀員負責收銀,廚師負責做漢堡,保潔阿姨負責打掃等,所有服務員需要用同一種語言交流,方便工作協調。

      微服務和 SOA

      微服務也是一種服務化,不過其和 SOA 架構的服務化概念也是有區別的,可以從以下幾個關鍵字來理解:

      松耦合:每個微服務內部都可以使用 DDD(領域驅動設計)的思想進行設計領域模型,服務間盡量減少同步的調用,多使用消息的方式讓服務間的領域事件來進行解耦。

      輕量級協議:Dubbo 是 SOA 的開源的標準實現之一,類似的還有像 gRPC、Thrift 等。微服務更傾向于使用 Restful 風格的 API,輕量級的協議可以很好得支持跨語言開發的服務,可能有的微服務用 Java 語言實現,有的用 Go 語言,有的用 C++,但所有的語言都可以支持 Http 協議通信,所有的開發人員都能理解 Restful 風格 API 的含義。

      高度自治和持續集成:從底層的角度來說,SOA 更加傾向于基于虛擬機或者服務器的部署,每個應用都部署在不同的機器上,一般持續集成工具更多是由運維團隊寫一些 Shell 腳本以及提供基于共同協議(比如 Dubbo 管理頁面)的開發部署頁面。微服務可以很好得和容器技術結合,容器技術比微服務出現得晚,但是容器技術的出現讓微服務的實施更加簡便,目前 Docker 已經成為很多微服務實踐的基礎容器。因為容器的特色,所以一臺機器上可以部署幾十個、幾百個不同的微服務。如果某個微服務流量壓力比其他微服務大,可以在不增加機器的情況下,在一臺機器上多分配一些該微服務的容器實例。同時,因為 Docker 的容器編排社區日漸成熟,類似 Mesos、Kubernetes 及 Docker 官方提供的 Swarm 都可以作為持續集成部署的技術選擇。

      其實從架構的演進的角度來看,整體的演進都是朝著越來越輕量級、越來越靈活的應用方向發展,甚至到近兩年日漸成熟起來的 Serverless(無服務)架構。從單體服務到分層的服務,再到面向服務、再到微服務甚至無服務,對于架構的挑戰是越來越大。

      微服務架構和分布式

      微服務架構屬于分布式系統嗎?答案是肯定的。微服務和 SOA 都是典型的分布式架構,只不過微服務的部署粒度更細,服務擴展更靈活。

      理解微服務中的分布式

      怎樣理解微服務中的分布式?舉一個招聘時一個同學來面試的例子。A 同學說,目前所在公司在做從單應用到微服務架構遷移,已經差不多完成了。提到微服務感覺就有話題聊了,于是便問“是否可以簡單描述下服務拆分后的部署結構、底層存儲的拆分、遷移方案?”。于是 A 同學說,只是做了代碼工程結構的拆分,還是原來的部署方式,數據庫還是那個庫,所有的微服務都用一個庫,分布式事務處理方式是“避免”,盡量都同步調用……于是我就跟這位同學友好地微笑說再見了。

      微服務的分布式不僅僅是容器應用層面的分布式,其為了高度自治,底層的存儲體系也應該互相獨立,并且也不是所有的微服務都需要持久化的存儲服務。一個“手機驗證碼”微服務可能底層存儲只用一個 Redis;一個“營銷活動搭建頁面”微服務可能底層存儲只需要一個 MongoDB。

      微服務中的分布式場景除了服務本身需要有服務發現、負載均衡,微服務依賴的底層存儲也會有分布式的場景:為了高可用性和性能需要處理數據庫的復制、分區,并且在存儲的分庫情況下,微服務需要能保證分布式事務的一致性。

      課程背景

      微服務架構的技術體系、社區目前已經越來越成熟,所以在初期選擇使用或者企業技術體系轉型微服務的時候,需要了解微服務架構中的分布式的問題:

      1.在所有服務都是更小單元的部署結構時,一個請求需要調動更多的服務資源,怎樣獲得更好的性能?

      2.當業務規模增大,需要有地理分布不同的微服務集群時,其底層的數據存儲集群是多數據中心還是單數據集群?

      3.數據存儲如何進行數據復制?

      4.業務數據達到大數據量時怎樣進行數據的分區?

      5.分布式事務怎樣保證一致性?

      6.不同程度的一致性有什么差別?

      7.基于容器技術的服務發現怎么處理?

      8.應該用哪些 RPC 技術,用哪些分布式消息隊列來完成服務通信和解耦?

      9.那么多的分布式技術框架、算法、服務應該選哪個才適合企業的業務場景?

      本課程從微服務不得不面對和解決的分布式問題出發,包含分布式技術的一系列理論以及架構模型、算法的介紹,同時結合技術選型和實踐應用,提供一系列解決方案的梳理。相信閱讀完整個課程,你會對微服務的分布式問題有個系統地理解。本課程會對微服務的分布式場景問題一一擊破,為你提供解決思路。

      課程內容

      本課程示例代碼地址如下:

      1.Microservice

      2.API-gateway

      分布式系統的問題

      引出分布式系統的可能問題:節點故障、網絡延遲,結合錯誤檢測的可行方案進行介紹;

      分布式中的時間和順序的問題,以及標量時鐘和向量時鐘的實現。

      分布式數據存儲

      分布式數據存儲的技術選型、關系型數據庫以及一些流行的 NoSQL 技術介紹(MongoDB、Redis、Neo4j 及 Cassandra 等);

      分布式存儲技術使用的數據結構,了解底層數據存儲原理(HashTable、SSTable、LSMTree、BTree 等);

      各個存儲方案使用的場景以及對比。

      數據復制

      對于大規模存儲集群,需要進行數據庫的復制、排除單點故障;

      數據復制的模型和實現以及幾種復制日志的實現方式;

      主備同步、主主復制、多數據中心的數據復制方案;

      數據復制中的讀寫一致性問題以及寫沖突問題的解決;

      介紹以 MySQL 為例延伸集群數據復制方案。

      數據分區

      當單個領域模型維度的數據已經到一定規模時,需要進行數據分區,減輕單庫壓力。數據分區和分表又有哪些不同?數據分區可以如何實現?

      以 MySQL 的分區策略為例介紹不同分區策略的實現。

      數據分區后,請求的路由有哪些解決方案?會展開介紹不同的方案又有什么差別。

      服務發現和服務通信

      基于容器技術的微服務體系,怎樣選擇服務發現、負載均衡的技術實現?不同的服務發現的技術有什么區別,如何選型?

      為了達到松耦合的目的以及基于 DDD 思想,微服務之間減少服務調用可以通過哪些技術實現?API Gateway 可以用哪些技術框架實現?遠程調用可以有哪些技術框架?怎樣提高同步通信的性能?

      分布式的消息隊列都有哪些開源、商業實現?應該怎樣選擇適合的消息隊列?

      使用 DDD 思想應該如何應對服務通信,如何在實踐中應用 DDD?

      分布式存儲集群的事務

      理解分布式中的事務以及本地事務的基礎概念;

      分布式存儲的隔離級別以及各個 DB 支持的隔離方案的實現原理;

      以 MySQL InnoDB 中的 MVCC 為例看并發控制的在 MySQL 的實現,學習存儲系統對于分布式事務的實現思想。

      分布式一致性

      了解分布式系統的一致性有哪些問題以及一致性的幾種實現程度的模型:線性一致性(強一致性)、順序一致性及因果一致性、最終一致性;

      分布式一致性相關的理論 CAP(CA、CP、AP 的相關算法)的介紹以及適合用于哪些實踐;

      介紹 FLP 不可能結果,以及 BASE 理論。

      分布式事務實踐

      了解微服務中分布式事務的問題;

      1.介紹強一致性的實踐:二階段、三階段。2PC、3PC 的優缺點和限制,XA 協議的介紹和實踐方案,以及最終一致性實踐:TCC 模型和實踐方案;

      2.分布式鎖的實現模型和實踐方案;

      3.基于微服務下的分布式事務實踐案例分析。

      共識問題

      了解為什么分布式場景下有共識問題;

      介紹共識算法和全局消息廣播的實現,公式算法的基礎:leader 選舉和 quorum 算法,以及一些已實現的算法的介紹和對比:VSR、Raft、Paxos、ZAB;

      共識算法在微服務體系的應用場景介紹:服務發現、一致性 kv 存儲(Etcd、Zk)以及技術的選型如何權衡一致性的追求和性能。

      架構設計

      了解了很多分布式的問題和解決方案之后,回歸微服務架構模型、技術選型、再回顧下微服務的弊端和特點;

      微服務體系的架構要素分析:安全、伸縮性、性能、可用性、擴展性;

      結合團隊、業務場景的 DDD 實踐和總結。

      課程寄語

      如果你是一位開發工程師,相信閱讀完本系列課程,將會了解很多分布式系統的理論知識,同時也會理解一些分布式存儲、中間件技術的原理,對工作中的分布式架構會有體系化的清晰認知。

      如果你是一位架構師,本系列課程提供了對于分布式系統問題的全面梳理,以及一些技術背后的理論,結合實踐和目前業界先進的方案,對于技術選型和架構搭建提供了參考。

      第01課:分布式系統的問題

      前言

      無論是 SOA 或者微服務架構,都是必須要面對和解決一些分布式場景下的問題。如果只是單服務、做個簡單的主備,那么編程則會成為一件簡單幸福的事,只要沒有 bug,一切都會按照你的預期進行。然而在分布式系統中,如果想當然的去按照單服務思想編程和架構,那可能會收獲很多意想不到的“驚喜”:網絡延遲導致的重復提交、數據不一致、部分節點掛掉但是任務處理了一半等。在分布式系統環境下編程和在單機器系統上寫軟件最大的差別就是,分布式環境下會有很多很“詭異”的方式出錯,所以我們需要理解哪些是不能依靠的,以及如何處理分布式系統的各種問題。

      理想和現實

      微服務架構跟 SOA 一樣,也是服務化的思想。在微服務中,我們傾向于使用 RESTful 風格的接口進行通信,使用 Docker 來管理服務實例。我們的理想是希望分布式系統能像在單個機器中運行一樣,就像客戶端應用,再壞的情況,用戶只要一鍵重啟就可以重新恢復,然而現實是我們必須面對分布式環境下的由網絡延遲、節點崩潰等導致的各種突發情況。

      在決定使用分布式系統,或者微服務架構的時候,往往是因為我們希望獲得更好的伸縮性、更好的性能、高可用性(容錯)。雖然分布式系統環境更加復雜,但只要能了解分布式系統的問題以及找到適合自己應用場景的方案,便能更接近理想的開發環境,同時也能獲得伸縮性、性能、可用性。

      分布式系統的可能問題

      分布式系統從結構上來看,是由多臺機器節點,以及保證節點間通信的網絡組成,所以需要關注節點、網絡的特征。

      (1)部分失敗

      在分布式環境下,有可能是節點掛了,或者是網絡斷了,如下圖:

      微服務和分布式的區別

      如果系統中的某個節點掛掉了,但是其他節點可以正常提供服務,這種部分失敗,不像單臺機器或者本地服務那樣好處理。單機的多線程對象可以通過機器的資源進行協調和同步,以及決定如何進行錯誤恢復。但在分布式環境下,沒有一個可以來進行協調同步、資源分配以及進行故障恢復的節點,部分失敗一般是無法預測的,有時甚至無法知道請求任務是否有被成功處理。

      所以在開發需要進行網絡通訊的接口時(RPC 或者異步消息),需要考慮到部分失敗,讓整個系統接受部分失敗并做好容錯機制,比如在網絡傳輸失敗時要能在服務層處理好,并且給用戶一個好的反饋。

      (2)網絡延遲

      網絡是機器間通信的唯一路徑,但這條唯一路徑并不是可靠的,而且分布式系統中一定會存在網絡延遲,網絡延遲會影響系統對于“超時時間”、“心跳機制”的判斷。如果是使用異步的系統模型,還會有各種環節可能出錯:可能請求沒有成功發出去、可能遠程節點收到請求但是處理請求的進程突然掛掉、可能請求已經處理了但是在 Response,可能在網絡上傳輸失敗(如數據包丟失)或者延遲,而且網絡延遲一般無法辨別。

      即使是 TCP 能夠建立可靠的連接,不丟失數據并且按照順序傳輸,但是也處理不了網絡延遲。對于網絡延遲敏感的應用,使用 UDP 會更好,UDP 不保證可靠傳輸,也不會丟失重發,但是可以避免一些網絡延遲,適合處理音頻和視頻的應用。

      (3)沒有共享內存、鎖、時鐘

      分布式系統的節點間沒有共享的內存,不應理所當然認為本地對象和遠程對象是同一個對象。分布式系統也不像單機器的情況,可以共享同一個 CPU 的信號量以及并發操作的控制;也沒有共享的物理時鐘,無法保證所有機器的時間是絕對一致的。時間的順序是很重要的,夸張一點說,假如對于一個人來說,從一個時鐘來看是 7 點起床、8 點出門,但可能因為不同時鐘的時間不一致,從不同節點上來看可能是 7 點出門、8 點起床。

      在分布式環境下開發,需要我們能夠有意識地進行問題識別,以上只是舉例了一部分場景和問題,不同的接口實現,會在分布式環境下有不同的性能、擴展性、可靠性的表現。下面會繼續上述的問題進行探討,如何實現一個更可靠的系統。

      概念和處理模型

      對于上述分布式系統中的一些問題,可以針對不同的特征做一些容錯和處理,下面主要看一下錯誤檢測以及時間和順序的處理模型。在實際處理中,一般是綜合多個方案以及應用的特點。

      錯誤檢測

      對于部分失敗,需要一分為二的看待。

      節點的部分失敗,可以通過增加錯誤檢測的機制,自動檢測問題節點。在實際的應用中,比如有通過 Load Balancer,自動排除問題節點,只將請求發送給有效的節點。對于需要有 Leader 選舉的服務集群來說,可以引入實現 Leader 選舉的算法,如果 Leader 節點掛掉了,其余節點能選舉出新的 Leader。實現選舉算法也屬于共識問題,在后續文章中會再涉及到幾種算法的實現和應用。

      網絡問題:由于網絡的不確定性,比較難說一個節點是否真正的“在工作”(有可能是網絡延遲導致的錯誤),通過添加一些反饋機制可以在一定程度確定節點是否正常運行,比如:

      健康檢查機制,一般是通過心跳檢測來實現的,比如使用 Docker 的話,Consul、Eureka 都有健康檢查機制,當發送心跳請求發現容器實例已經無法回應時,可以認為服務掛掉了,但是卻很難確認在這個 Node/Container 中有多少數據被正確的處理了。

      如果一個節點的某個進程掛了,但是整個節點還可以正常運行。在使用微服務體系中是比較常見的,一臺機器上部署著很多容器實例,其中個容器實例(即相當于剛才描述掛掉的進程)掛掉了,可以有一個方式去通知其他容器來快速接管,而不用等待執行超時。比如 Consul 通過 Gossip 協議進行多播,關于 Consul,可以參考這篇 Docker 容器部署 Consul 集群 內容。在批處理系統中,HBase 也有故障轉移機制。

      在實際做錯誤檢測處理時,除了需要 節點、容器 做出積極的反饋,還要有一定的重試機制。重試的實現可以基于網絡傳輸協議,如使用 TCP 的 RTT;也可以在應用層實現,如 Kafka 的 at-least-once 的實現。基于 Docker 體系的應用,可以使用 SpringCloud 的 Retry,結合 Hytrix、Ribbon 等。對于需要給用戶反饋的應用,不太建議使用過多重試,根據不同的場景進行判斷,更多的時候需要應用做出積極的響應即可,比如用戶的“個人中心頁面”,當 User 微服務掛了,可以給個默認頭像、默認昵稱,然后正確展示其他信息,而不是反復請求 User 微服務。

      時間和順序

      在分布式系統中,時間可以作為所有執行操作的順序先后的判定標準,也可以作為一些算法的邊界條件。在分布式系統中決定操作的順序是很重要的,比如對于提供分布式存儲服務的系統來說,Repeated Read 以及 Serializable 的隔離級別,需要確定事務的順序,以及一些事件的因果關系等。

      物理時鐘

      每個機器都有兩個不同的時鐘,一個是 time-of-day,即常用的關于當前的日期、時間的信息,例如,此時是 2018 年 6 月 23 日 23:08:00,在 Java 中可以用 System.currentTimeMillis() 獲取;另一個是 Monotonic 時鐘,代表著單調遞增的時間,一般是測量時間間距,在 Java 中調用 System.nanoTime() 可以獲得 Monotonic 時間,常常用于測量一個本地請求的返回時間,比如 Apache commons 中的 StopWatch 的實現。

      在分布式環境中,一般不會使用 Monotonic,測量兩臺不同的機器的 Monotonic 的時間差是無意義的。

      不同機器的 time-of-day 一般也不同,就算使用 NTP 同步所有機器時間,也會存在毫秒級的差,NTP 本身也允許存在前后 0.05% 的誤差。如果需要同步所有機器的時間,還需要對所有機器時間值進行監控,如果一個機器的時間和其他的有很大差異,需要移除不一致的節點。因為能改變機器時間的因素比較多,比如無法判斷是否有人登上某臺機器改變了其本地時間。

      雖然全局時鐘很難實現,并且有一定的限制,但基于全局時鐘的假設還是有一些實踐上的應用。比如 Facebook Cassandra 使用 NTP 同步時間來實現 LWW(Last Write Win)。Cassandra 假設有一個全局時鐘,并基于這個時鐘的值,用最新的寫入覆蓋舊值。當然時鐘上的最新不代表順序的最新,LWW 區分不了實際順序;另外還有如 Google Spanner 使用 GPS 和原子時鐘進行時間同步,但節點之間還是會存在時間誤差。

      邏輯時鐘

      在分布式系統中,因為全局時鐘很難實現,并且像 NTP 同步過程,也會受到網絡傳輸時間的影響,一般不會使用剛才所述的全局同步時間,當然也肯定不能使用各個機器的本地時間。對于需要確認操作執行順序的時候,不能簡單依賴一個基于 time-of-day 的 timestamps,所以需要一個邏輯時鐘,來標記一些事件順序、操作順序的序列號。常見的方式是給所有操作加上遞增的計數器。

      這種所有操作都添加一個全局唯一的序列號的方式,提供了一種全局順序的保證,全局順序也包含了因果順序一致的概念。關于分布式一致性的概念和實現會在后續文章詳細介紹,我們先將關注點回歸到時間和順序上。下面看兩種典型的邏輯時鐘實現。

      (1)Lamport Timestamps

      Lamport timestamps 是 Leslie Lamport 在 1978 年提出的一種邏輯時鐘的實現方法。Lamport Timestamps 的算法實現,可以理解為基于每個節點的一對值(NodeId,Counter)的全局順序的同步。在集群中的每個節點(Node)都有一個唯一標識,并且每個 Node 都持有一個本地的對于所有操作順序的一個 Counter(計數器)。

      Lamport 實現的核心思想就是把事件分成三類(節點內處理的事件、發送事件、接收事件):

      1.如果一個節點處理一個事件,節點 counter +1。

      2.如果是發送一個消息事件,則在消息中帶上 counter 值。

      3.如果是接收一個消息事件,則更新 counter = max(本地 counter,接收的消息中帶的 counter) +1。

      簡單畫了個示例如下圖:

      初始的 counter 都是 0,在 Node1 接收到請求,處理事件時 counter+1(C:1表示),并且再發送消息帶上 C:1。

      在 Node1 接受 ClientA 請求時,本地的 Counter=1 > ClientA 請求的值,所以處理事件時 max(1,0)+1=2(C:2),然后再發送消息,帶上 Counter 值,ClientA 更新請求的最大 Counter 值 =2,并在下一次對 Node2 的事件發送時會帶上這個值。

      這種序列號的全局順序的遞增,需要每次 Client 請求持續跟蹤 Node 返回的 Counter,并且再下一次請求時帶上這個 Counter。lamport 維護了全局順序,但是卻不能更好的處理并發。在并發的情況下,因為網絡延遲,可能導致先發生的事件被認為是后發生的事件。如圖中紅色的兩個事件屬于并發事件,雖然 ClientB 的事件先發出,但是因為延遲,所以在 Node 1 中會先處理 ClientA,也即在 Lamport 的算法中,認為 Node1(C:4) happens before Node1(C:5)。

      Lamport Timestamps 還有另一種并發沖突事件:不同的 NodeId,但 Counter 值相同,這種沖突會通過 Node 的編號的比較進行并發處理。比如 Node2(C:10)、Node1(C:10) 是兩個并發事件,則認為 Node2 的時間順序值 > Node1 的序列值,也就認為 Node1(C:10) happens before Node2(C:10)。

      所以可見,Lamport 時間戳是一種邏輯的時間戳,其可以表示全局的執行順序,但是無法識別并發,以及因果順序,并發情況無法很好地處理 偏序。

      (2)Vector Clock

      Vector Clock 又叫向量時鐘,跟 Lamport Timestamps 比較類似,也是使用 SequenceNo 實現邏輯時鐘,但是最主要的區別是向量時鐘有因果關系,可以區分兩個并發操作,是否一個操作依賴于另外一個。

      Lamport Timestamps 通過不斷把本地的 counter 更新成公共的 MaxCounter 來維持事件的全局順序。Vector Clock 則各個節點維持自己本地的一個遞增的 Counter,并且會多記錄其他節點事件的 Counter。通過維護了一組 [NodeId,Counter] 值來記錄事件的因果順序,能更好得識別并發事件,也即,Vector Clock 的 [NodeId,Counter] 不僅記錄了本地的,還記錄了其他 Node 的 Counter 信息。

      Vector Clock 的 [NodeId,Counter] 更新規則:

      1.如果一個節點處理一個事件,節點本地的邏輯時鐘的 counter +1。

      2.當節點發送一個消息,需要包含所有本地邏輯時鐘的一組 [NodeId,Counter] 記錄值。

      3.接受一個事件消息時, 更新本地邏輯時鐘的這組 [NodeId,Counter] 值:

      4.讓這組 [NodeId,Counter] 值中每個值都是 max(本地 counter,接收的消息中的counter)。

      本地邏輯時鐘 counter+1。

      如下圖簡單示意了 Vector Clock 的時間順序記錄:

      三個 Node,初始 counter 都是 0。NodeB 在處理 NodeC 的請求時,記錄了 NodeC 的 Counter=1,并且處理事件時,本地邏輯時鐘的 counter=0+1,所以 NodeB 處理事件時更新了本地邏輯時鐘為 [B:1,C:1]。在事件處理時,通過不斷更新本地的這組 Counter,就可以根據一組 [NodeId,Counter] 值來確定請求的因果順序了,比如對于 NodeB,第二個處理事件 [A:1,B:2,C:1] 早于第三個事件:[A:1,B:3,C:1]。

      在數值沖突的時候,如圖中粉色剪頭標記的。NodeC 的 [A:2,B:2,C:3] 和 NodeB[A:3,B:4,C:1]。C:3 > C:1、B:2 < B:4,種情況認為是沒有因果關系,屬于同時發生。

      Vector Clock 可以通過各個節點的時間序列值的一組值,識別兩個事件的先后順序。Vector 提供了發現數據沖突的方式,但是具體怎樣解決沖突需要由發現沖突的節點決定,比如可以將并發沖突拋給 Client 決定,或者用 Quorum-NRW 算法進行讀取修復(Read Repair)。

      Amazon Dynamo 就是通過 Vector Clock 來做并發檢測的一個很好的分布式存儲系統的例子。對于復制節點的數據沖突使用了 Quorum NRW 決議,以及讀修復(Read Repair)處理最新更新數據的丟失,詳細實現可以參考這篇論文 Dynamo: Amazon’s Highly Available Key-value Store ,Dynamo 是典型的高可用、可擴展的,提供弱一致性(最終一致性)保證的分布式 K-V 數據存儲服務。后續文章再介紹 Quorums 算法時,也會再次提到。Vector Clock 在實際應用中,還會有一些問題需要處理,比如如果一個上千節點的集群,那么隨著時間的推移,每個 Node 將需要記錄大量 [NodeId,Counter] 數據。Dynamo 的解決方案是通過添加一個 timestamp 記錄每個 Node 更新 [NodeId,Counter] 值的時間,以及一個設定好的閥值,比如說閥值是 10,那么本地只保存最新的 10 個 [NodeId,Counter] 組合數據。

      小結

      本文引出了一些分布式系統的常見問題以及一些基礎的分布式系統模型概念,微服務的架構目前已經被更廣泛得應用,但微服務面臨的問題其實也都是經典的分布式場景的問題。本文在分布式系統的問題中,主要介紹了關于錯誤檢測以及時間和順序的處理模型。

      關于時間和順序的問題處理中,沒有一個絕對最優的方案,Cassandra 使用了全局時鐘以及 LWW 處理順序判定;Dynamo 使用了 Vector clock 發現沖突,加上 Quorum 算法處理事件并發。這兩個存儲系統都有很多優秀的分布式系統設計和思想,在后續文章中會更詳細的介紹數據復制、一致性、共識算法等。

      分布式 微服務 微服務引擎 CSE

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:word中怎么調整表格大小(如何調整word中表格大小)
      下一篇:Excel凍結拆分窗格,數據行列輕松查看
      相關文章
      日韩亚洲国产综合高清| 亚洲成a人片在线看| 亚洲乱亚洲乱妇无码| 亚洲精品韩国美女在线| 亚洲AV本道一区二区三区四区 | 在线亚洲精品福利网址导航| 国产精品亚洲二区在线| 偷自拍亚洲视频在线观看99| 亚洲欧美国产精品专区久久| 亚洲人成色777777老人头| 亚洲精品欧美综合四区| 亚洲国产成人久久一区二区三区 | 在线a亚洲v天堂网2019无码| 亚洲中文字幕无码永久在线| 亚洲精品少妇30p| 亚洲成AV人片在线观看无| 香蕉蕉亚亚洲aav综合| 亚洲人成网站在线播放影院在线 | 亚洲成av人片在www鸭子| 亚洲AV噜噜一区二区三区| 国产亚洲欧美在线观看| 亚洲第一黄色网址| 狠狠亚洲婷婷综合色香五月排名| 亚洲午夜福利AV一区二区无码| 国产亚洲3p无码一区二区| 亚洲国产精品久久久久婷婷软件| 亚洲最大成人网色| 亚洲中文字幕在线无码一区二区 | 77777午夜亚洲| 亚洲色精品三区二区一区| 亚洲国产精品无码久久九九大片| 亚洲AV女人18毛片水真多| 亚洲乱码中文字幕综合234| 亚洲中文字幕无码一区二区三区 | 亚洲Av无码专区国产乱码DVD| 亚洲人成亚洲精品| 亚洲中文字幕久在线| 亚洲乱码无人区卡1卡2卡3| 亚洲AV日韩精品一区二区三区| 国产成人精品久久亚洲| 亚洲精品中文字幕乱码三区 |