標籤:

分散式系統工程如何搭建,有沒有一套完整的系統的實踐方法論,比如,存儲服務?

分散式系統的開發一直是一項非常有挑戰的事情,能做的人也相對比較少。每個人每個公司都有一套自己最佳實踐方法。

從工程的角度考慮,一般要考慮整個系統的全生命周期。

時間軸,包括了開發,單測,集成測試,部署,運維。等各方面就是包含了讓分散式系統提供服務的能力的各個方面吧

產品軸,系統變複雜了,系統擴容,系統容錯等等。

這樣,在考慮最佳的實踐方法論是何其重要,避免了很多的彎路和試錯。


又雙被邀~汗~-_-!

估計我若堅持不回答,我會被一直邀請到底~~ -_-b

好吧,話歸正傳。簡單的說:

  1. 如果壓力不是很大,規模不是很大,性能要求不高,那回答是:有!
  2. 如果壓力很大,或者規模很大,或者性能要求很高,或者以上3者均有很高要求,那回答是:沒有!

如果是第一種情況,可以直接看阿里系的那幫人寫的書。無論是網站,還是非網站,都OK。且請忽略以下所有內容。

如果是第二種情況……

~~~~~~~ 第二種情況分割線 ~~~~~~~~

不同的項目,不同的規模,從架構上來說就是完全不同的啊!!!!

架構不同,直接決定了部署、運維、擴容、容錯方式的完全不同啊!!!!

而且如果初期規模、要求類似,但後期業務增長曲線不同的話,架構也完全不同啊!!!!

沒有業務需求、業務說明、業務增長預期、技術儲備情況,那是無的放矢啊~~

說什麼都是空談。

但題主既然不停地問,那就空談一下吧…… -_-b

不過也就只能提提關鍵點,其他的沒有目標完全不知道該怎麼說~~

首先,題主問的是工程搭建,這個不同的架構也是完全不同的啊~~

這裡我就簡單理解成整個系統的設計、規劃、架構,和實施、部署、運維等。不限於搭建。

否則都不知道流程和架構,搭建無從談起。

題主也沒給出具體的項目類型和需求,那就直奔一個彈性很高,從DAU 1K~1億+ 的說吧。

注意:如果預期業務穩定期DAU不過2~3W,且壓力性能要求不是很高,請直奔之前第一種情況,後文請忽略~~

*. 首先,技術選型

根據團隊的技術儲備,和對項目的認識,選擇合適的核心開發語言和RPC框架/技術生態。

核心開發語言就是開發核心服務的語言,Java、Go、C#、C/C++ 都可以。

但如果實時性要求非常高,比如 FPS、RTS 等,還是請考慮 C/C++。像 Super Cell 的遊戲,一般情況下 50 ms 一個狀態包,如果有行動,可能5~10 ms就會有一個數據包。比如Brawl Stars,假設一個伺服器1000個房間,一個房間6個人。那1秒鐘伺服器就要處理12W個數據包,並下發12W個狀態包。所以要不用高配伺服器,要不就請考慮開發語言的選型。

(對於QPS,多說一句。RPC框架、資料庫、緩存、消息隊列哪些的官方QPS只是一個參考!!!不代表你的實際業務就能達到這個QPS!!!就像我們自己的框架在 4 core 的虛擬機上能到30W的QPS,但根據業務不同,實際開發下來,可能A服務只有12W的QPS,B服務只有3W的QPS,而C服務只有7K~~)

Ruby、Python、PHP、Node.js,可以用於開發性能要求不那麼高的輔助服務。但如果打算用於開發高實時高並發高性能的核心業務,還請再等上3~5年,看看技術的發展是否能跟上。

這裡最大的坑是:

雖然分散式做到最後,對於壓力和規模都是用機器堆,但同樣是上億註冊用戶,千萬DAU,堆幾百台機器和堆上萬台機器的成本還是得好好考慮一下~~

*. 架構

極力推薦 SOA + 微服務架構!!!

SOA 能有效簡化架構設計的難度,微服務能有效簡化開發的難度,並有效進行故障隔離。

但如果性能、壓力要求不高,用這個只會徒增複雜度。

*. 集群

對於複雜的業務,會有多級的集群。根據複雜度,整個業務的集群,最終可能不是棵樹,而是一片森林!!!

*. 負載均衡

負載均衡不只是業務的入口處!!!

也不是 F5、ELB、LVS什麼就能搞定的事情!!!

