分散式架構心得

来源:https://www.cnblogs.com/wang_yb/archive/2019/07/22/11224199.html
-Advertisement-
Play Games

"1. 為什麼要分散式" "2. 分散式架構帶來的挑戰" "3. 提高可靠性的設計" "3.1 監控設計" "3.2 一致性設計" "3.3 重試設計" "3.4 熔斷設計" "3.5 限流設計" "3.6 降級設計" "4. 提高性能的設計" "4.1 緩存設計" "4.2 非同步設計" "4.3 ...


1. 為什麼要分散式

隨著信息化的推進, 不論是 PC 還是 mobile 的用戶量都在激增, 單機的性能和可靠性是不可能滿足用戶的增長需求的. 為什麼分散式? 簡單來說, 不用分散式, 沒有更好的方法來解決不斷增長的用戶訪問需求.

分散式是趨勢, 對分散式架構中的機制有所瞭解, 是實施分散式架構的前提. 本文先簡要介紹分散式架構中一些的重要的概念和機制, 後續會對其中的機制進行更細緻的講解, 並給出實現示例.

2. 分散式架構帶來的挑戰

實施分散式之後, 首先面對的就是服務數量的增加, 由此給 監控調度 帶來了新的挑戰. 分散式的複雜性肯定比單機要高, 由此又帶來 可靠性性能 上的挑戰.

3. 提高可靠性的設計

提高可靠性, 先得知道可靠性是怎麼計算的, 一般有 2 個指標 MTTFMTTR

  1. MTTF: mean time to failure 平均故障前時間, 註意, 這裡是 故障前 時間, 不是 故障 時間
  2. MTTR: mean time to recovery 平均修複時間

系統可用性計算方法 MTTF/(MTTF+MTTR)

提高系統的可靠性, 有 2 種方式, 一種是做到沒有故障, 一種做到故障發生時, 系統依然能夠工作. 顯然第一種方式就像寫出沒有 BUG 的程式一樣不可能做到, 所以, 應該把故障也當成正常的業務邏輯來處理, 只要故障有了應對之策, 那麼對系統的損害就微乎其微, 至少損害是可控的.

3.1 監控設計

監控是可靠性的前提, 沒有監控, 無法在第一時間發現問題, 更別說預防問題的發生了. 監控也是分層的:

  • 基礎層: CPU, 記憶體, 網路吞吐, 磁碟 等
  • 中間層: nginx, redis, 消息隊列, 資料庫 等
  • 應用層: HTTP 響應時間, 返回碼, API 調用鏈路, 客戶端訪問信息 等

3.2 一致性設計

一致性是單機應用改造成分散式之後, 首先面對的問題. 一致性有強一致性(ACID)和最終一致性(BASE) 2 種. 現實中, 要求強一致性的場景其實遠沒有我們想象的那麼多, 在分散式系統中, 很多時候只需要最終一致性(BASE)即可.

  1. ACID: 原子性(Atomcity), 一致性(Consistency), 隔離性(Isolation,又稱獨立性), 持久性(Durability)
  2. BASE: 基本可用(Basic Availability), 軟狀態(Soft-state), 最終一致性(Eventual Consistency)

ACID 是真正的強調一致性, BASE 其實是強調可用性

3.3 重試設計

分散式系統中, 存在很多服務之間的調用, 頻繁的互相調用中, 經常會發生些意料之前的間歇性錯誤. 有些錯誤在響應端是會自動恢復的, 所以請求端不用對每個錯誤都直接返回給客戶端, 有時需要再重試幾次, 等待響應端的恢復.

當然, 重試要看情況, 調用返回超時, 或者返回可以重試的錯誤(比如, 繁忙中, 維護中, 資源不足等), 那麼就可以重試幾次. 如果返回 http 503 等, 這些可能觸發了響應端的 BUG, 或者響應端服務已經不正常了, 就沒有必要重試了.

重試也有策略, 不是一味不停的反覆調用, 這樣可能會給響應端帶來更大的壓力, 讓其更難自動恢復. 重試的策略有多種, 根據實際情況, 可以讓重試的時間間隔越來越大, 或者對重試次數做限制.

3.4 熔斷設計

重試是請求端的機制, 熔斷是響應端的機制, 目的是為了防止響應端的進一步惡化. 熔斷是響應端保護自己的一種機制, 也就是在不堪重負的時候, 斷開自己和外部的聯繫, 防止進一步惡化(就像家裡保護電器的保險絲)

