架構師訓練營第 1 期 - 第 05 周總結

用户头像
Panda
关注
发布于: 2020 年 10 月 25 日

分布式緩存架構

緩存 Cache 與 緩衝 Buffer

  • 緩存 Cache

  • 存儲在計算機上的一個原始數據複製集,以便於訪問

  • 訪問緩存比訪問原始數據便利

  • 介於數據訪問者和數據源之間的一個高速存儲

  • 多次存儲數據時,加快讀取的速度

  • 通常存於內存中

  • 緩衝 Buffer

  • 高速與低速裝置中的一個裝置

  • 不是用於相同數據多次訪問

  • 調節高低速設備存取速度

  • 低速設備先準備好數據寫入Buffer,再由高速設備讀取

  • 高速設備先把數據寫入Buffer, 再由低速設備處理

  • 異步處理數據,才不會相互牽制等待

  • 也是優化性能的一個手段

緩存無處不在

  • CPU 緩存

  • 操作系統緩存

  • 數據庫緩存

  • JVM 編譯緩存

  • CDN 緩存

  • 代理與反向代理緩存

  • 前端緩存

  • 應用程序緩存

  • 分部式對象緩存

緩存關鍵指標

  • 緩存命中率 

  • 緩存是否有效

  • 緩存是否有效依賴於能多少次重用同一個緩存,響應業務請求

  • 有多大的概率在每次查找時能找到所要的數據

  • 如果查询一个缓存,十次查询九次能够得到正确结果,那么它的命中率是 90%。

  • 影響因素

  • 緩存鍵集合大小

  • 集合越大,重用的機率越小

  • 如記錄天氣數據

  • 用 IP 當鍵值 (40億個)

  • 用所在國家數量 (一兩百個)

  • 鍵數量越少,緩存效率越高

  • 因為可用內存的大小固定

  • 想辦法減少可能的還存鍵值數量

  • 緩存可使用的內存空間

  • 內存空間越大,緩存命中率越高

  • 緩存對象生存時間 (TTL,Time To Live)

  • 對象生存時間(數據有效時間)越長,緩存命中率越高

  • 長時間有效的數據更適合緩存

緩存形式

  • 通讀緩存 (read/write through)

  • 給客戶端返回緩存資源

  • 請求未命中時由通讀緩存服務器獲取實際數據

  • 客戶端連接的是通讀緩存,而不是原始的服務器

  • 客戶端甚至不知道原始服務器在哪裡

  • 是客戶端唯一的數據源

  • example

  • 代理緩存

  • 反向代理緩存

  • 多層反向代理緩存

  • CDN

  • 旁路緩存 (cache-aside)

  • 獨立的鍵值鍵(key-value)存儲

  • 由客戶端應用代碼處理緩存

  • 詢問需要的對象是否存於緩存

  • 若存在則返回

  • 若不存在或過期,則連接主數據源取得

  • 將新得到的資料存入緩存

  • 客戶端須知道緩存及最終數據源兩者

  • example

  • 瀏覽器對象緩存

  • 本地對向緩存

  • 遠程分布式對象緩存

一致性hash 特性

  • 一致性

  • 當已有的 key 進行重新映射時

  • key 保留在原Node中

  • key 移到新加入的 Node中

  • 若key 移動到原有的其他 Node中就不滿足一致性

  • 均勻性

  • key 會等概率地映射到每一個Node中

