之前給組内同學分享了高可用方面的一些經驗,具體見slideshare。一些關鍵點整理如下:
高可用 - 備援 - 服務 - 負載均衡 - lvs + keepalived - 多組lvs,一組lvs間是vip漂移,組與組之間是通過DNS輪詢完成,即域名對應多個vip(不同營運商對應不同ip) - 反向代理 - 應用服務 - 服務化架構 - 存儲 - 緩存 - 結構化存儲 - KV - 硬體裝置 - 交換機 - 網卡 - 機櫃 - 公網出口 - 機房 - failover - watch-dog檢測 - sentinel - mysql MHA - 調用方檢測 - MCF - momostore - HTTPClient代理 - 架構、服務自動實作 - 分布式存儲 - HBase - Cassandra - redis cluster - codis
穩定性: - 穩定性是需要高可用的保證 - 實作細節上需要考慮 - 資源上限:線程數、記憶體隊列長度、連接配接數…… - 突增流量:限流 - 非核心服務故障:降級 - 依賴服務變慢:fail-fast - 如過服務調用路徑很長,其中某個環節變慢。這種情況下,如果不處理,請求占用的資源會越來越多,響應時間也會越來越慢。合理的處理方式是當服務慢到一定程度時,fail-fast,并且最好在調用的源頭實作,可以保證沒有占用過多的資源。 - m*n依賴的影響擴大:實作上解決;自動隔離;合理的逾時時間 - m個服務執行個體需要通路n個資料源,用戶端随機路由到一個服務執行個體,服務執行個體按照一定規則通路資料源。如果某個資料源變慢,由于随機通路服務,所有的服務執行個體都會通路該資料源,目前moa層面是通過線程池處理每個請求,如果資料源越來越慢,并且請求不變,會導緻線程池中堆積了大量通路該資料源的請求,而沒有資源處理其他請求。這就是一個資料源故障,進而影響所有上層服務的情況。 - 實作上解決:線程池隻做計算,通過事件循環處理網絡IO。 - 隊列消費端高可用:多消費者搶占消費 性能&擴充性: - 異步:異步處理部分邏輯,降低響應時間 - 水準擴充性:通過加機器解決請求的增加 - 服務層面:要做到無狀态,可以将狀态放到存儲上 - 存儲層面:做到一種好的資料分布政策 - hash: - 緩存:增删節點,rehash嚴重,會有大量穿透風險 - 存儲:每個hash分片保證高可用 - 擴容:成倍擴容,不太合理 - 一緻性hash - 緩存:增删節點時,rehash可控;并且通過虛拟節點,可以進一步優化 - 擴容:支援單個執行個體擴容 - 示例:Cassandra - range: - 存儲:需要存儲資料分布的中繼資料。 - 擴容:支援單個執行個體擴容 - 示例:HBase - hash + range: - hash key先hash到一個值域,再進行range劃分 - 分布比較均勻 - 示例:redis cluster,codis - 二級映射:号段 + 尾号 => range + hash: - 陌陌
監控&報警: - 發現問題,快速解決問題 - 類别: - 資源監控:cpu,記憶體,IO,網絡…… - JVM監控: - gc次數 - gc耗時 - 服務監控: - 耗時分布(95%, 99%等) - 請求量 - error count - 線程數 - HugeTimeout - FrequencyCount - 調用鍊 - MOA-Watcher