高並發下千萬數據量的Mysql中熱點數據如何持續保留在Redis中

數據智能相依偎 2024-05-31 10:09:05

在高並發下,爲了增加系統的並發能力通常都會使用緩存技術來緩存熱點數據,目的是防止大量的請求打到Mysql上導致Mysql被打垮而崩潰。

假設現在Mysql中千萬條數據量並且有幾十萬條是熱點數據,那麽如何實現Redis中始終存儲的都是熱點數據呢?

在介紹Redis如何持久保留熱點數據之前先說兩種算法:LRU和LFU

1、LRU和LFU算法

LRU:最近最少使用,是一種常用的頁面置換算法,選擇最近最久未使用的頁面予以淘汰。

LFU:最近最不經常使用,選擇最近使用次數最少的頁面予以淘汰。對于每個節點,都需要維護其使用次數count、最近使用時間time。

針對這兩種算法,使用圖形演示其保留數據的不同點。

如果隊列使用的是LRU算法保留數據

(1)訪問數據後的隊列數據效果

如果現在是訪問了數據3,那麽隊列中3數據將會在頭節點的位置,如下圖所示:

(2)添加數據後隊列中的數據效果

現在如果有新的數據5添加到隊列中,此時隊列的頭節點是5,尾節點上將數據4移出,如下圖所示:

如果隊列使用的是LFU算法保留數據,結構如下:

(1)訪問數據後的效果

假設現在訪問數據2,那麽訪問之後數據2的次數增加1並且更新最近使用的時間。效果如下:

(2)添加數據

假設現在添加一個數據5,那麽添加數據後的效果如下:

LFU刪除節點的策略是: 優先刪除使用次數Count最小的那個節點,因爲它最近最不經常使用所以刪除它。如果使用次數相同並且節點有多個,那麽在這些節點中刪除最近使用時間time最早的那個節點。

2、Redis中熱點數據持久保留的方案

Redis的數據是存儲在內存中,這也就意味著Redis的內存是有限的。爲了解決內存不足的問題,Redis提供了多種數據的淘汰策略,以下是Redis的內存淘汰策略的整理:

淘汰策略

描述

noeviction

當內存不足時,禁止淘汰數據,寫入操作報錯。這是 Redis 默認的內存淘汰策略。

allkeys-random

當內存不足時,從所有的 key 中,隨機選出數據進行淘汰

volatile-random

當內存不足時,從設置了過期時間的 key 中,隨機選出數據進行淘汰

volatile-ttl

當內存不足時,從設置了過期時間的 key 中,選出即將過期的數據(按照過期時間的先後,選出最先過期的數據)進行淘汰

allkeys-lru

當內存不足時,從所有 key 中使用 LRU 算法,選出最近使用最少的數據進行淘汰

volatile-lfu

當內存不足時,從設置了過期時間的 key 中使用 LFU 算法,選出使用頻率最低的數據進行淘汰

allkeys-lfu

當內存不足時,從所有 key 中使用 LFU 算法,選出使用頻率最低的數據,進行淘汰

volatile-lru

當內存不足時,從設置了過期時間的 key 中使用 LRU 算法,選出最近使用最少的數據進行淘汰

在高並發場景下緩存熱點數據一般都是采用LRU或者LFU方案實現,因爲其他方案對熱點數據不友好。

如果采用Reids的LRU方式緩存熱點數據,那麽會將最近在redis中沒有的數據緩存起來,如果空間的不足的情況下會移出隊列中最近未訪問的數據,如下圖所示:

但是本方案存在一個很嚴重的問題,假設數據4使用了1萬次,其他的數據只使用了一次,那麽對應的先後使用時間上的關系如下:

此時將數據4移除就不適合了,因爲它是使用次數最高的,只是最近時間沒有被訪問,極端的情況下可能因爲大量請求來訪問數據4,此時數據4在Redis中剛好被移除,那麽請求將會都打到Mysql上進而導致Mysql被打垮

如果Redis中采用LFU算法緩存熱點,那麽內存不足的情況下會清理到最近不常用的數據,然後存儲熱點數據:

此方案存儲熱點數據比LRU方式更加合理,因爲它只會清理那些不常用的數據,針對高並發下緩存大批量的熱點數據建議采用這種LFU的方式。

那麽Redis提供了volatile-lfu、allkeys-lfu,具體使用哪種需要根據實際的業務來選擇。Redis中的配置淘汰策略如下:

#redis.conf 配置策略maxmemory-policy allkeys-lfu/volatile-lfu#指定redis使用使用的內存大小maxmemory 1024

總結:在高並發且熱點數據量很大的情況下,建議使用Redis的lfu方式淘汰數據,因爲此方式更加科學合理。在某些熱點數據訪問量一樣的,那麽在淘汰數據的時候依據時間來淘汰,極端情況下被清理掉的熱點數據下一時刻被大量訪問,此時要做一下系統的保護(最簡單的是加鎖訪問數據庫)。

0 阅读:6

數據智能相依偎

簡介:感謝大家的關注