分佈式系統的知識體系,如何構建

轉載鏈接 分佈式系統的知識體系,如何構建?

對於開發工程師們來說,相信對於這種招聘要求的描述並不陌生:

「熟悉分佈式系統的設計和應用;熟悉分佈式、緩存、消息、搜索等機制;能對分佈式常用技術進行合理應用,解決問題」。

現在基本上大多數大、中型企業都會要求工程師們,除了要能在分佈式環境中進行開發,還要了解其中的原理、機制,對於架構師來說還需要能夠獨立設計分佈式系統。 

分佈式(計算機)系統的概念起源很早,目前已經基本涵蓋了大多數系統架構設計。

無論是 SOA 架構,或者微服務、Serverless 架構,都是基於分佈式環境的。掌握分佈式系統的知識體系是理解很多架構的基礎。比如日益盛行的微服務架構,也是基於分佈式計算環境。

設計分佈式系統中需要解決的問題,對於微服務架構也是一樣。如果基於容器技術,比如:Docker 容器來部署微服務實例,那麼還需要了解跨容器平臺的服務治理。 

本文主要談談,分佈式架構體系的幾個核心內容。開發工程師們可以根據這些內容,逐漸積累和構建自己的知識體系,並往技術架構方向邁進。

一、分佈式知識的核心模塊

分佈式系統最開始是起源於分佈式計算機的概念,隨着信息技術的發展,需要處理的數據以及計算已經超過了單臺計算機能夠擴展的系統資源。

將數據、程序分散到多臺計算機,通過一定的通信機制進行數據傳輸、共享,便產生了分佈式的計算機系統。分佈式計算髮展至今,衍生了SOA、微服務等架構模型。 

在資源的利用方面,最早期的分佈式計算是無共享系統資源的,機器與機器之間通過網絡通信進行分佈式數據共享。

後期隨着虛擬機技術的發展,一臺機器可以運行多臺虛擬機,它們可以共享機器的硬件資源,節約維護成本。

而今,更加流行的容器技術可以只基於一個操作系統內核,而不需要整個操作系統的資源,一臺機器可以部署更多的容器實例(比如 Docker,一臺機器可以部署上千個 Docker 容器實例),並且實例之間像獨立的操作系統一樣獨立運行、計算。 

可以看出,隨着數據和計算規模的增長,分佈式系統是朝着越來越輕量級的資源利用,以及越來越細的粒度和鬆耦合的服務化方向發展的。 

分佈式系統發展至今,從技術架構的角度來說,核心模塊主要是: 存儲、服務通信和服務治理以及分佈式事務。

這三個模塊的每一部分都涉及到很多知識點以及實踐中需要解決的分佈式問題。

設計一個分佈式系統,在技術架構上只要能處理好這三個模塊,其餘部分便是具體的 架構模型選擇(如: SOA、微服務、Serverless等)、架構思想選擇(如: 分層的思想、事件驅動的思想、DDD思想等)以及應用層面的中間件和框架的選擇(如:會有哪幾種開發語言,基於哪種服務間通信協議、用什麼框架集成)。

如下圖簡單列舉:

二、核心知識模塊

2.1 分佈式存儲

在分佈式系統中,尤其是數據密集型應用會涉及到很多分佈式存儲技術。分佈式的存儲主要有兩個方向的知識模塊,一個是數據複製,也即一個數據在多個節點(Data Node)有相同的數據副本。

另一個是數據分區,將大數據模型拆成多份到多個節點(Data Node)。這兩個方案都可以提高系統的吞吐量,並且也是一種容災備份的考量。

不同的存儲引擎、技術中對於複製、分區實現各有不同,但是核心的算法和分佈式計算模型是相通的。

一般來說開發工程師很少去自己研發一套類似 Redis、MongoDB、DynamoDB 這樣的存儲系統,但瞭解這些技術的共通的原理和機制,可以幫助我們更好地使用,以及分析各種分佈式問題。 

2.1.1 複製

數據複製有兩種複製模型:同步,以及異步。同步複製一般是阻塞的,可以保證所有的數據節點都保持有一致的數據副本,但是吞吐量低;

異步複製是非阻塞的,在數據保存到主庫後請求便立即返回,主庫和其他從庫之間的數據採用異步的方式進行同步,一致性模型上保證了最終一致性。

從數據節點的角色分配來說,最簡單的數據複製方案即是“主-從”複製。通過數據複製,可以使存儲服務擁有備份,當主庫掛掉時可以將數據讀寫請求切換到從庫。

如果遇到網絡故障,主,從節點都無法提供服務時,基於“主-主”複製的多數據中心便可以解決。

但是,越複雜的數據節點結構需要處理的問題也越多,比如不同數據節點的讀寫一致性問題,多個主節點都接受寫請求時,寫數據衝突的解決等。

