標籤:

聊聊分散式系統架構

聊聊分散式系統架構

來自專欄數據人生6 人贊了文章

一、分散式系統的經典基礎理論

1、分散式系統設計的兩大思路:中心化和去中心化

  • 中心化:中心化的設計思想在自然界和人類生活中是如此的普遍和自然,它的設計思想也很簡單,分散式集群中的節點按照角色分工,可以分為兩種角色--「領導」和「幹活的」,中心化的一個思路就是「領導」通常分發任務並監督「幹活的」,誰空閑了就給它安排任務,誰病倒了就一腳踢出去,然後把它的任務分給其他人;中心化的另一個思路是領導只負責生成任務而不再指派任務,由每個「幹活的」自發去領任務。
  • 去中心化:全球IP互聯網就是一個典型的去中心化的分散式控制架構,聯網的任意設備宕機都只會影響很小範圍的功能。去中心化設計通常沒有「領導」和「幹活的」,角色一樣,地位平等,因此不存在單點故障。實際上,完全意義的去中心化分散式系統並不多見,很多看起來是去中心化但工作機制採用了中心化設計思想的分散式系統正在不斷湧現,在這種架構下,集群中的領導是動態選擇出來的,而不是人為預先指定的,而且在集群發生故障的情況下,集群的成員會自發舉行會議選舉新的領導。典型案例如:zookeeper、以及Go語言實現的Etcd。

2、分散式系統的一致性原理

  • 在說明一致性原理之前,可以先了解一下cap理論和base理論,具體見《事務與柔性事務》中的說明。
  • 對於多副本的一致性處理,通常有幾種方法:同步更新--即寫操作需要等待兩個節點都更新成功才返回,這樣的話如果一旦發生網路分區故障,寫操作便不可用,犧牲了A。非同步更新--即寫操作直接返回,不需要等待節點更新成功,節點非同步地去更新數據,這種方式,犧牲了C來保證A。折衷--只要保證集群中超過半數的節點正常並達到一致性即可滿足要求,此時讀操作只要比較副本集數據的修改時間或者版本號即可選出最新的,所以系統是強一致性的。如果允許「數據一致性存在延遲時間」,則是最終一致性。
  • 如Cassandra中的折衷型方案QUORUM,只要超過半數的節點更新成功便返回,讀取時返回多數副本的一致的值。然後,對於不一致的副本,可以通過read repair的方式解決。read repair:讀取某條數據時,查詢所有副本中的這條數據,比較數據與大多數副本的最新數據是否一致,若否,則進行一致性修復。此種情況是強一致性的。
  • 又如Redis的master-slave模式,更新成功一個節點即返回,其他節點非同步地去備份數據。這種方式只保證了最終一致性。最終一致性:相比於數據時刻保持一致的強一致性,最終一致性允許某段時間內數據不一致。但是隨著時間的增長,數據最終會到達一致的狀態。此種情況只能保證最終一致性。著名的DNS也是最終一致性的成功例子。
  • 強一致性演算法:1989年就誕生了著名的Paxos經典演算法(zookeeper就採用了Paxos演算法的近親兄弟Zab演算法),但由於Paxos演算法難以理解、實現和排錯,所以不斷有人嘗試優化演算法,2013年終於有了重大突破:Raft演算法的出現,其中Go語言實現的Raft演算法就是Etcd,功能類似於zookeeper。
  • Base的思想:基本可用、柔性狀態、最終一致性,主要針對資料庫領域的數據拆分,通過數據分片(如Mycat、Amodeba等)來提升系統的可用性。由於分片拆分後會涉及分散式事務,所以接下來看一下如何用最終一致性的思路來實現分散式事務,也就是柔性事務。

3、柔性事務:具體見《事務與柔性事務》。

4、分散式系統的關鍵Zookeeper

  • 目標是解決分散式系統的幾個問題:集群集中化配置,集群節點動態發現機制,簡單可靠的節點Leader選舉機制,分散式鎖。
  • ZNode有一個ACL訪問許可權控制列表,提供對節點增刪改查的API,提供監聽ZNode變化的實時通知介面--Watch介面。
  • ZNode類型:持久節點(可以實現配置中心)、臨時節點(和創建這個節點的客戶端會話綁定,可實現集群節點動態發現,可以實現服務註冊中心)、時序節點(創建節點時會加上數字後綴,通過選擇編號最小的ZNode可以實現Leader選舉機制)、臨時性時序節點(同時具備臨時節點和時序節點的特性,主要用於分散式鎖的實現)。

二、分散式系統架構的主要內容

