欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一文了解發(fā)現(xiàn)并解決Redis熱key與大key問題

 更新時(shí)間:2024年05月12日 16:00:52   作者:CoLiuRs  
熱key是服務(wù)端的常見問題,本文主要介紹Redis熱key與大key問題的解決方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

使用緩存

為什么使用緩存

緩存就是數(shù)據(jù)交換的緩沖區(qū)(稱作Cache),目的就是提高我們的接口性能,特別是那些需要大量CPU計(jì)算和I/O獲取的數(shù)據(jù)。

使用緩存帶來的問題

緩存雖然能夠提高應(yīng)用程序的性能,但也會(huì)帶來一些問題。比如:緩存失效,緩存擊穿,緩存雪崩,數(shù)據(jù)一致性問題

緩存雪崩

緩存失效為什么會(huì)帶來問題呢?試想一下,單個(gè)的緩存失效其實(shí)并不會(huì)引發(fā)多大的問題,問題在于當(dāng)大量的Key同時(shí)失效時(shí),在高并發(fā)的情況下,大量的請(qǐng)求同時(shí)到數(shù)據(jù)庫層,會(huì)給數(shù)據(jù)庫層帶來壓力,從而引發(fā)其他的問題。

解決方案

優(yōu)化過期時(shí)間

既然是同時(shí)失效,那么我們只需要在Key的失效時(shí)間上再加上一個(gè)隨機(jī)時(shí)間就好了,也就是失效時(shí)間 + 隨機(jī)時(shí)間。go-zero 上已經(jīng)有相關(guān)的代碼,我簡單摘抄出來看下

// A Unstable is used to generate random value around the mean value base on given deviation.
type Unstable struct {
	deviation float64
	r         *rand.Rand
	lock      *sync.Mutex
}


// AroundDuration returns a random duration with given base and deviation.
func (u Unstable) AroundDuration(base time.Duration) time.Duration {
	u.lock.Lock()
	val := time.Duration((1 + u.deviation - 2*u.deviation*u.r.Float64()) * float64(base))
	u.lock.Unlock()
	return val
}

優(yōu)化緩存

采用多級(jí)緩存,不同級(jí)別緩存設(shè)置的超時(shí)時(shí)間不同,及時(shí)某個(gè)級(jí)別緩存都過期,也有其他級(jí)別緩存兜底。代碼如下,完整代碼見:cache_redis.go

func (r *RedisCacheClient) Get(ctx context.Context, key string, fetch fetchFunc) (result []byte, err error) {
	var byteValue []byte
	fullKey := getFullKey(r.prefix, key)
	fullKeyByte, _ := json.Marshal(fullKey)
	if val, err := r.localCache.Get(fullKeyByte); err == nil {
		r.status.IncrementLocalCacheHit()
		return val, nil
	}
	r.status.IncrementLocalCacheMiss()
	startTime := time.Now()
	byteValue, err = r.client.Get(fullKey).Bytes()
	elapsed := time.Since(startTime).Milliseconds()
	for _, p := range r.plugins {
		p.OnGetRequestEnd(ctx, cmdGet, elapsed, fullKey, err)
	}
	
	// 數(shù)據(jù)源拉取原始數(shù)據(jù)
    ........	
}

緩存擊穿

對(duì)于某些key設(shè)置了過期時(shí)間,但是其是熱點(diǎn)數(shù)據(jù),如果某個(gè)key失效,可能大量的請(qǐng)求打過來,緩存未命中,然后去數(shù)據(jù)庫訪問,此時(shí)數(shù)據(jù)庫訪問量會(huì)急劇增加。

解決方案

多級(jí)緩存+singleflight

我們可以設(shè)置多級(jí)緩存,每一級(jí)緩存失效時(shí)間不一樣,某個(gè)級(jí)別緩存過期,也有其他級(jí)別緩存兜底。而且再加上singleflight 限制,就可以做每一個(gè)服務(wù)實(shí)例只有一個(gè)請(qǐng)求最終到數(shù)據(jù)庫源上,大大減輕了數(shù)據(jù)源壓力

緩存穿透

緩存穿透是指查詢的數(shù)據(jù)在數(shù)據(jù)庫是沒有的,那么在緩存中自然也沒有,所以,在緩存中查不到就會(huì)去數(shù)據(jù)庫取查詢,這樣的請(qǐng)求一多,那么我們的數(shù)據(jù)庫的壓力自然會(huì)增大。

解決方案

