太牛了,值得收藏!7000字22张图,精讲 Redis 知识!
今天我們來分享 Redis 相關(guān)的知識,文章有點(diǎn)長,一定要看到最后呦!
前言
Redis 在當(dāng)今的計(jì)算機(jī)行業(yè),可以說是使用的最為廣泛的內(nèi)存數(shù)據(jù)庫,幾乎所有的后端技術(shù)面試都會涉及到 Redis 相關(guān)的知識,正所謂知己知彼,百戰(zhàn)百勝。今天咱們就來盤一盤 Redis,從基礎(chǔ)面試題到各種特性、功能,做一次一網(wǎng)打盡式的服務(wù)!
什么是 Redis
Redis 是用 C 語言開發(fā)的一個開源的高性能鍵值對(key-value)數(shù)據(jù)庫。通常建議在 Linux 上運(yùn)行,它通過提供多種鍵值數(shù)據(jù)類型來適應(yīng)不同場景下的存儲需求,數(shù)據(jù)存儲在內(nèi)存中,也可持久化到磁盤中,目前為止 Redis 支持的鍵值數(shù)據(jù)類型如下:
字符串類型
散列類型
列表類型
集合類型
有序集合類型
Redis 特色
Redis 是用 C 語言寫的開源項(xiàng)目,又由于數(shù)據(jù)都在內(nèi)存中,所以讀寫速度非常快
Redis 所有數(shù)據(jù)保存在內(nèi)存中,對數(shù)據(jù)的更新會異步地保存到磁盤上,這樣可以做到斷電不丟失數(shù)據(jù)
Redis 主從復(fù)制可以實(shí)現(xiàn)高可用和分布式
Redis 數(shù)據(jù)結(jié)構(gòu)
字符串
String 是 Redis 當(dāng)中最為基本的數(shù)據(jù)類型,最大512M,是二進(jìn)制安全的
Redis 的字符串是動態(tài)字符串,是可以修改的,內(nèi)部結(jié)構(gòu)實(shí)現(xiàn)上類似于 Java 的 ArrayList,采用預(yù)分配冗余空間的方式來減少內(nèi)存的頻繁分配,內(nèi)存為當(dāng)前字符串實(shí)際分配的空間,一般要高于實(shí)際字符串長度。當(dāng)字符串長度小于 1M 時(shí),擴(kuò)容都是加倍現(xiàn)有的空間,如果超過 1M,擴(kuò)容時(shí)一次只會多擴(kuò) 1M 的空間
使用場景:記錄用戶頁面訪問量、緩存基本數(shù)據(jù)、分布式 Id 生成器
散列
Redis 當(dāng)中的 Hash 相當(dāng)于 Java 的 HashMap,無序字典,內(nèi)部實(shí)現(xiàn)是用數(shù)組+鏈表,第一維的數(shù)組出現(xiàn)碰撞,則存到鏈表里面去。Rehash 的時(shí)候,為了不阻塞服務(wù),采用的是漸進(jìn)式的 Rehash,保留2個 Hash,逐漸在指令執(zhí)行或者定時(shí)任務(wù)中,將數(shù)據(jù)從老的 Hash 遷移到新的 Hash
使用場景:購物車、頻繁變化的屬性
列表
Redis 的列表按照插入順序排序,相當(dāng)于 Java 語言里面的 LinkedList,注意它是鏈表而不是數(shù)組。這意味著 list 的插入和刪除操作非???#xff0c;時(shí)間復(fù)雜度為 O(1),但是索引定位很慢,時(shí)間復(fù)雜度為O(n)。當(dāng)列表彈出了最后一個元素之后,該數(shù)據(jù)結(jié)構(gòu)自動被刪除,內(nèi)存被回收
Redis 的列表結(jié)構(gòu)常用來做異步隊(duì)列使用,將需要延后處理的任務(wù)結(jié)構(gòu)體序列化成字符串塞進(jìn) Redis 的列表,另一個線程從這個列表中輪詢數(shù)據(jù)進(jìn)行處理
列表不同進(jìn)出棧的方式,產(chǎn)生的不同數(shù)據(jù)結(jié)構(gòu)
LPUSH+LPOP = 棧
LPUSH+RPOP = 隊(duì)列
LPUSH+ LTRIM = 固定數(shù)量的列表
LPUSH +BRPOP = 消息隊(duì)列
使用場景:異步隊(duì)列
無序集合
set 相當(dāng)于 Java 的 HashSet,無序的鍵值對,不過其值都是NULL,鍵不可以重復(fù)。數(shù)據(jù)量較少且是整數(shù)的時(shí)候用有序數(shù)組,較大的時(shí)候采用散列表
應(yīng)用場景:標(biāo)簽、社交、隨機(jī)數(shù)
有序集合
zset 可能是 Redis 提供的最為特色的數(shù)據(jù)結(jié)構(gòu),它類似于 Java 的 SortedSet 和 HashMap 的結(jié)合體,一方面它是一個 set,保證了內(nèi)部 value 的唯一性,另一方面它可以給每個 value 賦予一個 score,代表這個 value 的排序權(quán)重。
它的內(nèi)部實(shí)現(xiàn)用的是一種叫「跳躍列表」的數(shù)據(jù)結(jié)構(gòu),之所以「跳躍」,是因?yàn)閮?nèi)部的元素可能「身兼數(shù)職」
一個元素,同時(shí)處于 L0、L1 和 L2 層,可以快速在不同層次之間進(jìn)行「跳躍」,定位插入點(diǎn)時(shí),先在頂層進(jìn)行定位,然后下潛到下一級定位,一直下潛到最底層找到合適的位置,將新元素插進(jìn)去
應(yīng)用場景:value 為粉絲 ID,score 是關(guān)注時(shí)間,可以按照關(guān)注時(shí)間順序給出粉絲 ID;value 是學(xué)生 ID,score 是其分?jǐn)?shù),可以按照分?jǐn)?shù)排序
Redis 持久化
Redis 提供了兩種持久化的方式,分別是RDB(Redis DataBase)和AOF(Append Only File)
RDB,簡而言之,就是在不同的時(shí)間點(diǎn),將 Redis 存儲的數(shù)據(jù)生成快照并存儲到磁盤等介質(zhì)上
AOF,則是換了一個角度來實(shí)現(xiàn)持久化,那就是將 Redis 執(zhí)行過的所有寫指令記錄下來,在下次 Redis 重新啟動時(shí),只要把這些寫指令從前到后再重復(fù)執(zhí)行一遍,就可以實(shí)現(xiàn)數(shù)據(jù)恢復(fù)了
其實(shí) RDB 和 AOF 兩種方式也可以同時(shí)使用,在這種情況下,如果 Redis 重啟的話,則會優(yōu)先采用 AOF 方式來進(jìn)行數(shù)據(jù)恢復(fù),這是因?yàn)?AOF 方式的數(shù)據(jù)恢復(fù)完整度更高
AOF 有一個配置屬性 sync,就是用來同步命令到磁盤的,如果我們對于 Redis 的性能要求不高,則可以在每條寫指令時(shí)都 sync 一下磁盤,這樣即使在突然斷電的情況下,也能保證數(shù)據(jù)的最小丟失率
RDB
RDB 是將 Redis 某一時(shí)刻的數(shù)據(jù)持久化到磁盤中,是一種快照式的持久化方法
Redis 在進(jìn)行數(shù)據(jù)持久化的過程中,會先將數(shù)據(jù)寫入到一個臨時(shí)文件中,待持久化過程都結(jié)束了,才會用這個臨時(shí)文件替換上次持久化好的文件。正是這種特性,讓我們可以隨時(shí)來進(jìn)行備份,因?yàn)榭煺瘴募偸峭暾捎玫?/p>
對于 RDB 方式,Redis 會單獨(dú)創(chuàng)建(fork)一個子進(jìn)程來進(jìn)行持久化,而主進(jìn)程是不會進(jìn)行任何 IO 操作的,這樣就確保了 Redis 極高的性能,子進(jìn)程創(chuàng)建后,父子進(jìn)程共享數(shù)據(jù)段,父進(jìn)程繼續(xù)提供讀寫服務(wù),寫臟的頁面數(shù)據(jù)會逐漸和子進(jìn)程分離開來
如果需要進(jìn)行大規(guī)模數(shù)據(jù)的恢復(fù),且對于數(shù)據(jù)恢復(fù)的完整性不是非常敏感,那 RDB 方式要比 AOF 方式更加的高效
AOF
AOF,英文是 Append Only File,即只允許追加不允許改寫的文件
如前面介紹的,AOF 方式是將執(zhí)行過的寫指令記錄下來,在數(shù)據(jù)恢復(fù)時(shí)按照從前到后的順序再將指令都執(zhí)行一遍,就這么簡單
默認(rèn)的 AOF 持久化策略是每秒鐘 fsync 一次(fsync是指把緩存中的寫指令記錄到磁盤中),因?yàn)樵谶@種情況下,Redis 仍然可以保持很好的處理性能,即使 Redis 故障,也只會丟失最近1秒鐘的數(shù)據(jù)
RDB 與 AOF 比較
Redis 主從
Redis 是支持主從同步的,而且也支持一主多從以及多級從結(jié)構(gòu)
主從結(jié)構(gòu),一是為了純粹的冗余備份,二是為了提升讀性能,比如很消耗性能的 sort 就可以由從服務(wù)器來承擔(dān)
Redis 的主從同步是異步進(jìn)行的,這意味著主從同步不會影響主邏輯,也不會降低 Redis 的處理性能
主從架構(gòu)中,可以考慮關(guān)閉主服務(wù)器的數(shù)據(jù)持久化功能,只讓從服務(wù)器進(jìn)行持久化,這樣可以提高主服務(wù)器的處理性能
在主從架構(gòu)中,從服務(wù)器通常被設(shè)置為只讀模式,這樣可以避免從服務(wù)器的數(shù)據(jù)被誤修改。但是從服務(wù)器仍然可以接受 CONFIG 等指令,所以還是不應(yīng)該將從服務(wù)器直接暴露到不安全的網(wǎng)絡(luò)環(huán)境中
舊版復(fù)制功能
Redis 的復(fù)制功能分為同步(sync)和命令傳播(command propagate)兩個操作:
同步操作用于將從服務(wù)器的數(shù)據(jù)庫狀態(tài)更新至主服務(wù)器當(dāng)前所處的數(shù)據(jù)庫狀態(tài)
命令傳播操作則用于在主服務(wù)器的數(shù)據(jù)庫狀態(tài)被修改,導(dǎo)致主從服務(wù)器的數(shù)據(jù)庫狀態(tài)出現(xiàn)不一致時(shí),讓主從服務(wù)器的數(shù)據(jù)庫重新回到一致狀態(tài)
同步過程
當(dāng)客戶端向從服務(wù)器發(fā)送 SLAVEOF 命令,要求從服務(wù)器復(fù)制主服務(wù)器時(shí),從服務(wù)器首先需要執(zhí)行同步操作,也就是將從服務(wù)器的數(shù)據(jù)庫狀態(tài)更新至主服務(wù)器當(dāng)前所處的數(shù)據(jù)庫狀態(tài)
從服務(wù)器對主服務(wù)器的同步操作需要通過向主服務(wù)器發(fā)送 SYNC 命令來完成,以下是 SYNC 命令的執(zhí)行步驟:
1)從服務(wù)器向主服務(wù)器發(fā)送 SYNC 命令
2)收到 SYNC 命令的主服務(wù)器執(zhí)行 BGSAVE 命令,在后臺生成一個 RDB 文件,并使用一個緩沖區(qū)記錄從現(xiàn)在開始執(zhí)行的所有寫命令
3)當(dāng)主服務(wù)器的 BGSAVE 命令執(zhí)行完畢時(shí),主服務(wù)器會將 BGSAVE 命令生成的 RDB 文件發(fā)送給從服務(wù)器,從服務(wù)器接收并載入這個 RDB 文件,將自己的數(shù)據(jù)庫狀態(tài)更新至主服務(wù)器執(zhí)行 BGSAVE 命令時(shí)的數(shù)據(jù)庫狀態(tài)
4)主服務(wù)器將記錄在緩沖區(qū)里面的所有寫命令發(fā)送給從服務(wù)器,從服務(wù)器執(zhí)行這些寫命令,將自己的數(shù)據(jù)庫狀態(tài)更新至主服務(wù)器數(shù)據(jù)庫當(dāng)前所處的狀態(tài)
缺點(diǎn)
這種復(fù)制功能,雖然可以很好的完成主備之間的數(shù)據(jù)同步,但是效率確實(shí)非常低的
每次執(zhí)行 SYNC 命令,主從服務(wù)器需要執(zhí)行以下動作:
1)主服務(wù)器需要執(zhí)行 BGSAVE 命令來生成 RDB 文件,這個生成操作會耗費(fèi)主服務(wù)器大量的 CPU、內(nèi)存和磁盤 I/O 資源
2)主服務(wù)器需要將自己生成的 RDB 文件發(fā)送給從服務(wù)器,這個發(fā)送操作會耗費(fèi)主從服務(wù)器大量的網(wǎng)絡(luò)資源(帶寬和流量),并對主服務(wù)器響應(yīng)命令請求的時(shí)間產(chǎn)生影響
3)接收到 RDB 文件的從服務(wù)器需要載入主服務(wù)器發(fā)來的 RDB文件,并且在載入期間,從服務(wù)器會因?yàn)樽枞鴽]辦法處理命令請求
4)BGSAVE 命令產(chǎn)生的 RDB 文件是主服務(wù)器鎖包含的所有數(shù)據(jù),這是一個全量過程
因?yàn)?SYNC 命令是一個如此耗費(fèi)資源的操作,所以 Redis 有必要 保證在真正有需要時(shí)才執(zhí)行 SYNC 命令
新版復(fù)制功能
為了解決舊版本復(fù)制功能的低效問題,Redis 從2.8版本開始,使用 PSYNC 命令代替 SYNC 命令來執(zhí)行復(fù)制時(shí)的同步操作
PSYNC 命令具有完整重同步(full resynchronization)和部分重同步(partial resynchronization)兩種模式:
完整重同步用于處理初次復(fù)制情況:完整重同步的執(zhí)行步驟SYN命令的執(zhí)行步驟基本一樣,它們都是通過讓主服務(wù)器創(chuàng)建并發(fā)RD文件,以及向從服務(wù)器發(fā)送保存在緩沖區(qū)里面的寫命令來進(jìn)行同步
部分重同步則用于處理斷線后重復(fù)制情況:當(dāng)從服務(wù)器在斷線后重新連接主服務(wù)器時(shí),如果條件允許,主服務(wù)器可以將主從服務(wù)器連接斷開期間執(zhí)行的寫命令發(fā)送給從服務(wù)器,從服務(wù)器只要接收并執(zhí)行這些寫命令,就可以將數(shù)據(jù)庫更新至主服務(wù)器當(dāng)前所處的狀態(tài)
PSYNC 命令的部分重同步模式解決了舊版復(fù)制功能在處理斷線后 重復(fù)制時(shí)出現(xiàn)的低效情況,即采用增量同步的形式,大大節(jié)省了服務(wù)器資源
哨兵與集群
Redis Sentinal 主要用于高可用,在 master 宕機(jī)時(shí)會自動將 slave 提升為 master,繼續(xù)提供服務(wù)
Redis Cluster 則側(cè)重于擴(kuò)展性,在單個 Redis 內(nèi)存不足時(shí),使用 Cluster 進(jìn)行分片存儲
Redis Sentinal
Sentinel(哨崗、哨兵)是 Redis 的高可用性(high availability)解決方案:由一個或多個 Sentinel 實(shí)例組成的 Sentinel 系統(tǒng)可以監(jiān)視任意多個主服務(wù)器,以及這些主服務(wù)器屬下的所有從服務(wù)器,并在被監(jiān)視的主服務(wù)器進(jìn)入下線狀態(tài)時(shí),自動將下線主服務(wù)器屬下的某個從服務(wù)器升級為新的主服務(wù)器,然后由新的主服務(wù)器代替已下線的主服務(wù)器繼續(xù)處理命令請求
初始狀態(tài)下,Server1 為主服務(wù)器,其余為從服務(wù)器
假設(shè)這時(shí),主服務(wù)器 Server1 進(jìn)入下線狀態(tài),那么從服務(wù)器 Server2、Server3、Server4 對主服務(wù)器的復(fù)制操作將被中止,并且 Sentinel 系統(tǒng)會察覺到 Server1 已下線
當(dāng) Server1 的下線時(shí)長超過用戶設(shè)定的下線時(shí)長上限時(shí),Sentinel 系統(tǒng)就會對 Server1 執(zhí)行故障轉(zhuǎn)移操作:
首先,Sentinel 系統(tǒng)會挑選 Server1 屬下的其中一個從服務(wù)器,并將這個被選中的從服務(wù)器升級為新的主服務(wù)器
之后,Sentinel 系統(tǒng)會向 Server1 屬下的所有從服務(wù)器發(fā)送新的復(fù)制指令,讓它們成為新的主服務(wù)器的從服務(wù)器,當(dāng)所有從服務(wù)器都開始復(fù)制新的主服務(wù)器時(shí),故障轉(zhuǎn)移操作執(zhí)行完畢
另外,Sentinel 還會繼續(xù)監(jiān)視已下線的 Server1,并在它重新上線時(shí),將它設(shè)置為新的主服務(wù)器的從服務(wù)器
選取新主
老主恢復(fù),降為從服務(wù)器
Redis Cluster
Redis 集群是 Redis 提供的分布式數(shù)據(jù)庫方案,集群通過分片(sharding)來進(jìn)行數(shù)據(jù)共享,并提供復(fù)制和故障轉(zhuǎn)移功能
Redis Cluser 采用虛擬槽分區(qū),所有的鍵根據(jù)哈希函數(shù)映射到0~16383整數(shù)槽內(nèi),計(jì)算公式:slot=CRC16(key)&16383
每一個節(jié)點(diǎn)負(fù)責(zé)維護(hù)一部分槽以及槽所映射的鍵值數(shù)據(jù)
Redis 虛擬槽分區(qū)解耦了數(shù)據(jù)與節(jié)點(diǎn)之間的關(guān)系,簡化了節(jié)點(diǎn)擴(kuò)容和收縮的難度
當(dāng)然 Redis 集群也有很多功能上的限制
1)key 批量操作支持有限。如 mset、mget,目前只支持具有相同 slot 值的 key 執(zhí)行批量操作。對于映射為不同 slot 值的 key 由于執(zhí)行 mget、mget 等操作可能存在于多個節(jié)點(diǎn)上因此不被支持
2)key 事務(wù)操作支持有限。同理只支持多 key 在同一節(jié)點(diǎn)上的事務(wù)操作,當(dāng)多個 key 分布在不同的節(jié)點(diǎn)上時(shí)無法使用事務(wù)功能
3)key 作為數(shù)據(jù)分區(qū)的最小粒度,因此不能將一個大的鍵值對象如 hash、list 等映射到不同的節(jié)點(diǎn)
4)不支持多數(shù)據(jù)庫空間。單機(jī)下的 Redis 可以支持16個數(shù)據(jù)庫,集群模式下只能使用一個數(shù)據(jù)庫空間,即db0
5)復(fù)制結(jié)構(gòu)只支持一層,從節(jié)點(diǎn)只能復(fù)制主節(jié)點(diǎn),不支持嵌套樹狀復(fù)制結(jié)構(gòu)
更新策略
緩存中的數(shù)據(jù)通常都是有生命周期的,需要在指定時(shí)間后被刪除或更 新,這樣可以保證緩存空間在一個可控的范圍。但是緩存中的數(shù)據(jù)會和數(shù)據(jù)源中的真實(shí)數(shù)據(jù)有一段時(shí)間窗口的不一致,需要利用某些策略進(jìn)行更新。
下面介紹 Redis 常用的三種緩存更新策略
LRU/LFU/FIFO 算法剔除
剔除算法通常用于緩存使用量超過了預(yù)設(shè)的最大值的時(shí)候,如何對現(xiàn)有的數(shù)據(jù)進(jìn)行剔除,例如使用 maxmemory-policy 這個配置作為內(nèi)存最大值后對于數(shù)據(jù)的剔除策略
超時(shí)刪除
超時(shí)剔除通過給緩存數(shù)據(jù)設(shè)置過期時(shí)間,讓其在過期時(shí)間后自動刪除,例如 Redis 提供的 expire 命令。如果業(yè)務(wù)可以容忍一段時(shí)間內(nèi),緩存層數(shù)據(jù)和存儲層數(shù)據(jù)不一致,那么可以為其設(shè)置過期時(shí)間。在數(shù)據(jù)過期后,再從真實(shí)數(shù)據(jù)源獲取數(shù)據(jù),重新放到緩存并設(shè)置過期時(shí)間
主動更新
應(yīng)用方對于數(shù)據(jù)的一致性要求高,需要在真實(shí)數(shù)據(jù)更新后,立即更新緩存數(shù)據(jù)。例如可以利用消息系統(tǒng)或者其他方式通知緩存更新
更新策略對比
從上面的橫向?qū)Ρ葦?shù)據(jù),我們可以得出如下建議配置
低一致性業(yè)務(wù)建議配置最大內(nèi)存和淘汰策略的方式
高一致性業(yè)務(wù)可以結(jié)合使用超時(shí)剔除和主動更新,這樣即使主動更新出了問題,也能保證數(shù)據(jù)過期時(shí)間后刪除臟數(shù)據(jù)
Redis 緩存雪崩、擊穿和穿透
這是三個 Redis 最為常見的三個問題,我們逐一來了解下
1.雪崩
什么是雪崩
由于緩存層承載著大量請求,有效地保護(hù)了存儲層,但是如果緩存層由于某些原因不能提供服務(wù),于是所有的請求都會達(dá)到存儲層,存儲層的調(diào)用量會暴增,造成存儲層也會級聯(lián)宕機(jī)的情況
預(yù)防和解決辦法
保證緩存層服務(wù)高可用性
出現(xiàn)服務(wù)不可用的情況,我們第一時(shí)間想到的肯定是高可用,甚至是異地容災(zāi)等機(jī)制
依賴隔離組件為后端限流并降級
無論是緩存層還是存儲層都會有出錯的概率,可以將它們視同為資源。作為并發(fā)量較大的系統(tǒng),假如有一個資源不可用,可能會造成線程全部阻塞(hang)在這個資源上,造成整個系統(tǒng)不可用。降級機(jī)制在高并發(fā)系統(tǒng)中是非常普遍的:比如推薦服務(wù)中,如果個性化推薦服務(wù)不可用,可以降級補(bǔ)充熱點(diǎn)數(shù)據(jù),不至于造成前端頁面開天窗
數(shù)據(jù)預(yù)熱
針對大量緩存同時(shí)過期的情況,可以通過緩存 reload 機(jī)制,預(yù)選去更新緩存,在即將發(fā)生大并發(fā)訪問前手動觸發(fā)加載緩存不同的 key,設(shè)置不同的過期時(shí)間,讓緩存失效的時(shí)間點(diǎn)盡量均勻
2.擊穿
如果緩存中的某個熱點(diǎn)數(shù)據(jù)過期了,此時(shí)大量的請求訪問了該熱點(diǎn)數(shù)據(jù),就無法從緩存中讀取,直接訪問數(shù)據(jù)庫,數(shù)據(jù)庫很容易就被高并發(fā)的請求沖垮,這就是緩存擊穿的問題
擊穿其實(shí)可以看做是雪崩的一個子集,解決方法一般有兩種,設(shè)置熱點(diǎn)數(shù)據(jù)永不過期和設(shè)置互斥鎖
所謂的互斥鎖,就是保證同一時(shí)間只有一個業(yè)務(wù)線程更新緩存,對于沒有獲取互斥鎖的請求,要么等待鎖釋放后重新讀取緩存,要么就返回空值或者默認(rèn)值
3.穿透
緩存穿透是指查詢一個根本不存在的數(shù)據(jù),緩存層和存儲層都不會命 中,導(dǎo)致請求在訪問緩存時(shí),發(fā)現(xiàn)緩存缺失,再去訪問數(shù)據(jù)庫時(shí),發(fā)現(xiàn)數(shù)據(jù)庫中也沒有要訪問的數(shù)據(jù),沒辦法構(gòu)建緩存數(shù)據(jù),來服務(wù)后續(xù)的請求。那么當(dāng)有大量這樣的請求到來時(shí),數(shù)據(jù)庫的壓力驟增,產(chǎn)生穿透問題
緩存穿透問題可能會使后端存儲負(fù)載加大,由于很多后端存儲不具備高 并發(fā)性,甚至可能造成后端存儲宕掉
解決方案
緩存空對象
當(dāng)存儲層不命中后,仍然將空對象保留到緩存層中,之后再訪問這個數(shù)據(jù)將會從緩存中獲取,這樣就保護(hù)了后端數(shù)據(jù)源
當(dāng)然緩存空對象會有兩個問題:
第一,空值做了緩存,意味著緩存層中存了更多的鍵,需要更多的內(nèi)存空間(如果是攻擊,問題更嚴(yán)重),比較有效的方法是針對這類數(shù)據(jù)設(shè)置一個較短的過期時(shí)間,讓其自動剔除
第二,緩存層和存儲層的數(shù)據(jù)會有一段時(shí)間窗口的不一致,可能會對業(yè)務(wù)有一定影響。例如過期時(shí)間設(shè)置為5分鐘,如果此時(shí)存儲層添加了這個數(shù)據(jù),那此段時(shí)間就會出現(xiàn)緩存層和存儲層數(shù)據(jù)的不一致,此時(shí)可以利用消息系統(tǒng)或者其他方式清除掉緩存層中的空對象
布隆過濾器攔截
在訪問緩存層和存儲層之前,將存在的 key 用布隆過濾器提前保存起來,做第一層攔截,即使發(fā)生了緩存穿透,大量請求只會查詢 Redis 和布隆過濾器,而不會查詢數(shù)據(jù)庫,保證了數(shù)據(jù)庫能正常運(yùn)行
這種方法適用于數(shù)據(jù)命中不高、數(shù)據(jù)相對固定、實(shí)時(shí)性低(通常是數(shù)據(jù) 集較大)的應(yīng)用場景,代碼維護(hù)較為復(fù)雜,但是緩存空間占用少
緩存空對象與布隆過濾器比較
好了,redis的功能還是非常強(qiáng)大的,尤其是在一些秒殺的系統(tǒng)或者是需要高速訪問的地方,用mysql會比較慢,我們上次寫了一個簡單的小應(yīng)用,里面就用到redis.(女友想買個手機(jī)!我用Python做了個比價(jià)機(jī)器人了!)
這就是今天的內(nèi)容,如果你覺得對你有所幫助,就點(diǎn)贊+在看支持一下吧~
也歡迎大家關(guān)注我們的視頻號,里面有很多好玩的視頻。
推薦閱讀: 入門:?最全的零基礎(chǔ)學(xué)Python的問題? |?零基礎(chǔ)學(xué)了8個月的Python??|?實(shí)戰(zhàn)項(xiàng)目?|學(xué)Python就是這條捷徑 干貨:爬取豆瓣短評,電影《后來的我們》?|?38年NBA最佳球員分析?|? ?從萬眾期待到口碑撲街!唐探3令人失望? |?笑看新倚天屠龍記?|?燈謎答題王?|用Python做個海量小姐姐素描圖?|碟中諜這么火,我用機(jī)器學(xué)習(xí)做個迷你推薦系統(tǒng)電影 趣味:彈球游戲? |?九宮格? |?漂亮的花?|?兩百行Python《天天酷跑》游戲! AI:?會做詩的機(jī)器人?|?給圖片上色?|?預(yù)測收入?|?碟中諜這么火,我用機(jī)器學(xué)習(xí)做個迷你推薦系統(tǒng)電影 小工具:?Pdf轉(zhuǎn)Word,輕松搞定表格和水印!?|?一鍵把html網(wǎng)頁保存為pdf!|??再見PDF提取收費(fèi)!?|?用90行代碼打造最強(qiáng)PDF轉(zhuǎn)換器,word、PPT、excel、markdown、html一鍵轉(zhuǎn)換?|?制作一款釘釘?shù)蛢r(jià)機(jī)票提示器!?|60行代碼做了一個語音壁紙切換器天天看小姐姐!|年度爆款文案
1).臥槽!Pdf轉(zhuǎn)Word用Python輕松搞定!
2).學(xué)Python真香!我用100行代碼做了個網(wǎng)站,幫人PS旅行圖片,賺個雞腿吃
3).首播過億,火爆全網(wǎng),我分析了《乘風(fēng)破浪的姐姐》,發(fā)現(xiàn)了這些秘密?
4).80行代碼!用Python做一個哆來A夢分身?
5).你必須掌握的20個python代碼,短小精悍,用處無窮?
6).30個Python奇淫技巧集?
7).我總結(jié)的80頁《菜鳥學(xué)Python精選干貨.pdf》,都是干貨?
8).再見Python!我要學(xué)Go了!2500字深度分析!
9).發(fā)現(xiàn)一個舔狗福利!這個Python爬蟲神器太爽了,自動下載妹子圖片
點(diǎn)閱讀原文,看200個Python案例!
總結(jié)
以上是生活随笔為你收集整理的太牛了,值得收藏!7000字22张图,精讲 Redis 知识!的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 用Python执行SQL、Excel常见
- 下一篇: 全国计算机等级考试三级数据库知识点总结