一致性 Hash

  • 基本演算法



  • 建立一致性hash環

  • 值域為hash code的所有空間

  • 如 0 ~ 2^32 -1

  • 順時針排列

  • 計算每一個 Node 的 hash code

  • 可用 Node name, IP

  • 其值一定在 hash 環內

  • 路由計算

  • 求對象 Key 的 hash code

  • 如 Key2

  • 將 key 的 hash code 對應到環上

  • 順時針查找最近 Node hash code

  • 若為 Key0,則為 Node 1

  • 若為 Key6,則為 Node 0

  • 此 Node 即為路由選擇結果

  • 增加 Node 3



  • 計算 Node 3 has code 並置於環上

  • 依路由計算出新的路由

  • 僅 Node 2 至 Node 3之間的 key 會被影響,其他不變

  • 如 key0 及 key3 被影響

  • 由 原本 Node 1,變成新的 Node 3

  • 優點

  • 餘數 hash 增減一個 Node會造成大部分的 Key 緩存不命中

  • 一致性 hash 僅造成小部分 key 緩存不命中

  • 不會對真實數據庫產生極大的負載壓力

  • 缺點

  • 負載壓力不均衡

  • Node hash code 可能過分集中,造成各 Node 間的

  • 訪問負載不均衡

  • 數據存儲不均衡

  • 訪問頻率不均衡

  • 訪問併發量不均衡

  • 增加 Node 後,對負載的分攤也不均衡

  • 僅部分 Node 負載壓力減輕,其他則不變

  • 如 Node 1減輕負載,但 Node 0及 Node 2則不變

  • 加了一個Node 僅影響一個 Node

  • 非我們增加 Node 的目標

  • 增加 Node 希望減輕所有 Node 的負擔

基於虛擬節點的一致性 Hash



  • 將每個節點都擴充多個虛擬節點放置於環上

  • 150 ~ 200 個

  • 之後依照基本的演算法進行路由計算

  • 若對應到虛擬節點,即看虛擬節點對應到哪一個真實節點

  • 以真實節點為路由選擇結果

  • 造成近似均勻的訪問結果

緩存提升性能的原因

  • 使用內存,訪問速度快

  • 通常存儲數據最終的結果,不需要中間計算

  • 減省 CPU 資源

  • 降低數據庫、磁盤及網路的負載壓力

  • 使 I/O設備有更好的響應特性

  • 使整個系統有更好的響應特性

緩存是系統性能優化的大殺器

  • 技術簡單

  • 性能提升顯著

  • 應用場景多

  • 適合於

  • 多次讀取的性能優化手段

  • 對寫沒有優化效果

需合理使用緩存

  • 不合理

  • 過分依賴緩存

  • 不合適的數據訪問特性

  • 合理使用緩存

  • 頻繁修改的數據不適合緩存

  • 來不及讀就已經失效

  • 同一數據的讀寫比在 2:1 以上,緩存才有意義

  • 讀寫比例越高,緩存越有意義,緩存價值也越大

  • 沒有熱點的訪問不適合緩存

  • 內存有限,僅能存儲一部分數據

  • 內存管理使用 LRU (Least Recently Used) 演算法

  • 寫入後,很長時間不讀或隨機讀取

  • 還沒被再次訪問就被擠出緩存

  • 徒消耗內存資源

  • 不遵循二八定律的數據

  • 大部分數據訪問不是集中在小部分的數據上,不適合緩存

  • 二八定律

  • 80%的訪問須集中在20%的數據上

  • 緩存此20%的數據,可以減少80%的訪問時間

  • 數據允許一定時間內的不一致與髒讀

  • 數據庫更新數據,緩存服務器不一定知道

  • 緩存設有失效時間

  • 應用需要容忍一定時間的數據不一致

  • 通常這種延遲是可以接受的,但仍須審慎評估具體的應用

  • 即時更新緩存

  • 即時通知緩存,數據已經失效,刪除該緩存資料

  • 增加系統開銷

  • 不要造成緩存雪崩

  • 緩存數據丟失或緩存不可用,不能影響到應用程序

  • 雪崩原因

  • 數據庫已經習慣緩存

  • 當緩存服務崩潰,數據庫突然接收超過負載的訪問壓力

  • 數據庫崩潰

  • 應用程序崩潰

  • 使用緩存預熱

  • 系統開啟時將熱點數據加載好

  • 避免系統開啟時段性能不好,數據庫負載高

  • 避免緩存穿透

  • 不恰當的業務或惡意攻擊,持續高併發請求不存在的數據

  • 所有請求沒有緩存而都落到數據庫上

  • 解法

  • 將不存在的數據也緩存起來(其value值為null)

