久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

Redis中怎么應(yīng)對緩存熱key問題

165次閱讀
沒有評論

共計(jì) 3675 個字符,預(yù)計(jì)需要花費(fèi) 10 分鐘才能閱讀完成。

這篇“Redis 中怎么應(yīng)對緩存熱 key 問題”文章的知識點(diǎn)大部分人都不太理解,所以丸趣 TV 小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細(xì),步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Redis 中怎么應(yīng)對緩存熱 key 問題”文章吧。

背景

熱 key 是什么問題,如何導(dǎo)致的?

一般來說,我們使用的緩存 Redis 都是多節(jié)點(diǎn)的集群版,對某個 key 進(jìn)行讀寫時,會根據(jù)該 key 的 hash 計(jì)算出對應(yīng)的 slot,根據(jù)這個 slot 就能找到與之對應(yīng)的分片 (一個 master 和多個 slave 組成的一組 redis 集群) 來存取該 K -V。但是在實(shí)際應(yīng)用過程中,對于某些特定業(yè)務(wù)或者一些特定的時段(比如電商業(yè)務(wù)的商品秒殺活動),可能會發(fā)生大量的請求訪問同一個 key。所有的請求(且這類請求讀寫比例非常高)都會落到同一個 redis server 上,該 redis 的負(fù)載就會嚴(yán)重加劇,此時整個系統(tǒng)增加新 redis 實(shí)例也沒有任何用處,因?yàn)楦鶕?jù) hash 算法,同一個 key 的請求還是會落到同一臺新機(jī)器上,該機(jī)器依然會成為系統(tǒng)瓶頸 2,甚至造成整個集群宕掉,若此熱點(diǎn) key 的 value 也比較大,也會造成網(wǎng)卡達(dá)到瓶頸,這種問題稱為“熱 key”問題。

如下圖 1、2 所示,分別是正常 redis cluster 集群和使用一層 proxy 代理的 redis 集群 key 訪問。

如上所說,熱 key 會給集群中的少部分節(jié)點(diǎn)帶來超高的負(fù)載壓力,如果不正確處理,那么這些節(jié)點(diǎn)宕機(jī)都有可能,從而會影響整個緩存集群的運(yùn)作,因此我們必須及時發(fā)現(xiàn)熱 key、解決熱 key 問題。

1. 熱 key 探測

熱 key 探測,看到由于 redis 集群的分散性以及熱點(diǎn) key 帶來的一些顯著影響,我們可以通過由粗及細(xì)的思考流程來做熱點(diǎn) key 探測的方案。

1.1 集群中每個 slot 的 qps 監(jiān)控

熱 key 最明顯的影響是整個 redis 集群中的 qps 并沒有那么大的前提下,流量分布在集群中 slot 不均的問題,那么我們可以最先想到的就是對于每個 slot 中的流量做監(jiān)控,上報之后做每個 slot 的流量對比,就能在熱 key 出現(xiàn)時發(fā)現(xiàn)影響到的具體 slot。雖然這個監(jiān)控最為方便,但是粒度過于粗了,僅適用于前期集群監(jiān)控方案,并不適用于精準(zhǔn)探測到熱 key 的場景。

1.2 proxy 的代理機(jī)制作為整個流量入口統(tǒng)計(jì)

如果我們使用的是圖 2 的 redis 集群 proxy 代理模式,由于所有的請求都會先到 proxy 再到具體的 slot 節(jié)點(diǎn),那么這個熱點(diǎn) key 的探測統(tǒng)計(jì)就可以放在 proxy 中做,在 proxy 中基于時間滑動窗口,對每個 key 做計(jì)數(shù),然后統(tǒng)計(jì)出超出對應(yīng)閾值的 key。為了防止過多冗余的統(tǒng)計(jì),還可以設(shè)定一些規(guī)則,僅統(tǒng)計(jì)對應(yīng)前綴和類型的 key。這種方式需要至少有 proxy 的代理機(jī)制,對于 redis 架構(gòu)有要求。

1.3 redis 基于 LFU 的熱點(diǎn) key 發(fā)現(xiàn)機(jī)制

