## 一:場景 20w的QPS的場景下,服務端架構應如何設計? ## 二:常規解決方案 可使用分散式緩存來抗,比如redis集群,6主6從,主提供讀寫,從作為備,不提供讀寫服務。1台平均抗3w併發,還可以抗住,如果QPS達到100w,通過增加redis集群中的機器數量,可以擴展緩存的容量和併發讀寫能 ...
一:場景
20w的QPS的場景下,服務端架構應如何設計?
二:常規解決方案
可使用分散式緩存來抗,比如redis集群,6主6從,主提供讀寫,從作為備,不提供讀寫服務。1台平均抗3w併發,還可以抗住,如果QPS達到100w,通過增加redis集群中的機器數量,可以擴展緩存的容量和併發讀寫能力。同時,緩存數據對於應用來講都是共用的,主從架構,實現高可用。
三:如何解決緩存熱點(熱key)問題
但是如果出現緩存熱點,比如10w流量來自同一個key,打到同一個redis實例,那麼就有可能出現CPU被打滿,這種增加redis集群數量解決不了問題。
本地緩存可以解決熱key問題,主要原因是本地緩存可以避免redis單台緩存伺服器的高負載。通過複製多份緩存副本,將請求分散到多個緩存伺服器上,可以減輕緩存熱點導致的單台緩存伺服器壓力。此外,本地記憶體緩存也具有更快的訪問速度,因為數據存儲在應用程式的記憶體中,無需跨網路傳輸數據。
四:通用多級緩存方案
請求優先打到應用本地緩存,本地緩存不存在,再去r2m(redis)集群拉取,同時緩存到本地
五:多級緩存同步方案
1 運營後臺保存數據,寫入r2m緩存,同時通過redis的發佈訂閱功能發佈消息
2 本地應用集群作為消息訂閱者,接受消息後,刪除本地緩存,C端流量請求打過來的時候,如果本地緩存不存在,則將r2m中緩存載入到本地緩存。
3 定時任務是防止極端情況下,r2m緩存失效,將數據重新載入到r2m緩存。
六:緩存同步組件選型
採用redis的發佈訂閱。
Redis的發佈訂閱模式是推模式。在Redis中,SUBSCRIBE命令用於訂閱一個或多個頻道,以便在有消息發佈到這些頻道時接收通知。PUBLISH命令用於向一個或多個頻道發佈消息。當有消息發佈到某個頻道時,所有訂閱該頻道的客戶端都會收到該消息。在推模式下,每個頻道維護一個客戶端列表,發送消息時遍歷該列表將消息推送給所有訂閱者。拉模式則相反,發送者將消息放到一個郵箱中,所有訂閱這個郵箱的客戶端可以在任意時刻去收取。確保所有客戶端都成功收取完整的郵件後,才刪除該郵件。
Redis的發佈訂閱是非同步的。當有消息發佈到某個頻道時,Redis會非同步地將消息推送給所有訂閱該頻道的客戶端。這意味著,客戶端不會阻塞等待消息,而是繼續執行其他任務,直到需要接收消息時才會去獲取。這種非同步方式可以提高系統的併發性和效率。
七:使用本地緩存註意事項
1 本地緩存占用java進程的jvm記憶體空間,故不能進行大數據量存儲,需要進行緩存大小評估。
2 業務能接受短暫數據的不一致,更適用於讀場景。
3 緩存更新策略,主動更新和被動更新,本地緩存一定要設置有效期
4 定時任務同步緩存機制,根據業務情況考慮極端情況數據丟失
5 rpc調用避免本地緩存污染,可通過深拷貝解決。
6 本地緩存隨著應用重啟而失效,註意載入分散式緩存時機
7 redis的pub,sub模式更新緩存策略(刪除本地緩存key,避免在pub,sub模式下傳遞大value,pub,sub模式不會持久化消息數據,導致消費者對應redis的緩衝區超限,從而導致數據丟失),本地緩存失效時,加鎖synchronized,由一個線程載入r2m緩存,避免併發更新。
備註:r2m底層由redis實現。
作者:京東科技 張石磊
來源:京東雲開發者社區