消息隊列

  • 系統寫數據性能優化

  • 透過消息隊列異步架構實現

  • 同步調用

  • Client code 在遠端調用功能完成前不返回

  • 阻塞等待後才繼續執行

  • 多個同步調用所用的時間會疊加累計

  • 異步調用

  • Client code將遠端調用放入消息對列(queue)中,就返回

  • 不必等待

  • 增加一個消息隊列消費者,負責真實遠端調用

  • Client code 與遠程系統異步的併行執行

  • 客戶端利用 "回調" 來得知遠端調用的結果並處理之



  • 多次異步調用,不會阻塞應用線程

  • 多次異步調用是同時並行,時間不是疊加累計

消息隊列構建異步調用架構



  • 角色

  • 消息生產者

  • 消息隊列

  • 消息消費者

  • 消息生產者與消息消費者

  • 異步執行

  • 通過消息隊列解耦合

  • 相互之間不用同步等待

  • 不相互阻塞

模型

  • 點對點模型

  • 多個生產者

  • 多個消費者

  • 生產者生產的每個消息只被消費一次

  • 容易進行擴容和伸縮

  • 發布訂閱模型

  • 消息透過一個Topic (主題)被訂閱

  • 此主題可以被多個消費者訂閱

  • 每個消費者都會得到訂閱主題的消息,分別進行處理

  • 消息一次生產,多次消費

  • 消費者間不會影響對方對同一個訂閱消息的處理

好處

  • 實現異步處理,提升(寫)的處理性能

  • 同步響應時間長

  • 異步響應時間短

  • 更好的伸縮性

  • 若上傳文件須後處理,且須擴容

  • 無消息隊列狀況 (同步處理)

  • 擴容前端集群

  • 連其他無相關的操作也一起擴容

  • 資源利用不均衡

  • 使用消息隊列狀況(異步處理)

  • 可直接擴容文件處理的後端工作者

  • 可以針對某一特定場景單獨進行伸縮

  • 使伸縮更具有針對性

  • 不用對架構上做改變

  • 實現削峰填谷

  • 應用程序的負載不均衡

  • 高低峰時間不定

  • 若以高峰來配置系統,可能有很多時間用不到,造成浪費

  • 使用消息隊列可以解決高峰時的併發

  • 數據庫可以依據自己的能力處理消息

  • 事件可在消息隊列中堆積

  • 可以分在一些消息至低谷時處理

  • 高峰時沒有太高的峰值壓力

  • 低谷的時候也沒有浪費資源

  • 失敗隔離和自我修復

  • 生產者不直接依賴消費者

  • 消息隊列將和消費者系統的錯誤與生產者系統組件隔離

  • 雙方互不受對方失敗影響

  • 可以在任意時刻對消費者系統進行維護和發布操作而不影響生產者系統

  • 簡化部屬和服務器管理的難度

  • 解除生產者與消費者間的耦合

  • 雙方沒有直接調用依賴的耦合

  • 雙方沒有代碼的耦合

  • 雙方可獨立開發發展

事件驅動架構 EDA (Event-Driven Architecture)



  • 生產者發布一個事件

  • 消費者訂閱事件

  • 消費者通過消息隊列獲取事件

  • 因事件驅動後續的消費者程序的執行

  • 通過事件構建一個程序運行的流程

  • 更容易擴展功能

  • 新增一個消費者並訂閱主題

  • 好處

  • 系統性能提升

  • 整體架構更加的低耦合

  • 維護擴展更加的容易

  • 耦合表面積更少

  • 請求/響應為強依賴

  • 多方的耦合

  • 事件驅動僅耦合於事件的格式與含義

負載均衡架構