redis 4.0 以上的版本支持了每個節(jié)點(diǎn)上的基于 LFU 的熱點(diǎn) key 發(fā)現(xiàn)機(jī)制,使用 redis-cli –hotkeys 即可,執(zhí)行 redis-cli 時加上–hotkeys 選項(xiàng)。可以定時在節(jié)點(diǎn)中使用該命令來發(fā)現(xiàn)對應(yīng)熱點(diǎn) key。

如下所示,可以看到 redis-cli –hotkeys 的執(zhí)行結(jié)果,熱 key 的統(tǒng)計(jì)信息,這個命令的執(zhí)行時間較長,可以設(shè)置定時執(zhí)行來統(tǒng)計(jì)。

1.4 基于 Redis 客戶端做探測

由于 redis 的命令每次都是從客戶端發(fā)出,基于此我們可以在 redis client 的一些代碼處進(jìn)行統(tǒng)計(jì)計(jì)數(shù),每個 client 做基于時間滑動窗口的統(tǒng)計(jì),超過一定的閾值之后上報至 server,然后統(tǒng)一由 server 下發(fā)至各個 client,并且配置對應(yīng)的過期時間。

這個方式看起來更優(yōu)美,其實(shí)在一些應(yīng)用場景中并不是那么合適,因?yàn)樵?client 端這一側(cè)的改造,會給運(yùn)行的進(jìn)程帶來更大的內(nèi)存開銷,更直接的來說,對于 Java 和 goLang 這種自動內(nèi)存管理的語言,會更加頻繁的創(chuàng)建對象,從而觸發(fā) gc 導(dǎo)致接口響應(yīng)耗時增加的問題,這個反而是不太容易預(yù)料到的事情。

最終可以通過各個公司的基建,做出對應(yīng)的選擇。

2. 熱 key 解決

通過上述幾種方式我們探測到了對應(yīng)熱 key 或者熱 slot,那么我們就要解決對應(yīng)的熱 key 問題。解決熱 key 也有好幾種思路可以參考,我們一個一個捋一下。

2.1 對特定 key 或 slot 做限流

一種最簡單粗暴的方式,對于特定的 slot 或者熱 key 做限流,這個方案明顯對于業(yè)務(wù)來說是有損的,所以建議只用在出現(xiàn)線上問題,需要止損的時候進(jìn)行特定的限流。

2.2 使用二級(本地)緩存

本地緩存也是一個最常用的解決方案,既然我們的一級緩存扛不住這么大的壓力,就再加一個二級緩存吧。由于每個請求都是由 service 發(fā)出的,這個二級緩存加在 service 端是再合適不過了,因此可以在服務(wù)端每次獲取到對應(yīng)熱 key 時,使用本地緩存存儲一份,等本地緩存過期后再重新請求,降低 redis 集群壓力。以 java 為例,guavaCache 就是現(xiàn)成的工具。以下示例:

 // 本地緩存初始化以及構(gòu)造
 private static LoadingCache String, List Object  configCache
 = CacheBuilder.newBuilder()
 .concurrencyLevel(8) // 并發(fā)讀寫的級別,建議設(shè)置 cpu 核數(shù)
 .expireAfterWrite(10, TimeUnit.SECONDS) // 寫入數(shù)據(jù)后多久過期
 .initialCapacity(10) // 初始化 cache 的容器大小
 .maximumSize(10)//cache 的容器最大
 .recordStats()
 // build 方法中可以指定 CacheLoader,在緩存不存在時通過 CacheLoader 的實(shí)現(xiàn)自動加載緩存
 .build(new CacheLoader String, List Object () {
 @Override
 public List Object  load(String hotKey) throws Exception {
 
 }
 });
 
 // 本地緩存獲取
 Object result = configCache.get(key);

本地緩存對于我們的最大的影響就是數(shù)據(jù)不一致的問題,我們設(shè)置多長的緩存過期時間,就會導(dǎo)致最長有多久的線上數(shù)據(jù)不一致問題,這個緩存時間需要衡量自身的集群壓力以及業(yè)務(wù)接受的最大不一致時間。

2.3 拆 key

如何既能保證不出現(xiàn)熱 key 問題,又能盡量的保證數(shù)據(jù)一致性呢?拆 key 也是一個好的解決方案。