分散式系統架構的主要內容包括:

  • RPC和對象序列化
  • 分散式內存緩存技術、分散式內存計算
  • 分散式存儲
  • 分散式計算
  • 全文檢索
  • 消息隊列
  • 容器

1、RPC和對象序列化

  • RPC設計的初衷是設計一套遠程通信的通用框架,這個框架能夠自動處理通信協議、對象序列化、網路傳輸等複雜細節,讓開發者調用遠程方法跟調用本地方法「看起來沒什麼區別」。
  • Java里經典的RPC實現方案是RMI,僅支持Java語言的客戶端調用。
  • 人類歷史上,支持多語言通信的第一次偉大嘗試造就了功敗垂成的CORBA技術,1991年CORBA1.1誕生,直到1994年底才完成了CORBA2.0規範。
  • CORBA失敗的原因可能包括:規範巨大而複雜,很難學習,開發過於複雜使得CORBA程序員稀缺,商業CORBA費用昂貴,很多公司開始轉向Web瀏覽器、Java和EJB的電子商務基礎設施等。同時,XML技術的興起加速了CORBA的沒落,SOAP使用XML作為RPC新的對象序列化機制,IBM則發揚光大推出WebService整套方案。
  • SOAP嚴格意義上屬於XML-RPC技術的一個變種,SOAP是第一次真正成功解決了多語言多平台支持的開放性RPC標準。
  • 但是SOAP報文複雜而且編碼臃腫,由於它是面向機器識別的表達格式,最終導致了基於XML的SOAP協議和其上的WebService框架的末路,導致了基於JSON簡單文本格式編碼的HTTP REST通信方式的興起。
  • HTTP REST慢慢侵佔了RPC大部分領地,並導致了一度盛行的XML-RPC的滅絕;同時促進了正統RPC技術走向一個新的發展階段,追求更高的性能及增加多語言多平台的支持,成為越來越多開源RPC框架的目標,比如Thrift、Apache Avro等開源框架。
  • 當年CORBA牆倒眾人推時,最初參與CORBA的一幫技術專家另起爐灶打造了延續至今的RPC之王--ZeroC Ice,作為RPC領域的王者,ICE已經發展成一個很強大的微服務架構平台,在RPC通信領域裡,性能第一,穩定性第一,多語言多平台支持。
  • 與一般的HTTP REST框架不同,一個可用的RPC框架不僅解決了遠程調用問題,也提供了用於服務註冊和服務發現的基礎設施,比如RMI里的RMI Registry。服務註冊、服務發現和服務監控後來成為通用分散式系統架構的核心和關鍵技術基礎,也被賦予一個新概念--「服務治理框架」,最早的說法可能來自BAT的一些架構師。比如Dubbo就具備服務治理的能力,同時dubbo還提出了服務編排、服務降級、訪問規則控制等,但實際上作為分散式系統最核心的仍然是:穩定、高性能的RPC通信及多語言支持。
  • 如果一個分散式系統具備如下特點,則可以稱之為「微服務架構」:1、任何一個服務都由多個獨立的進程提供服務,這些進程可以分布在多台物理機上,任何進程宕機都不會影響系統提供服務;2、整個系統是由多個微服務有機組成的一個分散式系統,換而言之,不是一個巨大的單體應用。
  • 當前主流的微服務架構可以分為三類:1、基於傳統高性能RPC技術和服務治理的微服務框架,這個領域的王者是ZeroC IceGrid;2、以HTTP REST為通信機制的通用性微服務架構,最典型的為Spring Cloud;3、基於容器技術,沒有提過特定的RPC通信機制,理論上任何分散式應用都可以運行在微服務架構平台上,言外之意就是要選擇合適的通信協議,比如REST、Thrift、gRPC等,這個領域的王者是Google的Kubernetest。
  • 微服務架構下,是否還需要Spring Framework?是否還需要MyBatis、Hibernate等數據映射框架?這個問題的答案不是特別確定,但有不少人傾向於不再使用這些框架來開發微服務,理由如下:1、微服務系統通常很多時候是互聯網應用,CRUD操作少,查詢操作多,因此Mybatis和Hibernate框架的優勢不明顯;2、微服務是系統中的重要骨幹,開發速度相對於微服務的實現品質來說並不重要;所以不少人傾向於直接採用原生JDBC來實現微服務的業務代碼。
  • 在對象序列化這塊,JSON雖然是簡單文本格式編碼,但存在佔用空間大、性能低下等特點,於是與語言無關的高效二進位編碼協議成為熱點技術之一。首先誕生了開源二進位序列化框架--MessagePack,是模仿JSON設計的一個高性能二進位的通用序列化框架。除了MessagePack,Google開源的多語言支持的Protocol Buffers編碼協議也是這方面的代表作品。在Protocol Buffers之後,Google又開源了FlatBuffers,在性能、序列化過程中內存的佔用大小、第三方依賴庫的數量、編譯後生成的中間代碼數量等方面都做了大幅改進。Apache也發布了多語言的頂級RPC項目Apache Avro。

