後端架構高可用可伸縮
去年參加技術分享活動, 七牛的一個技術簡要的介紹了一些高可用可伸縮的一些經驗之談, 聽完之後受益匪淺, 整理一下, 主要分以下幾個部分:
入口層高可用業務層高可用緩存層高可用資料庫高可用入口層可伸縮業務層可伸縮緩存層可伸縮資料庫可伸縮下面來分層介紹實踐方法。
入口層高可用
nigix兩個 keeplive保活 心跳做好。
使用心跳技術:keeplive提供這個技術比如機器A IP是1.2.3.4, 機器B IP是1.2.3.5, 那麼再申請一個IP (1.2.3.6)我們稱之為心跳IP, 平時綁定再A上面, 如果A宕機, 那麼IP會自動綁定到B上面DNS 層面綁定到心跳IP即可兩台機器必須在同一網段服務監聽必須監聽所有IP, 如果僅僅監聽心跳IP, 那麼從機上的服務(不持有心跳IP的機器)會啟動失敗伺服器利用率下降(混合部署可以改善這一點)考慮一個問題, 兩台機器, 兩個公網IP, DNS把功能變數名稱同時定位到兩個IP,
不算, 用戶端(比如流覽器) 解析完後會隨機選一個 IP訪問 , 而不是一個失敗後就去另一個 。 所以如果一台機器當機 , 那麼就有一半左右的用戶無法訪問 。
業務層高可用 業務層不要有狀態 , 狀態分散到緩存層和資料庫層 。 只要沒有狀態,
緩存層高可用 緩存層分得細一點, 保證單台緩存宕機後資料庫還能撐得住 。
資料庫高可用MySQL有主從模式, 還有主主模式都能滿足你的需求MongoDB也有ReplicaSet的概念, 基本都能滿足大家的需求。
高可用小結
入口層可伸縮入囗層如何提供伸縮性?直接鋪機器 ?然後DNS加IP就可以了吧?可以, 但也有需要注意的地方儘管一個功能變數名稱解析到幾十個IP沒有問題, 但是很流覽器用戶端只會使用前面幾個IP, 部分功能變數名稱供應商對此有優化(比如每次返回的IP順序隨機 ), 但是這個優化效果不穩定。 推薦的做法是使用少量的nginx機 器作為入囗, 業務伺服器隱藏在內網(HTTP類型的業務這種方式居多)
業務層可伸縮跟應付高可用一樣, 保證無狀態是很好的手段。 加機器繼續水準部署即可。
緩存層可伸縮
直接用 codis或者redis 3.0 即可
如果低峰期間資料庫能抗的住 ,那麼直接下線存然後上新緩存就是最簡單有效的辦法
緩存類型 不變型緩存:緩存key對應的value不會變更 弱一致性和不變型緩存擴容很方便,用一致性HASH即可
一致性HASH在分散式集群中,對機器的添加刪除,或者機器故障後自動脫離集群這些操作是分散式集群管理最基本的功能。如果採用常用的hash(object)%N演算法,那麼在有機器添加或者刪除後,很多原有的資料就無法找到了,這樣嚴重的違反了單調性原則
一致性HASH可以有效解決這個問題,一致性雜湊演算法在保持了單調性的同時,還是資料的遷移達到了最小,這樣的演算法對分散式集群來說是非常合適的,避免了大量資料移轉,減小了伺服器的的壓力。
舉個例子
如果緩存從9台擴容到10台, 簡單Hash況下90%的緩存會馬上失效,而一致性Hash 情況下,只有10%的緩存會失效。
強一致緩存問題1.緩存用戶端的配置更新時間會有微小的差異,在這個時間窗內有可能會拿到過期的資料。2.如果在擴充節點之後裁撤節點,會拿到髒資料。比如a這個key之前在機器1, 擴容後在機器2,資料更新了, 但裁撤節點後key回到機器1 這樣就會有髒資料的問題
問題二解決方法:要麼保持永不減少節點,要麼節點調整間隔大於資料有效時間。
問題一解決方法:
- 兩套hash配置都更新到用戶端,但仍使用舊的配置
- 兩個個用戶端改為只有兩套hash結果一致的情況下會使用緩存,其餘情況從資料庫讀,但寫入緩存。
- 逐個用戶端通知使用新配置。
資料庫可伸縮水準拆分垂直拆分定期滾動
緩存層可伸縮
直接用 codis或者redis 3.0 即可
如果低峰期間資料庫能抗的住 ,那麼直接下線存然後上新緩存就是最簡單有效的辦法
緩存類型 不變型緩存:緩存key對應的value不會變更 弱一致性和不變型緩存擴容很方便,用一致性HASH即可
一致性HASH在分散式集群中,對機器的添加刪除,或者機器故障後自動脫離集群這些操作是分散式集群管理最基本的功能。如果採用常用的hash(object)%N演算法,那麼在有機器添加或者刪除後,很多原有的資料就無法找到了,這樣嚴重的違反了單調性原則
一致性HASH可以有效解決這個問題,一致性雜湊演算法在保持了單調性的同時,還是資料的遷移達到了最小,這樣的演算法對分散式集群來說是非常合適的,避免了大量資料移轉,減小了伺服器的的壓力。
舉個例子
如果緩存從9台擴容到10台, 簡單Hash況下90%的緩存會馬上失效,而一致性Hash 情況下,只有10%的緩存會失效。
強一致緩存問題1.緩存用戶端的配置更新時間會有微小的差異,在這個時間窗內有可能會拿到過期的資料。2.如果在擴充節點之後裁撤節點,會拿到髒資料。比如a這個key之前在機器1, 擴容後在機器2,資料更新了, 但裁撤節點後key回到機器1 這樣就會有髒資料的問題
問題二解決方法:要麼保持永不減少節點,要麼節點調整間隔大於資料有效時間。
問題一解決方法:
- 兩套hash配置都更新到用戶端,但仍使用舊的配置
- 兩個個用戶端改為只有兩套hash結果一致的情況下會使用緩存,其餘情況從資料庫讀,但寫入緩存。
- 逐個用戶端通知使用新配置。
資料庫可伸縮水準拆分垂直拆分定期滾動