RRedis系列(八):緩存到底該如何做到高可用?

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" "}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/97/9741224f34c1fac10f094b62cb55b3b3.jpeg","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"★ "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"一枚用心堅持寫原創的“無趣”程序猿,在自身受益的同時也讓朋友們在技術上有所提升。"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"上篇文章分析比較了生產環境中常見的幾種緩存,本文接着來分析分析緩存如何做到高可用,大白話解釋下就是緩存到底該怎麼做才能儘可能的避免緩存不可用的情況發生。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"什麼情況會導致緩存不可用?"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"numberedlist","attrs":{"start":null,"normalizeStart":1},"content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"​單點問題:"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"什麼是單點問題呢?就是我們在使用緩存時,有時候由於 QPS、內存容量只需要一個端口(此處的一個端口是指一主一從)就可以扛住所有讀寫請求時,比如寫 QPS 5k,讀 QPS 30k,內存 5G;根據這個數據規模,DBA 在部署資源時會選擇只部署一個節點。當緩存資源由於某些情況導致服務器宕機或服務不可用時,由於只部署了一個端口,從而導致當前整個應用服務不可用(這種情況之前在實際生產環境中真實發生過,直接炸裂),這就是所謂的單點問題;其實在分佈式架構中,爲了做到服務的高可用,要儘量去避免單點問題,做到雞蛋儘量不放在一個籃子裏來儘量保證服務的可用性。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"numberedlist","attrs":{"start":"2","normalizeStart":"2"},"content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"緩存穿透/緩存擊穿"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"緩存穿透/緩存擊穿是指某些時刻由於有些熱 key 失效或者是過期,導致在一瞬間大量請求繞過緩存直接打到 DB 上,由於 DB 的讀寫 qps 並不高,從而導致 DB 直接瞬間被打掛,尤其是在微博這種應用上,突發熱點流量加上緩存設計不合理導致熱 key 過期,就會發生緩存擊穿的情況。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"numberedlist","attrs":{"start":"3","normalizeStart":"3"},"content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":3,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"緩存雪崩"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"緩存雪崩是指由於緩存過期時間設計不合理,緩存數據過期時間集中,導致在某一時刻緩存中數據大面積過期,從而導致緩存的 miss 率大大增加,由於緩存沒有攔住請求導致大量請求落到 DB 上,最終導致後端 DB 資源被徹底打掛,即使重啓 DB 也會被大量請求瞬間再次打掛。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如何設計高可用的緩存?"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"numberedlist","attrs":{"start":null,"normalizeStart":1},"content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"單點問題解決方案"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"首先,單端口在資源申請階段部署爲多端口的(大於一個端口),同時每個端口至少部署爲一主一從且分佈在不同的節點上;通過此種部署方式,會有如下幾個好處:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"假設某個從節點服務不可用時,將讀請求轉移到主節點上可繼續提供服務,當從節點恢復後再加入到集羣中繼續提供服務。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"假設集羣中某幾個節點服務不可用時,此時最壞的情況也只是影響部分用戶的功能使用。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"zerowidth"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"其次,在多端口部署的基礎上,在機房層面做到多機房災備;此種緩存的做法是:假設一個緩存部署兩份,而這兩份緩存部署在不同的機房中,這樣的話,即使其中一個機房發生極端情況,可以將流量切換到另外一個機房中,從而做到機房層面的高可用。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"最後,可以使用一致性 hash 算法,使用機器的 ip 或者域名做 hash 操作,分佈在一個虛擬的環上,同樣對於 key 也做相同的 hash 操作,當 key 得到一個 hash 值後,順時針移動直到遇到第一個節點,然後將 key 對應的 value 存儲到該節點上;此種做法是節點動態上下線的時候只需要對部分 key 做 rehash 操作,但是此種方案的缺點是:節點動態上下線後,key 經過 rehash 操作後導致各個節點數據分佈不均,也就導致各個節點的服務承載的壓力不均不可控。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"numberedlist","attrs":{"start":"2","normalizeStart":"2"},"content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"緩存穿透/緩存擊穿的解決方案"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"緩存擊穿是由於熱 key 失效導致的,所以第一種方案是:可以根據業務場景,選擇可以將熱 key 直接全部緩存到緩存中並且永遠不過期,通過此種方式來避免熱 key 因爲過期的問題導致緩存擊穿;第二種方案是:由於熱 key 一般情況下並不是很多,所以我們可以考慮使用 localCache,在系統啓動時,預先將熱點數據全部加載到內存中,只要服務器不發生宕機就可以一直正常提供服務。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"numberedlist","attrs":{"start":"3","normalizeStart":"3"},"content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":3,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"緩存雪崩的解決方案"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"緩存雪崩是在某一時刻,緩存中數據大量集中過期導致緩存不可用,對於此種情況,一般是在緩存 key 設計時,對 key 增加一個一定時間範圍內的隨機時間戳,使得 key 過期分散開來,從而避免所有 key 同時過期的尷尬情況。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"總結"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本文主要介紹了實際生產環境中緩存該如何做到高可用,從而避免由於緩存不可用而導致整個系統崩潰。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"關於 Redis 系列文章總計 8 篇,從 Redis 基礎命令使用,到 Redis 基礎集合及常用命令的底層實現,然後到集羣搭建實戰,然後到 Redis 的線程模型,最後到線上緩存方案設計及緩存高可用的方案,到此關於 Redis 專題暫時告一段落,但後續還會繼續更新關於緩存相關的文章,朋友們有對緩存相關知識感興趣的話題可以和作者交流,後續會持續更新更多精彩的緩存文章。好了,下篇文章開始我們來講講 MySQL,不知道你會不會感興趣呢?盡情期待哈。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/ba/ba0bbae3160cda22beaec7e372763fa9.jpeg","alt":null,"title":"","style":[{"key":"width","value":"25%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"往期推薦"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://mp.weixin.qq.com/s?__biz=MzIzNTIzNzYyNw==&mid=2247484500&idx=1&sn=d5440c36669bdb8dd8b2d66136cb1333&chksm=e8eb7dc0df9cf4d61d546a6faa4e278f73a51f368b8e903c757696591edb716fa00289808471&token=1252383346&lang=zh_CN#rd","title":""},"content":[{"type":"text","text":"Redis系列(七):緩存只是讀寫回種這麼簡單嗎?如果是,那麼請你一定看看這篇文章"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://mp.weixin.qq.com/s?__biz=MzIzNTIzNzYyNw==&mid=2247484476&idx=1&sn=9ac5d9fda3567e8a970a3608935a9fd9&chksm=e8eb7da8df9cf4be9df41dedde5d768ee3218d8ee9919422044ce7e4e60f3d44ce56a5470d73&token=1252383346&lang=zh_CN#rd","title":""},"content":[{"type":"text","text":"Redis系列(六):你說要看Redis線程模型?安排"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://mp.weixin.qq.com/s?__biz=MzIzNTIzNzYyNw==&mid=2247484438&idx=1&sn=1d3c5a6295580e181dbeed96042984d7&chksm=e8eb7d82df9cf49421feb942feef21482964c65db184284e7fc350ae7ce01581062b2608ee25&token=1252383346&lang=zh_CN#rd","title":""},"content":[{"type":"text","text":"Redis系列(五):你要的Redis集羣搭建來了,實踐與否你自己選!"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"http://mp.weixin.qq.com/s?__biz=MzIzNTIzNzYyNw==&mid=2247484394&idx=1&sn=7423bc0983bdcfc48dcaaf14c700b93d&chksm=e8eb7a7edf9cf368629b751280337f350ddf383cd8cb410491aa6fcd623e84f5c072bd4ea87e&scene=21#wechat_redirect","title":null},"content":[{"type":"text","text":"Redis系列(四):天天用着Redis集羣,主從同步該知道吧?集羣工作原理是否需要了解下?"}]},{"type":"text","text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"http://mp.weixin.qq.com/s?__biz=MzIzNTIzNzYyNw==&mid=2247483827&idx=1&sn=44cfb50953b0f745b2719977453c3a42&chksm=e8eb7827df9cf131ea8aa1496e9ec2d1ed22ed245225dad0613511006b9428fffb16c92cdd6a&scene=21#wechat_redirect","title":null},"content":[{"type":"text","text":"一文讀懂消費者背後的那點\"貓膩\""}]}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章