如何設計乙個微型分布式架構?

2021-09-19 22:21:19 字數 3071 閱讀 2853

序言(初衷)

快取伺服器儲存模型架構(背景):

隨著業務頻寬自然增長,使用者端頻寬增長,假設業務回源率不變的情況下,磁碟快取淘汰更新(淘汰)速率變快,表現為以下業務瓶頸(iowait變高、回源頻寬變高,由於磁碟空間大小受限的快取淘汰導致回源率變高)。

為了說明這個原理。我們假設兩個極端:乙個是裝置磁碟容量無限大,業務過來的流量快取只受源站快取規則受限。只要快取沒過期,磁碟可以無限快取,回源流量只需要首次訪問的流量,所以這個回源量(率)只跟業務特性(重複率)有關係。另乙個極端是磁碟極限小(歸零),那麼無論業務設定快取是否過期,客戶端訪問量都是1比1的回源量。假設業務平均的快取週期是1個小時。那麼這1個小時的首次快取頻寬(同一cache key的多次訪問,我們認為是一次)將是這個硬碟的所需要的空間。這個大小是合理的,可以保證磁碟足夠容納業務的量。假設這個量達不到,或者本來達到了,但是由於業務自然增長了,1個小時內地首次快取頻寬變多,硬碟空間也不夠用。

裝置擴容是個解決辦法。但是壓測系統在這之前,沒有客觀資料證明需要擴容多大裝置。或者擴容多少裝置沒有進行灰度驗證,裝置到位拍腦袋直接線上部署機器。我們在實驗機器進行線上日誌的重放,模擬出儲存模擬曲線,來指導線上機房合理的裝置儲存。這就是建設重放日誌系統的意義。

麻雀雖小,五臟俱全的重放日誌模型(總覽)

這一章,我們定義了下列模組:

圖2 日誌伺服器的日誌分片檔案任務控制器:啟動任務或者結束任務總開關。任務分配均勻分配給具體的肉雞和**伺服器。插入任務到task pool中,收集服務端的實時總流量、回源流量、總請求次數和回源次數資料並插入到回源率結果資料表。

**服務端:提供實時回源資料查詢服務。並且安裝nws快取伺服器等元件,該機器等同於線上機房的軟體模組。

實時展示介面:可隨時檢視實時回源率和一些任務異常狀態資訊。

圖3為客戶端和服務端的互**。圖4是任務控制端在任務進行中和其他模組的聯動過程。

圖3 肉雞和**服務端的架構

圖4 控制端的任務聯動過程分布式系統特點

先說說高效能:在乙個通用模型中。我們模擬線上日誌,這個系統要做到高效、因為我們的重放日誌速度要比線上的qps還要快。機器的重放速度決定了分析結果的速度。同時更快的速度,所需要的肉雞資源更少。筆者在python各個url請求庫和golang中,最終敲定使用了golang實現肉雞。golang做到了和原生c+epoll一樣快的速度,但是**實現容易多了。理論上我們對一台做過**端效能瓶頸分析。線上日誌比模擬日誌更複雜,qps適度下降是必然的。golang這個客戶端達到預期目標。

圖5 系統的動態可擴充套件可恢復:分布式系統不同於單機模式。不能避免可能有各種故障,有時候系統部分節點出錯了,我們更傾向於不用這個節點,而不是繼續使用未處理完成的結果。即非0即1,無中間狀態。還有分布式系統網路傳輸延遲不可控。所以壓測系統設計了一套容錯機制:包括心跳檢測失敗,自動在資料表剔除肉雞服務端。介面異常容錯。超時過期未完成任務去除。crontab定時拉取退出程序等。

一些設計正規化的思考

single-productor and multi-consumer