配合SOA + 微服務架構和森林集群,是RPC框架,或者技術生態自帶的負載均衡/數據路由模塊。

比如輪轉派發、隨機派發、廣播、任意數量成功、優先順序,等等。以及他們的組合。

一個實際的例子:

一個視頻直播業務:

用戶APP通過智能DNA解析,隨機獲取到最近的一台 UserGate。App 連接上 UserGate,然後發送登陸請求。UserGate 隨機從 Login 服務集群中抽取一台 Login 服務,將用戶的登錄請求轉交給該 Login 服務處理。Login 直連本機的 DBProxy 服務,DBProxy 根據 hash 選擇對應的資料庫服務。Login 驗證完畢後,返回給 UserGate。UserGate 根據一致性哈希選擇相應的緩存服務,從緩存服務中獲取用戶的頭像等信息,然後返回給客戶APP。

客戶APP 發送開設直播的請求,UserGate 收到請求後,根據一致性hash從直播服務集群中選擇對應的直播服務實例。對應的直播服務實例創建完房間後,通過廣播告訴列表伺服器集群所有的實例有新的直播開播,做好準備。同時從機器人控制集群中隨機選擇一個服務實例,告訴主播開播。對應的機器人控制服務實例,根據自身集群的狀態信息,自動將請求轉到集群的master服務上去。於是機器人控制集群的master服務開始向對應的直播間派發機器人。

然後其他用戶通過UserGate隨機選擇的列表服務,就能獲取最新開播的直播列表。然後以開播類似的路徑,進入直播房間。

這個實例中,每一步的路由都帶有負載均衡的性質。但至於每一步該是隨機、哈希、一致性哈希、廣播、系統壓力負載、還是強一致性,取決於上下游具體的服務所承載的所有功能和對應的角色。

相關的負載均衡和數據路由模塊,可能大多數RPC框架中沒有自帶,需要額外開發。如果對這方面不甚了解,可以參考百度的 brpc 框架。在開源的框架中,brpc 還算不錯。

*. 狀態

一定要將業務流程分段,以便區分哪些服務是狀態服務,哪些是無狀態服務!!!

無狀態服務比狀態服務簡單不止一倍!!!

狀態服務盡量集中!!!否則分散式事務又慢又難回退!!!

狀態伺服器一定要有自動恢復,和集群間狀態轉移的功能!!!

*. 事務

盡量避免分散式事務!!!

這玩意又慢又難回退!!!

通過盡量將事務集中在一個狀態伺服器上處理,避免分散式事務!!!

(如果前面兩條路,直路荊棘遍地,彎路需要倒幾次公交。反正公交又便宜又不用徒步,那我又何必披荊斬棘,搞得牛逼哄哄,好像所向披靡一樣呢?)

*. 內部重試

為了更好的容錯,移動要有內部重試機制。根據資源開銷,甚至是多級內部重試。

*. 消息隊列

一定用自己開發的,嵌入在各個服務中的分散式的輕量級消息隊列!!!

如果RPC的技術生態完善,開發嵌入在各個服務中的分散式輕量級消息隊列其實是件超級簡單的事情!!!

某大廠,32核128G內存的物理機,運行改版的 RabbitMQ,3~4W的QPS!!!

對我們來說,這簡直就是一個笑話!!!

我們的一個業務,日均1000億條的消息傳送量,最高配的機器是 8 核的虛擬機~~~! -_-!!

*. 去中心化

不用集中的消息隊列服務,或者消息隊列服務集群也是出於這個考慮。

即使用消息隊列集群,那也必須不同的case的消息隊列集群完全獨立。否則共享的消息隊列集群自身就是一個中心。

要是這個集群一掛,那不僅僅是部分業務,而是所有的業務,全面癱瘓!!!

*. 服務發現/集群管理系統

千萬不要用 Zookeeper!!!

千萬不要用 Zookeeper!!!

千萬不要用 Zookeeper!!!

千萬不要用 etcd!!!千萬不要用 etcd!!!千萬不要用 etcd!!!

除非你自建機房,網路穩定得如一潭死水一樣~~(請當我啥也沒說)

我們用的 AWS 的服務,網路波動,那不是月經,不是日經,那是分經啊~~~!!!分經~~!!!前幾十秒 ping 在200usec左右,後面就是400usec。分把鍾來個幾個msec。然後周把瞬間網路全卡幾秒鐘~~!!!美洲、歐洲、亞太輪流來~~ ~~"T_T"~~ 說多都是淚啊~~