設(shè)置Null值

  • 約定:對(duì)于返回為Null的依然緩存,對(duì)于拋出異常的返回不進(jìn)行緩存,注意不要把拋異常的也給緩存了。采用這種手段的會(huì)增加我們緩存的維護(hù)成本,需要在插入緩存的時(shí)候刪除這個(gè)空緩存,當(dāng)然我們可以通過設(shè)置較短的超時(shí)時(shí)間來解決這個(gè)問題。

數(shù)據(jù)過濾

  • 小數(shù)據(jù)用BitMap,大數(shù)據(jù)可以用布隆過濾器

數(shù)據(jù)一致性問題

我們通常說的數(shù)據(jù)一致性指的是在程序運(yùn)行過程中本地緩存、分布式緩存、mysql數(shù)據(jù)庫三者之間的數(shù)據(jù)一致性

本地緩存與DB保持一致

解決方案

MQ 方案

  • 應(yīng)用實(shí)例1收到請(qǐng)求,更新 db,同時(shí)更新應(yīng)用自己的本地緩存.
  • 應(yīng)用實(shí)例1 發(fā)送更新 mq 廣播消息.
  • 應(yīng)用 實(shí)例2 和應(yīng)用實(shí)例3 收到消息,查詢 db,更新本地緩存.
  • 這個(gè)時(shí)候應(yīng)用實(shí)例1,2,3與 DB 數(shù)據(jù)就保持一致

Redis與DB保持一致

基于 binlog 方案

  • 更新 db 數(shù)據(jù)
  • 監(jiān)聽 mysql binlog, 并寫入到MQ
  • 啟動(dòng)一個(gè)數(shù)據(jù)處理應(yīng)用,消費(fèi) MQ 數(shù)據(jù)并進(jìn)行數(shù)據(jù)加工
  • 將加工后的數(shù)據(jù)寫入 redis
  • 查詢 redis 數(shù)據(jù)返回

延遲雙刪方案

先進(jìn)行緩存清除,再執(zhí)行 update sql,最后(延遲 N 秒)再執(zhí)行緩存清除。
上述中(延遲 N 秒)的時(shí)間要大于一次寫操作的時(shí)間,一般為 3-5 秒。

基于定時(shí)任務(wù)方案

1.更新 db 數(shù)據(jù),同時(shí)寫入數(shù)據(jù)到 redis
2.啟動(dòng)一個(gè)定時(shí)任務(wù)定時(shí)將 db 數(shù)據(jù)同步到 redis

熱key和大key問題

熱key

熱key是服務(wù)端的常見問題,指一段時(shí)間內(nèi)某個(gè)key的訪問量遠(yuǎn)遠(yuǎn)超過其他的key,導(dǎo)致大量訪問流量落在某一個(gè)redis實(shí)例中;或者是帶寬使用率集中在特定的key

以被請(qǐng)求頻率來定義是否是熱key,沒有固定經(jīng)驗(yàn)值。某個(gè)key被高頻訪問導(dǎo)致系統(tǒng)穩(wěn)定性變差,都可以定義為熱key。

可能造成的問題

  • 占用大量的CPU資源,影響其他請(qǐng)求并導(dǎo)致整體性能降低。
  • 集群架構(gòu)下,產(chǎn)生訪問傾斜,即某個(gè)數(shù)據(jù)分片被大量訪問,而其他數(shù)據(jù)分片處于空閑狀態(tài),可能引起該數(shù)據(jù)分片的連接數(shù)被耗盡,新的連接建立請(qǐng)求被拒絕等問題。
  • 在搶購或秒殺場景下,可能因商品對(duì)應(yīng)庫存Key的請(qǐng)求量過大,超出Redis處理能力造成超賣。
  • 熱Key的請(qǐng)求壓力數(shù)量超出Redis的承受能力易造成緩存擊穿,即大量請(qǐng)求將被直接指向后端的存儲(chǔ)層,導(dǎo)致存儲(chǔ)訪問量激增甚至宕機(jī),從而影響其他業(yè)務(wù)。

發(fā)現(xiàn)方法

開發(fā)獨(dú)立的熱 key 檢測系統(tǒng)

提供單獨(dú)的熱 key 檢測的接入 sdk,應(yīng)用系統(tǒng)引入該 sdk 后,熱 key 檢測系統(tǒng)自動(dòng)計(jì)
算是否熱 key 并推送相關(guān)結(jié)果給應(yīng)用系統(tǒng),應(yīng)用系統(tǒng)根據(jù)業(yè)務(wù)實(shí)際情況進(jìn)行相應(yīng)處理。

改寫 redis 客戶端收集上報(bào)數(shù)據(jù)