熔斷類似保險絲, 但也有不同, 它不僅僅只有 斷開連通 2 種狀態, 還可以有 半開 的狀態, 也就是限制請求的流量, 只處理有限的請求, 直至服務恢復. 當響應端的熔斷斷開的時候, 應該通知請求端, 停止重試

3.5 限流設計

限流的目的是通過對併發訪問進行限速, 讓服務端能夠響應更多的請求, 不至於在峰值被壓死 限流的演算法有: 計數器方式, 隊列演算法(請求速度波動, 處理速度勻速), 漏斗演算法, 令牌桶演算法

3.6 降級設計

降級是在系統應對突發情況時, 降低損失的一個方案 主要的降級方式有:

  1. 降低一致性: 從強一致性變為最終一致性
  2. 停止次要功能: 停止訪問不重要的功能, 從而釋放出更多的資源
  3. 簡化功能: 把一些功能簡化掉. 比如, 簡化業務流程, 或是不再返回全量數據, 只返回部分數據

4. 提高性能的設計

採用分散式設計之後, 不僅不會降低性能, 反而在分散式環境下, 有了更多的手段來提高性能.

4.1 緩存設計

緩存可以有效的提高 I/O, 是提高性能的有效手段之一. 在分散式環境下, 除了性能, 緩存的策略還要考慮一致性的問題, 一般有 3 種常用策略:

  • Cache Aside 更新模式 失效 先從 Cache 取數據, 沒有則從資料庫獲取, 成功後, 放入 Cache 命中 從 Cache 中取數據, 然後返回 更新 先把數據存入資料庫中, 成功後, 讓緩存失效
  • Read/Write Through 更新模式, 與 Cache Aside 相比, 應用不用再關心數據放在緩存還是資料庫中了 Read Through 查詢時如果未命中, 則更新緩存, 但是更新緩存的動作由緩存服務來完成, 應用本身不用關心 Write Through 如果未命中, 直接更新資料庫, 然後返回. 如果命中, 則更新緩存, 然後由緩存服務自己去更新資料庫
  • Write Behind Caching 更新模式 在更新數據的時候,只更新緩存,不更新資料庫,而我們的緩存會非同步地批量更新資料庫 因為 I/O 是非同步處理的, 所有更新操作會非常快, 但是帶來的問題是, 數據不是強一致性的, 有數據丟失的風險

緩存的設計中, 要考慮爬蟲的影響, 因為爬蟲有可能會改變緩存數據的優先順序, 讓真正有用的數據被緩存清除.

4.2 非同步設計

同步調用 影響吞吐量, 消耗系統資源, 只能一對一, 有多米諾骨牌效應, 而 非同步調用 能有效提高系統的吞吐量. 採用非同步設計, 服務解耦之後, 一定要有 監控, 否則出了問題無法及時對應.

非同步調用的方式主要有:

  1. 請求響應方式: 給請求中加入回調, 響應結束後出發回調
  2. 訂閱方式: 接收方訂閱發送方的消息, 收到消息就放入處理隊列中, 逐步處理
  3. Broker 方式: 接收方和發送方互相看不到對方, 發送方發送消息到 broker, 接受方從 broker 中獲取消息來處理, 這種方式的好處是將服務徹底解耦

非同步處理的事務一致性一般不是強一致性, 而是最終一致性, 非同步處理可以和事件溯源(Event Sourcing)結合, 非同步處理 + 事件溯源的方式,可以很好地讓我們的整個系統進行任務的統籌安排、批量處理,可以讓整體處理過程達到性能和資源的最大化利用

4.3 資料庫設計

分散式環境中, 不論是 緩存, 還是 非同步, 最終數據還是要持久化到資料庫中, 如果資料庫慢的話, 前面做的再好也效果有限. 提高資料庫性能的方式主要有:

  1. 讀寫分離(CQRS): 將 Command 和 Query 分開, 如果 Command 操作變為 Event Sourcing, 就可以把寫操作也簡化掉, 也變成無狀態的, 大幅降低寫操作的副作用, 以得到更大的併發和性能
  2. 分庫分表(Sharding): 一般來說, 資料庫最大的性能問題有 2 個, 一個是對資料庫的操作, 一個是資料庫中數據的大小 分庫的策略可以按地理位置, 按日期或者某個範圍分, 或是按一種哈希散列演算法. 資料庫分片必須考慮業務, 從業務的角度入手, 而不是從技術的角度入手 只考慮業務分片, 不要考慮哈希散列的方式分片
  3. 數據分片有水平分片和垂直分片 2 種, 水平分片就是分庫, 垂直分片則是分表, 把一張表中的一些欄位放到一張表中,另一些欄位放到另一張表中