[表] 為什麼不要用?

碰上這種分經的環境,隔三差五,月把兩月的就來個半個多小時投不出票,選不出主來~~!!!這還是在同一個機房內~!!!我們其他的服務可以做到2年不停機不重啟,我們可不想在這種事上浪費時間和精力~~!!

[里] 為什麼不要用?

因為 ZooKeeper 和 etcd 是一致性優先!!!CAP 中的 C!!!

做配置管理是非常OK的,但在微服務中,我們需要的是 A 優先~~~!!!可用性優先!!!

一致性導致的問題,調整業務流程邏輯後還是比較好搞定的。但是可用行的問題,萬一給你來個20分鐘半小時不可用,哭死啊~~~!!!

*. 緩存

我不提倡使用 redis、memcache 等。用這些,表示還處於初級水平。

比如 memcache,常見的流程是,業務伺服器問memcache有沒有?memcache回答沒有。然後業務伺服器去DB中獲取數據,處理後回寫memcache。

這個流程落不啰嗦?麻不麻煩?

最好的是針對業務的分散式緩存,其本身就可視為數據源,屏蔽掉任何DB的操作。具體的要求與前述「去中心化」和「消息隊列」的要求相同。

*. IDL 介面協議

為了伺服器能更好的灰度更新,最好使用可兼容的介面協議。在服務介面更替的時候,為了不停服,不需要兩代介面並存。而重要的一點就是,使用無 IDL 的RPC 框架!!!不過可惜的是,除去 RESTful 這類文本的不算,目前開源的RPC框架,好像全是 IDL 的。我所接觸到的無 IDL 的,都是私有閉源框架。

如果沒有可用的無IDL的框架,那落實到IDL上來,以 ProtoBuf 為例,盡量少用 required!!!

據傳,這可是 Google 工程師們的經驗總結!!!其實 ProtoBuf 還好,兩年前的 fbThrift (Thrift facebook 分支)的可選參數用起來可是的編寫額外的代碼進行操作。(最新版 fbThrift 我沒有跟進,不知道改善沒有?)

*. 更新

無論介面、協議、服務、集群,一定要支持不停服灰度更新!!!

如果已經做到了前述的大部分標準,那無論是介面級別、服務級別、還是集群級別的灰度是很順理成章的事。

*. 部署

注意 /proc/loadavg 裡面的數值。嚴格控制每台機器上的進程/線程數。

比如 4 core 的機器,假設所有線程和進程的繁忙度適中的話,理論上系統運行的所有進程線程的數量不應該超過500~600。根據具體的業務,這個值可能有一定的變動。

然後,假設你已做到了之前所有要求。假設你的業務有10個不同的服務進程。假設業務初期用戶少,壓力小,那最簡單的部署演化就是:

兩台4 core 機器,每台機器上各運行一套完整的業務。因為你已經做到了之前的要求,那其實請求和數據是在這兩台機器之間自動負載均衡的。兩台機器上的對應服務構成一個服務集群。

然後用戶多一點,壓力大一點:加機器,加 4 core 機器。

然後用戶再多一點,壓力再大一點,機器估計有6~8台左右:4 core 變 8 core。

然後用戶再多一點,壓力再大一點:加機器,分拆服務。比如之前每台機器運行 10 個服務實例,那現在一台變兩台,每台運行5個服務實例。

以此類推~~

*. 故障隔離

一開始,即使用戶非常少,壓力非常低,每項服務也至少有兩個實例。掛了一個至少還有另外一個在運行。

對於某些壓力超小、業務超簡單,但是不能 down 的服務,做成對等集群。如果有必須要一台機器獨立處理的事務,或者做成對等集群反而引出更多業務流程,那就做成自動選主,且能自動切換主從,且新的主能自動接管當前集群狀態的一主多從集群。

這是當半夜宕機時,你也能安心睡大覺的關鍵!!!

目前我們多個項目,全球一天一千多億的消息投遞,加上亞馬遜的網路分經抖動。只要資料庫高可用不崩,剩下的服務能抗住業務壓力,down再多的機器,再多的服務實例,我們也就:看一眼報警,然後接著睡大覺。第二天再處理~!!!

最後,以上僅對大型高壓力高性能項目有效。普通項目用這種「最佳實踐」成本太高,複雜度大。不推薦。