2、分散式內存緩存技術、分散式內存計算

  • 緩存系統常用的緩存淘汰策略:1、Least Frequently Used(LFU)策略--計算使用頻率,優先淘汰最不常用的緩存條目,CPU的cache所採用的淘汰策略即為LFU策略;2、Least Recently Used(LRU)策略--淘汰最近最少使用的條目;3、Adaptive Replacement Cache(ARC)策略--該策略由兩個LRU組成,第1個LRU包含的條目是最近只被使用過一次的條目,第2個LRU包含的是最近被使用過二次的條目;4、其他還有一些基於緩存時間的淘汰策略,比如淘汰存活時間超過5分鐘的緩存條目。
  • 分散式緩存都採用Hash演算法進行數據分片,將數量龐大的緩存項均勻分布到集群中的每個節點上,比如Redis3.0開始實現的分散式集群功能就採用了Hash演算法,將緩存項均勻分布到16384個Slot上去。以Redis2.x為基礎改造的Codis是國內分散式緩存開源的一個典範,出自豆瓣網。Memcache本身並沒有提供集群功能,但很多客戶端Driver實現了Hash演算法分配邏輯,因此也可以看成是一種分散式緩存的解決方案。
  • 內存計算產品:商業的SAP Hana、開源的VoltDB等。VoltDB是一種開源的高性能的內存關係型資料庫,提供社區版和商業版,是一種NewSql,是一個借鑒並基於HSQL的分配內存資料庫集群。

3、全文檢索

  • Lucence Core:Java編寫的核心類庫,提供全文檢索功能的底層API與SDK。
  • Solr:基於Lucence Core開發的高性能搜索服務,提供了REST API的高層封裝介面,還提供了一個Web管理界面。
  • PyLucene:一個Python版的Lucene Core的高仿實現。
  • ElasticSearch:也是基於Lucence的分散式全文檢索中間件。

4、消息隊列

  • 第一代消息隊列:J2EE時代的產物,強調企業級特性,比如消息持久存儲與事務的要求,都遵循JMS規範,最著名的是開源Apache ActiveMQ。雖然當前基於J2EE架構的企業軟體少了,但依然有不少商業軟體仍然採用了企業級的J2EE架構。值得一提的是,ActiveMQ Artemis是ActiveMQ的下一代產品,它已經融合了多種MQ的特性,成為Java領域無法超越的MQ之王。
  • 第二代消息隊列:制定了一個開放性、免費的消息中間件協議AMQP標準,第一個也是最重要的開源AMQP消息中間件產品RabbitMQ,同時ActiveMQ目前也支持AMQP協議,Apache還專門開源了Qpid這個基於AMQP協議的消息中間件產品。
  • 第三代消息隊列:分散式系統設計理念,採用Zookeeper實現去中心化的集群管理,以Kafka為代表。

5、微服務架構

  • 當前主流的微服務架構可以分為三類:1、基於傳統高性能RPC技術和服務治理的微服務框架,這個領域的王者是ZeroC IceGrid;2、以HTTP REST為通信機制的通用性微服務架構,最典型的為Spring Cloud;3、基於容器技術,沒有提過特定的RPC通信機制,理論上任何分散式應用都可以運行在微服務架構平台上,言外之意就是要選擇合適的通信協議,比如REST、Thrift、gRPC等,這個領域的王者是Google的Kubernetest。
  • 微服務架構的項目在實施過程中經常需要考慮的問題:引入自動化工具與集中運維管理工具,用於程序的編譯打包、自動化部署和升級等工作;需要研究、測評大量相關開源工具並引入微服務架構中,原因是之前的很多中間件工具只適合於單體應用;團隊重構,包括展現層和微服務層,建議團隊中的骨幹技術人員成為微服務層的開發主力;高質量的文檔。
  • 基於消息隊列的微服務架構:網易的蜂巢平台採用了基於消息隊列的微服務架構,但基於消息隊列的微服務架構案例少,沒有知名的開源平台,因此實施成本高、風險大。

推薦閱讀:

Linux-CentOS6.6 主從智能DNS Server架構部署指南
當紅架構Cloud_Native_怎麼搭建才能成為上雲助攻手?
Dubbo在互金行業的應用
為 Node.js 應用建立一個更安全的沙箱環境

TAG:架構 |