我們在放入緩存時就將對應(yīng)業(yè)務(wù)的緩存 key 拆分成多個不同的 key。如下圖所示,我們首先在更新緩存的一側(cè),將 key 拆成 N 份,比如一個 key 名字叫做 good_100,那我們就可以把它拆成四份,good_100_copy1、good_100_copy2、good_100_copy3、good_100_copy4,每次更新和新增時都需要去改動這 N 個 key,這一步就是拆 key。

對于 service 端來講,我們就需要想辦法盡量將自己訪問的流量足夠的均勻,如何給自己即將訪問的熱 key 上加入后綴。幾種辦法,根據(jù)本機(jī)的 ip 或 mac 地址做 hash,之后的值與拆 key 的數(shù)量做取余,最終決定拼接成什么樣的 key 后綴,從而打到哪臺機(jī)器上;服務(wù)啟動時的一個隨機(jī)數(shù)對拆 key 的數(shù)量做取余。

2.4 本地緩存的另外一種思路 配置中心

對于熟悉微服務(wù)配置中心的伙伴來講,我們的思路可以向配置中心的一致性轉(zhuǎn)變一下。拿 nacos 來舉例,它是如何做到分布式的配置一致性的,并且相應(yīng)速度很快?那我們可以將緩存類比配置,這樣去做。

長輪詢 + 本地化的配置。首先服務(wù)啟動時會初始化全部的配置,然后定時啟動長輪詢?nèi)ゲ樵儺?dāng)前服務(wù)監(jiān)聽的配置有沒有變更,如果有變更,長輪詢的請求便會立刻返回,更新本地配置;如果沒有變更,對于所有的業(yè)務(wù)代碼都是使用本地的內(nèi)存緩存配置。這樣就能保證分布式的緩存配置時效性與一致性。

2.5 其他可以提前做的預(yù)案

上面的每一個方案都相對獨(dú)立的去解決熱 key 問題,那么如果我們真的在面臨業(yè)務(wù)訴求時,其實(shí)會有很長的時間來考慮整體的方案設(shè)計(jì)。一些極端的秒殺場景帶來的熱 key 問題,如果我們預(yù)算充足,可以直接做服務(wù)的業(yè)務(wù)隔離、redis 緩存集群的隔離,避免影響到正常業(yè)務(wù)的同時,也會可以臨時采取更好的容災(zāi)、限流措施。

一些整合的方案

目前市面上已經(jīng)有了不少關(guān)于 hotKey 相對完整的應(yīng)用級解決方案,其中京東在這方面有開源的 hotkey 工具,原理就是在 client 端做洞察,然后上報對應(yīng) hotkey,server 端檢測到后,將對應(yīng) hotkey 下發(fā)到對應(yīng)服務(wù)端做本地緩存,并且這個本地緩存在遠(yuǎn)程對應(yīng)的 key 更新后,會同步更新,已經(jīng)是目前較為成熟的自動探測熱 key、分布式一致性緩存解決方案,京東零售熱 key。

以上就是關(guān)于“Redis 中怎么應(yīng)對緩存熱 key 問題”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望丸趣 TV 小編分享的內(nèi)容對大家有幫助,若想了解更多相關(guān)的知識內(nèi)容,請關(guān)注丸趣 TV 行業(yè)資訊頻道。

正文完
 
丸趣
版權(quán)聲明:本站原創(chuàng)文章,由 丸趣 2023-07-15發(fā)表,共計(jì)3675字。
轉(zhuǎn)載說明:除特殊說明外本站除技術(shù)相關(guān)以外文章皆由網(wǎng)絡(luò)搜集發(fā)布,轉(zhuǎn)載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 绵阳市| 黎城县| 台东县| 徐水县| 房产| 大港区| 奈曼旗| 牡丹江市| 邮箱| 巩留县| 呈贡县| 福安市| 广灵县| 凤庆县| 东海县| 白朗县| 涿鹿县| 潜山县| 桑日县| 交口县| 会东县| 台北县| 虎林市| 登封市| 潜江市| 台湾省| SHOW| 永靖县| 定结县| 南木林县| 庆城县| 静海县| 内江市| 邻水| 麻城市| 阿鲁科尔沁旗| 松溪县| 台北市| 漯河市| 突泉县| 华蓥市|