不同的存儲技術的數據複製的實現,以及支持的複製策略會有所區別,學習數據複製相關的知識可以通過不同存儲引擎的官網以及找一些經典的論文資料。

這裏舉個簡單的例子,比如 Mysql 的集羣方案,可以看看 Mysql 數據複製實現細節、Mysql 集羣數據複製方案。 

2.1.2 分區

數據複製相當於同一個數據源的相同副本存儲在不同的數據節點中,數據分區是將一份數據源以一定的規則拆分成多份,也是分佈在不同的數據節點中。

簡單來說,複製等於將數據文件 copy 到不同機器上,分區是將大的數據文件以一定的規則拆成一個個小的文件,分散到不同機器上。數據分區往往可以和數據複製結合使用。

很多數據存儲引擎都自帶分區功能(如 PostgreSQL,Mysql,Oracle),分區功能對開發者是透明的。

除了分區,另外一個常用的將大數據拆成小數據集的方式就是分表,一般是基於索引設置一個路由規則,比如取模,將一個數據表進行拆分。

分表和分區的實現上以及場景上有所區別,也可以同時使用。這兩者都可以提高數據訪問的速度,並且擴展性高。 

總結來說:在分佈式環境下,隨着數據量增大,性能的壓力以及擴展性的需求,在存儲服務層可以做的技術方案主要是數據複製、分區。

複製和分區一般都是很多存儲服務內置的功能。從應用層或者中間件層來說,還可以採用分表(有的存儲服務也自帶分表,或者通過插件的方式支持分表),分表屬於水平拆分,在業務上還可以做垂直拆分,比如將一個大表拆成有外鍵關聯的子表,將佔用數據空間大的字段拆到其它表等方式。

分區中重要的知識點主要是分區策略的實現,不同的存儲引擎支持的策略不同,但是基本的分區方案策略實現是大同小異的,學習分區時可以先以一個數據庫爲切入點,比如 Mysql 5.7 分區概要

想要從宏觀角度來了解分佈式解決方案時,可以看看 Distributed systems for fun and profit 系列文章。

如果想要體系化學習分佈式數據存儲系統的方案,推薦看《Designing Data-Intensive Applications》,這本書從淺到深介紹了分佈式數據集羣的方案,並對一些問題的解決機制和原理都有深入介紹。 

2.2 服務通信和服務治理

分佈式系統中,服務實例部署在不同的節點,服務間的通信可能跨操作系統或者容器。隨着容器技術的發展,服務治理已經成爲了容器服務的重點技術領域之一。

服務通信和服務治理關注的問題點以及應用的技術各有不同,但目前有很多分佈式技術集成了這兩者(如 Kubernates,Consul 1.2版本開始支持 Service Mesh)。 

2.2.1 服務通信的基礎是。服務發現、服務註冊、健康檢查。無論是 SOA 架構或者微服務架構,都需要通過服務名(service name)定位到服務實例的“IP:Port”。

SOA 一般由企業總線來集成這些功能(比如 Dubbo 基於 Zookeeper)。在基於容器的微服務架構下,可以使用類似 Consul、Eureka、Etcd 等更加輕量級的服務發現技術。

學習的時候,可以先了解這些技術的共通點,以及經典理論,比如 CAP 理論,FLP 不可能結果理論。然後再學習這些技術背後的原理和機制。

比如服務發現和服務註冊機制,不同的技術使用的一致性算法不同,Zookeeper 基於 Zab 算法,Zab 又基於 Paxos 算法做了很多改進;Etcd 基於 Raft 算法。

而 Consul 和 Eureka 捨棄了嚴格的一致性,選擇了 CAP 中的“A”和“P”,對於可用性來說,Consul 和 Eureka 基於的技術也是不同的,Consul 基於 Gossip 協議,而 Eureka 則基於 Ribbon。這些技術的知識的學習可以從官網以及 Github 中找到項目源碼。 

2.2.2 分佈式消息隊列。對於SOA架構、微服務架構來說,消息隊列可以用來進行服務間的解耦,並且提升請求響應的性能。

在學習消息隊列時,需要先對網絡通信的知識打好基礎(網絡協議、編解碼機制,底層框架和原理等),分佈式消息隊列的存儲也是關鍵。

最好先從工作中接觸到的 MQ 進行學習,或者選擇社區活躍的開源 MQ:如Kafka、RocketMQ、RabbitMQ 等。 

2.2.3 服務治理。服務治理在 SOA 架構中類似於企業總線涵蓋的功能。容器技術裏比較出名的服務治理技術是 Kubernates。

對於小規模集羣來說,不是在一開始就需要服務治理,隨着容器規模、服務體系的增長以及團隊的擴充,纔開始考慮是否需要構建服務治理平臺。

服務治理包含了熔斷機制、流控機制、服務監控、負載均衡、容器的透明化管理、服務實例的動態擴容縮容等等。