改寫 Redis SDK,記錄每個(gè)請(qǐng)求,定時(shí)把收集到的數(shù)據(jù)上報(bào),然后由一個(gè)統(tǒng)一的服務(wù)進(jìn)行聚合計(jì)算。

解決方案

利用本地緩存

在你發(fā)現(xiàn)熱 key 以后,把熱 key 加載到系統(tǒng)的內(nèi)存中。針對(duì)這種熱 key 請(qǐng)求,會(huì)直接從內(nèi)存中取,而不會(huì)走到 redis 層。

  • 優(yōu)點(diǎn):內(nèi)存訪問和 redis 訪問的速度不在一個(gè)量級(jí),基于本地緩存,接口性能非常好, 可以
    大大增加單實(shí)例的 QPS。
  • 缺點(diǎn):受應(yīng)用內(nèi)存限制,容量有限,數(shù)據(jù)量非常大的時(shí)候,占用太多內(nèi)存,不太適合。部分熱點(diǎn)數(shù)據(jù),需要提前預(yù)知。熱點(diǎn)數(shù)據(jù)自動(dòng)檢測有一定的延遲,系統(tǒng)短時(shí)間內(nèi)承受的風(fēng)險(xiǎn)比較大。

大key

大key是指當(dāng)redis的字符串類型占用內(nèi)存過大或非字符串類型元素?cái)?shù)量過多

生產(chǎn)環(huán)境中,綜合衡量運(yùn)維和環(huán)境的情況,給大key定義參考值如下:

  • string類型的key超過10KB
  • hash/set/zset/list等數(shù)據(jù)結(jié)構(gòu)中元素個(gè)數(shù)大于5k/整體占用內(nèi)存大于10MB

可能造成的問題

  • 客戶端執(zhí)行命令的時(shí)長變慢。
  • Redis內(nèi)存達(dá)到maxmemory參數(shù)定義的上限引發(fā)操作阻塞或重要的Key被逐出,甚至引發(fā)內(nèi)存溢出(Out Of Memory)。
  • 集群架構(gòu)下,某個(gè)數(shù)據(jù)分片的內(nèi)存使用率遠(yuǎn)超其他數(shù)據(jù)分片,無法使數(shù)據(jù)分片的內(nèi)存資源達(dá)到均衡。
  • 對(duì)大Key執(zhí)行讀請(qǐng)求,會(huì)使Redis實(shí)例的帶寬使用率被占滿,導(dǎo)致自身服務(wù)變慢,同時(shí)易波及相關(guān)的服務(wù)。
  • 對(duì)大Key執(zhí)行刪除操作,易造成主庫較長時(shí)間的阻塞,進(jìn)而可能引發(fā)同步中斷或主從切換。

發(fā)現(xiàn)方法

實(shí)時(shí)統(tǒng)計(jì)

我們可以通過在Redis 客戶端上實(shí)時(shí)統(tǒng)計(jì)出大Key,直接計(jì)算出Key對(duì)應(yīng)的Value值大小就可以,例如

// b 為序列化之后的數(shù)據(jù)
b, err := utils.Serialize(value, c.getSerializer())
if err != nil {
   return err
}
// var b []byte
// 長度
reqSize =  len(b)

// 10KB
bigKey := 1024 * 10
if reqSize > bigKey {
    
}
  • 優(yōu)點(diǎn):對(duì)性能幾乎無影響。
  • 缺點(diǎn):返回的Key序列化長度并不等同于它在內(nèi)存空間中的真實(shí)長度,因此不夠準(zhǔn)確,僅可作為參考。

離線全量Key分析

  • 對(duì)Redis的RDB備份文件進(jìn)行定制化的分析,幫助您發(fā)現(xiàn)實(shí)例中的大Key,掌握Key在內(nèi)存中的占用和分布

  • Redis提供了bigkeys參數(shù)能夠使redis-cli以遍歷的方式分析Redis實(shí)例中的所有Key,并返回Key的整體統(tǒng)計(jì)信息與每個(gè)數(shù)據(jù)類型中Top1的大Key,bigkeys僅能分析并輸入六種數(shù)據(jù)類型(STRING、LIST、HASH、SET、ZSET、STREAM),命令示例為redis-cli -h 127.0.0.1 -p 6379 --bigkeys

  • 優(yōu)點(diǎn):可對(duì)歷史備份數(shù)據(jù)進(jìn)行分析,對(duì)線上服務(wù)無影響。

  • 缺點(diǎn):時(shí)效性差,RDB文件較大時(shí)耗時(shí)較長。