還有就是,去公司面試,不是全球頂級公司的的最後1兩輪,千萬別用以上內容。否則前幾輪的面試官可能會嘲笑你啥都不懂~~!! -_-!(這是以前多次親身經歷!!-_-!)

最後的最後,那些所謂的分散式理論和知識,實操中基本無用~~!

就好比一致性哈希,實操中必然會用,但不是會讓你去寫。開源的健壯的經歷千萬項目檢驗的一致性哈希代碼一堆一堆的。會用就行~

還有一點,如果是打算去做 OpenStack 之類的,那請當我啥也沒說~~


學生思維


在 TiDB Contributor Club 群里,有小夥伴討論過一個課程 MIT-6.824: Distributed Systems, MIT的課程,專門講分散式系統的,很多專門做分散式系統的老鳥也推薦這個課程,我已經保存書籤了,準備下周開始抽時間看了,題主可以一起來玩~

傳送門:如何的才能更好的學習MIT6.824分散式系統課程?


〈分散式系統原理與泛型〉好像是叫這個


我想這些會對這個問題是一個理論補充吧。

現在主流開源分散式系統架構都有哪些? 分散式系統領域有哪些經典論文?

學習分散式系統需要怎樣的知識?

關於分散式程序設計有哪些書籍值得推薦?

一名分散式存儲工程師的技能樹是怎樣的?

如何的才能更好的學習MIT6.824分散式系統課程?

做一個補充:

分散式系統一般分為分散式K/V系統、分散式文件系統和分散式資料庫等幾個大類,在學習這幾類系統的時候,需要掌握的知識或技能應該包括計算機基礎知識、分散式演算法和協議相關論文、分散式系統設計范型相關論文、開源的分散式系統案例以及造相關的輪子。

基礎知識

根據博主目前經驗來看,學習分散式系統首先要掌握以下基礎知識:

OS相關

體系結構相關

Unix系統編程

Unix網路編程

並發編程

常用數據結構和演算法

論文

分散式系統的論文主要分為兩大方面,一方面是演算法或者協議相關的論文,另一方面是系統設計相關的。

演算法或者協議相關

Byzantine General

paxos

paxos made simple 和 paxos made live

raft

cap base

2pc 3pc

leases

acid

time and ordering

Time Clocks and the ordering of Events in a Distributed System

Virtual Time and Global States of Distributed System

Distributed Snapshots: Determining Global States of a Distributed System

mvcc

consensus

gossip

load balancing algorithms

系統設計范型相關

google file system

bigtable

mapreduce

chubby

spanner

dynamo

megastore

dremel

pregel

percolator

Sinfonia: A New Paradigm for Building Scalable Distributed Systems

google f1

Windows Azure Storage: A high available cloud storage service with strong consistency

facebook haystack

開源系統範例

主要分為分散式K/V,分散式文件系統和分散式資料庫三個方面。

分散式K/V系統

redis cluster

tair

分散式文件系統

hdfs

ceph

swift

lustre

taobao filesystem

分散式資料庫

clustrix

MemSQL

VoltDB

造輪子

可以自己造分散式K/V系統、分散式文件系統、分散式資料庫系統的輪子,簡單的,可以從分散式K/V系統開始。

整個思路

對於基礎知識部分,有盲點就補

對於論文模塊,常見的分散式演算法、協議論文,經典的系統范型相關論文需要精讀

對於開源系統模塊,在學習完論文之後,每個部分精讀一個系統的代碼,其他的系統了解實現原理

對於造輪子,可以儘早開始,先按照自己思路來造,後面通過讀論文、讀開源系統來發現自己系統的缺陷,不斷完善即可

最後,本文只是一個思路,很多東西還沒有細化,需要不斷完善。

參考文獻

http://duanple.blog.163.com/blog/static/709717672011330101333271/

https://github.com/ty4z2008/Qix/blob/master/ds.md

http://blog.ivanyang.me/distributedsystem/2016/03/06/whatwetalkaboutwhenwetalkaboutds


玩分散式啊, 首先你得解決分散式系統最根本的問題: 拜占庭將軍問題.


推薦閱讀:

分散式系統工程師要不要轉行做機器學習?
一名分散式存儲工程師的技能樹是怎樣的?
如何的才能更好的學習MIT6.824分散式系統課程?
請問哪位大神比較過spring cloud和dubbo,各自的優缺點是什麼?

TAG:分散式系統 |