HTTP 負載均衡架構

  • 利用負載均衡服務器將用戶請求分發給集群中的某一台服務器

  • 集群中的服務器

  • 部署相同的應用程序

  • 提供相同Web (HTTP)處理能力

  • 當高併發請求到達負載均衡服務器,負載均衡服務器會

  • 分發請求給不同的應用服務器

  • 使集群中的服務器均勻分攤高併發的請求

  • 負載均衡服務器為公網 IP 地址

  • 通常應用服務器為內網 IP 地址

  • 防止攻擊、增加安全性

負載均衡服務器兩個關鍵點

  • 請求如何分發

  • 如何選擇服務器來分發

請求如何分發

  • HTTP 重定向負載均衡

  • 方法

  • 用戶訪問 HTTP重定向負載均衡服務器的 IP 地址

  • 重定向服務器利用路由算法得到一台真正應用服務器的IP地址

  • 寫入HTTP 重定向header內

  • 重定向服務器不對請求作任何其他處理

  • 用戶端瀏覽器得到重定向header,重新把請求發給真正應用服務器

  • 優點

  • 實作方法簡單

  • 部署簡單

  • 缺點

  • 用戶的每一次請求變成兩次請求

  • 第一次請求得到重定向IP地址

  • 第二次才是真正的應用請求

  • 一次 HTTP 通信,變成兩次 HTTP 通信

  • 請求效率低

  • 安全性問題

  • 應用程序服務器必須為對外暴露

  • IP 必須為公網 IP

  • 很少人使用

  • 性能比較低

  • 安全性比較差

  • DNS 負載均衡

  • 方法

  • DNS解析域名時,將相同域名解析出不同的 IP 地址

  • 對不同用戶解析出不同的 IP 地址,實現負載均衡

  • 由域名服務商提供,不用自己部署負載均衡服務器

  • 缺點

  • 無HTTP重定向兩次請求的缺點

  • 第一次或本地緩存超時時才需要做域名解析

  • 因為原本就需要執行域名解析

  • 安全性問題與HTTP重定向相同

  • 很多大型互聯網應用都使用 DNS 負載均衡

  • DNS解析出來的 IP 地址不是真正的應用服務器IP地址

  • DNS解析出來的 IP 地址是互聯網內部的負載均衡服務器的IP地址

  • 兩級負載均衡

  • 第一級 - DNS 負載均衡

  • 第二級 - 內部應用負載均衡

  • 以此解決DNS負載均衡安全性問題

  • 反向代理負載均衡

  • 方法

  • 若反向代理無用戶請求內容,則轉發至應用服務器取得

  • 利用轉發時選擇服務器,實現負載均衡

  • 適用於小型互聯網應用

  • 效率比較低

  • 性能比較差

  • 因為

  • 反向代理為一個完整的HTTP 請求

  • 反向代理服務器必須

  • 得到用戶端請求的所有 TCP 封包後才能轉發

  • 得到服務器回應的所有TCP封包後才能將響應返回給用戶

  • 需要一個應用層 (HTTP層)協議的轉換

  • 通信中需要處理應用層協議和規範

  • IP 負載均衡

  • 方法

  • 對每一個來自用戶的封包的 IP 地址進行處理

  • 將來源 IP 地址 (用戶 IP) 改成負載均衡服務器 內網 IP 地址

  • 將目標 IP 地址(負載均衡服務器公網 IP)改成應用服務器內網 IP 地址

  • 對來自應用服務器的封包的 IP 地址進行處理

  • 將來源 IP 地址 (應用服務器內網 IP 地址) 改成負載均衡服務器公網 IP 地址

  • 將目標 IP 地址改成用戶的 IP 地址

  • 需維護 IP 映射表

  • 不用應用層協議轉換

  • 處理簡單

  • 性能壓力比反向代理小的多

  • 缺點

  • 一般請求

  • 請求封包少

  • 響應封包多

  • 如圖片、影像等

  • 所有應用服務器的響應封包都需經過負載均衡服務器

  • 服務器的網卡出口頻寬有限

  • 會成為瓶頸

  • 數據鏈路層負載均衡

  • 方法

  • 通過修改封包MAC 地址實現負載均衡

  • 負載均衡服務器與後端應用服務器為相同的 虛擬 IP 地址

  • 對來自用戶的封包

  • 將目標 MAC 地址 (負載均衡服務器)修改成應用服務器的 MAC 地址

  • 應用服務器的響應封包可以直接丟至網路中

  • 因為沒有修改請求的來源及目標 IP 地址

  • 又負載均衡服務器 IP 與應用服務器相同

  • 封包不用再經過負載均衡服務器

  • 又稱三角模式

  • 用戶 --> 負載均衡 --> 應用服務器 --> 用戶

  • 為大型互聯網應用中最主要的負載均衡方式