在肉雞客戶端的設計中:讀日誌檔案一行一條記錄,新增到訊息管道,然後多個執行worker從訊息管道取url,執行模擬請求。訊息管道傳送的是一條待執行的日誌url。io消耗型程式指的是如果consumer執行訪問日誌並瞬間完成結果,但是productor需要對日誌進行複雜的字串處理(例如正則之類的),那麼它下次取不到資料,就會被管道block住。另外一種是cpu消耗型程式,如果日誌url已經預先處理好了,productor只是簡單的copy資料給訊息管道。而consumer訪問url,經過不可預知的網路延遲。那麼多個consumer(因為是包括網路訪問時間,consumer個數設計超過cpu核數,比如2倍)同時訪問,讀端速度慢於寫端數度。在對乙個日誌檔案進行實驗,我們發現處理18w條記錄日誌的時間是0.3s,而執行完這些url的訪問任務則需要3分鐘。那麼很顯然這是乙個cpu消耗性程序。如果是io消耗型的程式。golang有種叫fan out的訊息模型。我們可以這樣設計:多個讀端去讀取多個chan list的chan,乙個寫端寫乙個chan。fanout則將寫端的chan,迴圈寫到chan list的chan中。

map-reduce

我們有時會做乙個地理位置乙個運營商的機房日誌分析。乙個機房包含數台機器ip。合理的排程多個肉雞客戶端並行訪問日誌,可以更快速得到合併回源率資料。

那麼如何解決這個問題呢,根本原因在於彙總資料所在的檔案系統是本地的,不是分布式的(hadoop的hdfs大概就是基於這種需求發明的把)。如果是狀態碼緯度,這種思路是沒問題的,因為http狀態碼總量就那麼少。那麼如果是url緯度,比如說某機房給單肉雞的單次任務在10分鐘的url總資料量達到18萬條。只看日誌重複數》100的肉雞資料。這樣誤差最大值是100*肉雞數,所以對於10臺肉雞的機房,只要是綜合合併結果》1000。都是可信任的。如果是網域名稱緯度,少數頭部客戶流量佔比大多數頻寬。 這也就是所謂的hot-key,少數的hot-key佔據了大多數比例的流量。所以網域名稱緯度時,這個時候可以把關注點縮放在指定網域名稱的url列表。如果本地上報給資料表的資料量太大,url也可以考慮進行短位址壓縮。當然如果不想彎道超車的話,需要硬解決這個問題,那可能得需要hdfs這種分布式檔案系統。

stream-processing

所謂的流式處理則需要在前一道部分輸出結果到達時,啟動後一道工序,前一道工序繼續輸出,後一道則需要做出處理事件響應。後一道需要頻繁排程程式。

總結當然:現實中的生產線的分布式系統會遠比這個複雜,但是本文實現的從0到1的迷你麻雀分布式系統有一定的實踐意義。它不是一蹴而就的,不斷地版本迭代。當然該系統也完成了作者的kpi-儲存模型分析,在中途遇到問題時,進行的設計思考和改良,在此總結分享給大家。

如何設計乙個麻雀般的微型分布式架構?

本文由 mariolu 發表於 雲 社群專欄 隨著業務頻寬自然增長,使用者端頻寬增長,假設業務回源率不變的情況下,磁碟快取淘汰更新 淘汰 速率變快,表現為以下業務瓶頸 iowait變高 回源頻寬變高,由於磁碟空間大小受限的快取淘汰導致回源率變高 為了說明這個原理。我們假設兩個極端 乙個是裝置磁碟容量...

設計乙個分布式RPC框架

提前先祝大家春節快樂!好了,先簡單聊聊。我從事的是大資料開發相關的工作,主要負責的是大資料計算這塊的內容。最近hive集群跑任務總是會出現thrift連線hs2相關問題,研究了解了下內部原理,突然來了興趣,就想著自己也實現乙個rpc框架,這樣可以讓自己在設計與實現rpc框架過程中,也能從中了解和解決...

設計乙個分布式RPC框架

提前先祝大家春節快樂!好了,先簡單聊聊。我從事的是大資料開發相關的工作,主要負責的是大資料計算這塊的內容。最近hive集群跑任務總是會出現thrift連線hs2相關問題,研究了解了下內部原理,突然來了興趣,就想著自己也實現乙個rpc框架,這樣可以讓自己在設計與實現rpc框架過程中,也能從中了解和解決...