解決方案

  • 業(yè)務(wù)拆分,將key的含義更細(xì)粒度化,避免大key出現(xiàn)。
  • 數(shù)據(jù)結(jié)構(gòu)上拆分。如果大key是個(gè)大json,可以通過mset的方式,將這個(gè)key的內(nèi)容打散到各個(gè)實(shí)例中,減小大key對(duì)數(shù)據(jù)量傾斜的影響;如果是大list,可以拆成list_1,list_2,list_N;其他數(shù)據(jù)結(jié)構(gòu)同理。(可以考慮增加單獨(dú)key存儲(chǔ)大key被拆分的個(gè)數(shù)或元數(shù)據(jù)信息)
  • 對(duì)于長文本,更建議使用文檔型數(shù)據(jù)庫例如MongoDB等。
  • 對(duì)一致性要求不高的場景,嘗試使用客戶端緩存。(只解決了redis的阻塞問題,但機(jī)器或局域網(wǎng)的帶寬問題沒有改善)
  • 對(duì)大key的壓縮。相當(dāng)于用cpu資源來降低網(wǎng)絡(luò)io,其中g(shù)oogle提出的snappy算法較常用。
  • 對(duì)于hash等數(shù)據(jù)結(jié)構(gòu),需要注意業(yè)務(wù)是否可以引入定期清理無效field的機(jī)制。
    • Hash 結(jié)構(gòu)不建議使用,沒有辦法對(duì)具體的Key做過期時(shí)間設(shè)置,只能再額外開發(fā)功能去做,增加開發(fā)成本

到此這篇關(guān)于一文了解發(fā)現(xiàn)并解決Redis熱key與大key問題的文章就介紹到這了,更多相關(guān)Redis熱key與大key內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

  • Redis源碼閱讀:Redis字符串SDS詳解

    Redis源碼閱讀:Redis字符串SDS詳解

    這篇文章主要介紹了Redis源碼閱讀:Redis字符串SDS,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Redis高可用的三種實(shí)現(xiàn)方式

    Redis高可用的三種實(shí)現(xiàn)方式

    在實(shí)際生產(chǎn)環(huán)境中為保證Redis的服務(wù)連續(xù)性和可靠性,需要設(shè)計(jì)一個(gè)高可用架構(gòu),本文就來介紹一下Redis高可用的三種實(shí)現(xiàn)方式,主要包括主從復(fù)制模式,Redis Sentinel模式和Redis Cluster模式,感興趣的可以了解一下
    2023-12-12
  • SpringBoot集成redis錯(cuò)誤問題及解決方法

    SpringBoot集成redis錯(cuò)誤問題及解決方法

    這篇文章主要介紹了SpringBoot集成redis錯(cuò)誤問題,本文給大家分享完美解決方法,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-02-02
  • 如何利用 Redis 實(shí)現(xiàn)接口頻次限制

    如何利用 Redis 實(shí)現(xiàn)接口頻次限制

    這篇文章主要介紹了如何利用 Redis 實(shí)現(xiàn)接口頻次限制,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-02-02
  • 一篇文章帶你徹底搞懂Redis?事務(wù)

    一篇文章帶你徹底搞懂Redis?事務(wù)

    這篇文章主要介紹了一篇文章帶你徹底搞懂Redis?事務(wù)的相關(guān)資料,需要的朋友可以參考下
    2022-10-10
  • Redis協(xié)議具體用法詳解

    Redis協(xié)議具體用法詳解

    在本篇文章中小編給大家整理了關(guān)于Redis協(xié)議具體用法以及相關(guān)內(nèi)容知識(shí)點(diǎn),需要的朋友們學(xué)習(xí)下。
    2019-06-06
  • springmvc集成使用redis過程

    springmvc集成使用redis過程

    這篇文章主要介紹了springmvc集成使用redis過程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • 關(guān)于Redis緩存問題及解決

    關(guān)于Redis緩存問題及解決

    這篇文章主要介紹了關(guān)于Redis緩存問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-03-03
  • redis分布式鎖之可重入鎖的實(shí)現(xiàn)代碼

    redis分布式鎖之可重入鎖的實(shí)現(xiàn)代碼

    相信大家都知道可重入鎖的作用防止在同一線程中多次獲取鎖而導(dǎo)致死鎖發(fā)生,本文通過幾個(gè)例子給大家分享redis分布式鎖之可重入鎖的實(shí)現(xiàn)代碼,對(duì)redis分布式鎖的相關(guān)知識(shí),感興趣的朋友一起看看吧
    2021-05-05
  • redis中修改配置文件中的端口號(hào) 密碼方法

    redis中修改配置文件中的端口號(hào) 密碼方法

    今天小編就為大家分享一篇redis中修改配置文件中的端口號(hào) 密碼方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-05-05

最新評(píng)論