分佈式系統設計導論

一、定義

 

從實用主義角度描述分佈式系統,即系統對外有統一的入口,系統內的業務層進程能夠有無限多個,便可水平擴展,可根據計算量增減機器。存儲層支持水平擴展,可根據計算量增減機器。使系統在計算和存儲上,理論上能夠達到無限制。對於這個定義,你們看看就好,我並無過多的進行抽象,我但願更實用更易懂一些。強調一下,這只是一篇導論,概要描述一些分佈式系統中的核心技術。mysql

通常互聯網系統常見的分佈式系統部署爲:外網負載均衡層--web層--業務邏輯負載均衡層--業務邏輯層--持久化層。回頭給你們補張拓撲圖。web

負載均衡層的實現,從大類別上通常分爲兩種:proxy方式與客戶端路由。redis

web層能夠歸納爲外網業務層,並不必定使用的HTTP協議實現,通常用於處理外部協議解析,包裝業務層原子功能以對外提供各類業務。sql

業務邏輯層,將系統劃分爲各個原子性功能,對更爲複雜的業務層提供支持。原子性功能獨立出來,能夠組合出更多的業務,知足業務擴展,另外可根據不一樣的子功能增減機器。另外將核心業務層從web層剝離,也有安全性考慮。數據庫

二、負載均衡

 

客戶端路由:即服務端有多個入口,客戶端依賴一些策略選擇訪問具體某個入口。好比智能DNS,其實就是客戶端路由的一種實現。緩存

proxy實現:客戶端所有訪問統一的proxy做爲訪問入口,由proxy將請求進行分發,策略在proxy中實現,客戶端無需關注。如:ngnix與Apache反向代理是典型的proxy,F五、lvs也算是一種,只是對於輸出流並不走proxy過。也許這樣定義proxy並不必定徹底正確,可是我想不到一個更好的詞了。安全

三、應用層分佈式

 

要使應用層,即web層和業務邏輯層可以實現水平擴展,是相對容易的,總結一句話歸納:保證應用層無狀態,可實現水平擴展。然而在絕大多數應用場景中,業務都是有狀態的,咱們要作到的只是使應用層進程自己是無狀態的,將進程內的內存緩存所有剝離出來,通常分爲兩大類,1、session,存儲用戶認證信息及某些業務的上下文信息;2、業務緩存數據。儘可能不要使用進程內的內存鎖,除非你肯定他不影響進程多開。服務器

目前主流作法均是將session和業務緩存信息抽離出來存入到Redis或者memcache這些程序中,也有一些簡單的作法,依賴負載均衡層,根據不一樣的sessionid或者業務id,將請求分發至對應的業務服務器上,好比在sessionid和業務id上加上服務器id,不過這種作法,在業務服務器宕機後,其餘服務器並不能有效接管其客戶端請求,並不推薦如此實現。session

四、數據庫層分佈式

 

核心在於數據庫水平拆分的實現,通常具體實現是根據要分表的字段作哈希,如對訂單表的訂單號對100取餘,可將分爲100份,獲得一個訂單號維度的100份表。這樣拆分後,查詢方必須知道訂單號才能夠進行操做。實際中每每要進行其餘維度的查詢,好比用戶維度,那麼在存儲的時候,也須要存儲一份用戶維度的表。可讓應用層寫的時候寫兩個維度,也可使用觸發器雙寫(多寫),也能夠根據數據庫增量日誌作異步拆分。併發

數據庫水平拆分是一種以空間換時間的方法,大部分系統使用主從讀寫分離能夠解決的問題,並不必定非要作水平拆分。

五、數據一致性與事物完整性

 

一個比較大型且業務複雜的系統,每每一個業務在處理時,鏈路是比較長的,即須要通過比較多進程或者系統處理才能夠完成,當跨進程跨系統時,要保證數據一致性並非那麼容易,若是不注重數據一致性,那大家的客服估計要忙的暈頭轉向,技術與運維也會在查日誌處理問題業務中沒法自拔。

什麼是數據一致性,系統被劃分爲子模塊後,各個子模塊對於同一筆訂單,他們的數據應該是一致的,跨系統同理。舉個最簡單的例子,用戶去銀行支付,支付成功了,可是在系統中仍舊是未支付,這就是一個最多見的數據一致性問題。

什麼是事物完整性,一筆業務在系統中流轉順序爲,A-B-C-D-E,五個步驟,若ABC成功,到D就已經失敗,那麼這個事物不完整。這個與數據庫中的事物處理又必定的區別,由於每一個事物都做爲不一樣的子事物在單獨進程中執行,系統須要維護這樣的事物完整,就必須增長額外的工做了,好比使用異步補調或者分佈式事物管理器管理事物。

六、日誌與監控

 

對於一個分佈式系統,日誌與監控是沒法省略的,一個業務作完,每每鏈路比較長,這就須要比較完善的日誌系統來跟蹤業務。對於分佈式系統來講,其系統中的進程很是多,業務也比較複雜,若是沒有監控,那人就跟瞎子同樣,哪些業務可能會出問題,哪些可能扛不住了須要加機器,都無從得知。

通常來講分佈式系統,也應該有一套分佈式日誌跟蹤系統,日誌收集器將日誌彙總到日誌系統中,由日誌系統對日誌進行整理。每一個業務請求進入系統應分配一個traceid跟蹤號,使日誌系統可以抽取其業務報文數據,耗時等。

請求次數、請求耗時、峯值、平均值、錯誤數、錯誤報文、線程併發數、請求被block的線程數、數據庫請求消耗、併發數、峯值等等,太多的業務數據都須要被監控到,而且當各個指標與平均值偏離到指定值時應能及時告警。

 

七、系統可用性

 

假如每臺機器一天中出問題的機率爲0.1%,那麼若系統有100臺服務器,在1天中有一臺及以上出問題的機率爲1-0.999^100=9.52%,如果1000臺服務器,這個機率是63.2%,基本上3天就有一臺機器完蛋了,因而可知從技術上提升系統可用性的重要,若是在這樣一個大型系統中你解決不了這個問題,基本上可能每天都有事故,還談什麼用戶體驗與本身的KPI呢?

咱們須要考慮容災了,不論是應用層仍是數據庫層,咱們要提升系統可用性。heartbeat、keepalive對proxy等單點的容災,MHA對MySQL的容災等均可以幫助咱們來提高系統可用性。

 

來源:http://blog.csdn.net/tjgamejx2/article/details/51013428

相關文章
相關標籤/搜索