如何選擇服務器來分發 (負載均衡算法)

  • 輪詢

  • 請求依次分法給每一個服務器

  • 加權輪詢

  • 根據硬件的性能,在輪詢的基礎上,按照配置的權重發給服務器

  • 服務器性能好的權重高,性能低的權重低

  • 隨機

  • 請求隨機發給服務器

  • 如果硬件性能不同,也可以使用加權隨機

  • 最少連接

  • 紀錄服務器正在處理的連接數

  • 選取最少連接者

  • 較少使用

  • 連接數容易算錯

  • 輪詢與隨機已經達到均衡的目的

  • 源地址散列

  • 根據請求來源地址進行 hash 計算

  • 可以保證同一個來源的請求總是在同一個服務器上處理

  • 實現會話(session)黏滯

應用服務器集群的 session 管理

Session

  • Web應用中的狀態訊息

  • 紀錄請求上下文

  • 如交易請求中的購物車

  • 在負載均衡的架構下如何做session管理

  • 請求因算法不同,會落在不同的服務器

  • 上下文無法記錄在一起

管理方法

  • Session 複製

  • 方法

  • 將修改的 session 複製到其他應用服務器上

  • 所有應用服務器記錄相同的 session

  • 缺點

  • 當應用服務器數量大時

  • 每個session 需複製到所有的服務器,通信數據量大

  • 每個session 存儲在所有服務器上 ,存儲數據量大

  • 不符集群減輕服務器壓力的目的

  • 複製造成服務器的負載壓力提升

  • 很難進行大規模伸縮

  • 消耗資源

  • 幾乎不使用這種方式

  • Session 綁定

  • 方法

  • 利用源地址散列算法達成

  • 同一用戶請求總是在同一台服務器上

  • 缺點

  • 違反高可用

  • 當服務器失效,原用戶請求會發至新服務器

  • 但新服務器沒有原本的 session

  • 用戶將丟失先前操作的資料

  • 當服務器迭代新功能時也會出現丟失 session

  • 用戶體驗差

  • 幾乎不使用這種方式

  • 利用 Cookie 紀錄 session

  • 方法

  • 利用 cookie紀錄請求上下文

  • 每一次請求都包含 cookie

  • 缺點

  • cookie 大小有限

  • 某些瀏覽器或特殊的場景下 cookie 會被禁用

  • 雖然有問題,實際應用常用這種方式

  • 使用 session 服務器

  • 方法

  • 建立一個 session 共享服務器或集群

  • 應用服務器不紀錄 session

  • 應用服務器為無狀態服務器

  • 應用服務器由 session 服務器獲得 session 內容

  • 優點

  • 不管應用服務器當機、進行擴容都不影響 session 處理

  • 應用服務器及群

  • 不共享任何訊息

  • share nothing

  • 不紀錄任何狀態

  • 這種集群最容易進行伸縮

  • 最常見的方式



发布于: 2020 年 10 月 25 日 阅读数: 17
用户头像

Panda

关注

还未添加个人签名 2015.06.29 加入

还未添加个人简介

评论

发布
暂无评论
架構師訓練營第 1 期 - 第 05 周總結