5. 分散式架構的部署

分散式環境下, 部署升級的方式也和單機應用不一樣, 更加靈活, 主要有:

  1. 停機部署: 現有服務停機, 部署新版本之後再啟動
  2. 藍綠部署: 分別有 stage/prod 2 套環境, 升級 stage 之後, 將流量切換到 stage, stage 變為 prod, prod 作為下一次升級的 stage 使用物理機的話, 2 套環境會有資源浪費, 虛擬機的話隨時回收會好些. 如果服務中有狀態的話, 比如緩存之類的, 那麼停機部署和藍綠部署都會有問題
  3. 滾動部署: 逐步替換應用的所有實例, 來緩慢發佈一個新版本, 這種方式對於有狀態的服務也是比較友好的 這種方式的問題是新舊版本同時線上, 如果有問題, 回滾麻煩, 而且 2 個版本同時在會帶來相容性的問題
  4. 灰度部署(金絲雀部署): 將生產環境的流量逐步切換到新環境, 可以按流量分配, 先切 10%, 沒有問題, 再加, 有問題回滾. 在多租戶環境, 也可以按租戶切換流量.
  5. A/B 測試: 這種方式同時上線 2 個版本, 然後比較可用性, 受歡迎程度, 可見性等 藍綠部署是為了不停機, 灰度部署是對新版本的質量沒信心. 而 A/B 測試是對新版的功能沒信心

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1. var arr = [ ]; 數組:[ ] 空數組 console.log為Array(0) 功能:定義空數組用來接收的 2. var str = ’ ’ 空字元串 功能:定義空字元串用來接收的 3. arr[arr.length] = ‘在最後數組添加’ arr.push(‘添加’) 常用 ...
  • 大體思路 後端書寫REST api時,有一些api是非常敏感的,比如獲取用戶個人信息,查看所有用戶列表,修改密碼等。如果不對這些api進行保護,那麼別人就可以很容易地獲取並調用這些 api 進行操作。 所以對於一些api,在調用之前,我們在服務端必須先對操作者進行“身份認證”,這就是所謂的鑒權。 J ...
  • title: 基於SpringBoot+Redis的Session共用與單點登錄 date: 2019 07 23 02:55:52 categories: 架構 author: mrzhou tags: SpringBoot redis session 單點登錄 基於SpringBoot+Redi ...
  • 語音直播房間項目文章彙總。當時對標的競品是音遇、撕歌。2個主力後端研發,3個月,1500+ commit,996、007,紀念那段充滿福報的經歷😂。 系統設計 SD項目架構圖 SD項目:基於狀態機和MQ的語音游戲方案 設計模式系列:狀態模式 狀態機框架選型簡單比較 stateless4j踩坑經歷 ...
  • 架構雜談《六》 超時處理模式 在服務化或者微服務架構里,傳統的整體應用拆分成多個職責單一的微服務,微服務之間通過某種網路通信協議互相通信和交互,完成特定的功能,然而由於網路通信的不穩定,在設計系統時必須考慮到對網路通信的容錯,特別是對調用超時問題的處理。 一、微服務的交互模式 1、同步調用模式 在同 ...
  • 今天,越來越多的用戶被馬蜂窩持續積累的筆記、攻略、嗡嗡等優質的分享內容所吸引,在這裡激發了去旅行的熱情,同時也拉動了馬蜂窩交易的增長。在幫助用戶做出旅行決策、完成交易的過程中,IM 系統起到了重要的作用。 IM 系統為用戶與商家建立了直接溝通的渠道,幫助用戶解答購買旅行產品中的問題,既促成了訂單交易 ...
  • 影響抖音推薦機制的有以下因素。 ①愛心數量就是我們看到抖音視頻,右側有個愛心,愛心越多,越有利於熱門。 ②觀看時長如果用戶只看了2秒就刷到下一個視頻,說明我們的視頻內容質量不怎麼樣,也就是不能受到用戶的喜歡,平臺自然不會給你熱門,給你太多的推薦。 抖音聯盟內部教程 ③評論數量多看同行視頻的評論,你就 ...
  • 大家在玩抖音的過程中是不是會遇到下麵的問題呢,是否玩了很長時間的抖音,並且花了很多原創的心血,作品卻依然沒有上熱門是否感覺明明已經非常努力了,而熱門與你還是擦肩而過是否發現看到別人的視頻在某平臺上見過,卻在這裡上了熱門。 其實,對於80%的抖音用戶來說,這些問題都在困惑著大家,實際上做成功的僅僅只有 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...