如果不用一個服務治理技術,一開始也可以手動“治理”加上一些有熔斷、負載均衡的框架(如 ribbon,hytrix)來集成到應用。

服務治理包含的模塊很多,不同技術的實現標準也不同,學習過程應該實踐大於理論,如果對 Docker 比較感興趣,可以結合 Kubernates 官網和 Github 源碼進行學習,國內的社區可以多看看 k8s中文社區。

深入淺出 Docker 技術棧實踐

Docker + K8S 集羣環境搭建及分佈式應用部署 

2.3 分佈式事務 

對於設計大型分佈式系統,分佈式事務基本上是必須要面對的一座大山。理解分佈式事務,除了從應用系統的角度出發,還可以從更源頭概念來理解。

比如,數據庫存儲系統的事務特點,不同隔離級別的實現。分佈式應用系統很難像存儲系統一樣滿足完整的事務特性,比如 2PC 的解決方案,可以滿足原子性,但會犧牲性能。

所以對原子性、一致性要求不嚴格的場景,更多是基於 BASE 理論。BASE 理論適用在很多 NoSQL 系統中。

NoSQL 更多的關注點不是保證事務 ACID 的特性,而是性能、吞吐量、擴展性以及可用性。

BASE 也同樣適用於業務類型的分佈式系統。對於分佈式事務,簡單列舉下學習 Route: 

2.3.1 瞭解關係型數據庫的事務的特性,尤其是不同的隔離級別。可以從自己最常用的數據庫着手,瞭解該數據庫的隔離級別在哪種併發場景會出現哪些讀、寫數據的問題。

這方面的知識需要去一些官網,找對應版本的資料。比如 PostgreSQL 可以去看下 PostgreSQL 事務隔離級別介紹。 

2.3.2 針對工作中平常使用的 NoSQL 技術,或者自己想學的 NoSQL,瞭解它們是怎樣利用集羣的特性實現高可用和高可擴展性。

對於一些通用的實現,可以看看經典論文。比如 Dynamo 的這篇論文

Dynamo: Amazon’s Highly Available Key-value Store

Google 的 BigTable 論文:

Bigtable: A Distributed Storage System for Structured Data

在一些論文裏,可以瞭解到 NoSQL 系統是怎樣實現 BASE 理論,以及對於 CAP 中一致性模型取捨的考量。 

2.3.3 在實踐方面,基於 X/Open(XA)標準的實現較多,但 XA 屬於 2PC 模型,保證了原子性,但是會降低系統的吞吐量,適用於一致性、原子性敏感的業務。

基於 BASE 理論的 TCC 模型,以及基於可靠的分佈式消息隊列的模型現在越來越成爲主流的分佈式事務解決方案。

這些知識點是比較零散的,不同的公司使用的方案各不相同。學習的時候可以先對這些方案的實現以及可能存在的問題進行整體的瞭解(網上的資料很多,最好找到可靠的學習資料,比如 GitChat 上有一些課程和 chat )。

分佈式事務入門指南

然後在遇到具體場景時需要對業務進行充分的分析,然後決定使用哪種方案。 

三、如何構建知識體系?

分佈式系統的知識點很多,除了分佈式的重要理論(CAP、BASE、FLP不可能理論)、共識算法(Paxos、Raft、ZAB),還要了解一些開源的高性能、高可擴展的分佈式 NoSQL 技術(如 Dynamo,MongoDB,Redis)以及關係型數據庫集羣的數據複製、數據分區的方案和實現機制(Mysql、Oracle、PostgreSQL)。

實踐中還會需要知道分佈式事務的解決方案(2PC、3PC、TCC)。面對龐大的知識體系,可以將知識模塊進行拆分,然後逐個攻破。

在學習的時候,可以針對各個知識點嘗試下面的方法: 

利用碎片時間瞭解知識點:多在一些活躍的社區上訂閱分佈式系統的文章,微服務架構方面可以多閱讀 microservices

GitChatCSDNDockerOne 中關於分佈式知識的文章可以每天讀上一兩篇,更加零散的時間可以閱讀一些技術公衆號的文章。 

針對知識面進行體系化學習:進行體系化的學習可以先設定一些目標,比如一個月之內針對某一個知識模塊,閱讀完某本書或課程、論文,並對重點知識進行自己的梳理。

關於分佈式知識推薦一些資料:

 

 

《Designing Data-Intensive Applications》

這本書對數據密集型系統以及分佈式的存儲體系,從問題的引出到各種解決方案的介紹都非常詳盡,雖然是英文版但是易讀性強。

Distributed Systems for fun and profit ,其中包含了5篇文章,分別講述了分佈式的一些問題和概念,作爲初步瞭解是很好的資料。

《分佈式計算——原理、算法與系統》這本書對很多分佈式的概念,問題從數學和理論角度介紹得全面細緻,需要一定的數學基礎。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章