一起分析Redis快取一致性、快取穿透、快取擊穿及快取雪崩問題
這篇文章為大家帶來了關於Redis的相關知識,其中主要介紹了關於快取一致性、快取穿透、快取擊穿、快取雪崩以及快取資料的寫同步的與DB一致性的問題,下面一起來看一下,希望對大家有幫助。
(1)快取失效一致性問題
一般快取的使用方式是:先讀取緩存,若不存在則從DB中讀取,並將結果寫入到快取中;下次資料讀取時便可以直接從快取中取得資料。 【相關推薦:Redis影片教學】
資料的修改是直接失效快取數據,再修改DB內容,避免DB修改成功,但由於網路或其他問題導致快取資料沒有清理,造成了髒數據。但這仍然無法避免髒資料的產生,一種並發的場景下:假設業務對資料Key:Hello Value:World有大量的讀取和修改請求。線程A向OCS讀取Key:Hello,得到Not Found結果,開始向DB請求數據,得到數據Key:Hello Value:World;接下來準備向OCS寫入此條數據,但在寫入OCS前(網絡, CPU都等可能導致A線程處理速度降低)另一B線程請求修改數據Key:Hello Value:OCS,首先執行失效緩存動作(因為B線程並不知道是否有此條數據,因此直接執行失效操作), OCS成功處理了失效請求。轉回A執行緒繼續執行寫入OCS,將Key:Hello Value:World寫入到快取中,A執行緒任務結束;B執行緒也成功修改了DB資料內容為Key:Hello Value:OCS。為了解決這個問題,OCS擴充了Memcached協定(公有雲即將支援),增加了deleteAndIncVersion介面。此介面並不會真的刪除數據,而是給數據打了標籤,表示已失效狀態,並且增加數據版本號;如果數據不存在則寫入NULL,同時也產生隨機數據版本號。 OCS寫入支援原子對比版本號:假設傳入的版本號與OCS保存的資料版本號一致或原始資料不存在,則準許寫入,否則拒絕修改。
回到剛才的場景:線程A向OCS讀取Key:Hello,得到Not Found結果,開始向DB請求數據,得到數據Key:Hello Value:World;接下來準備向OCS寫入此條數據,版本號資訊預設為1;在A寫入OCS前另一個B線程發起了動作修改數據Key:Hello Value:OCS,首先執行刪除緩存動作,OCS順利處理了deleteAndIncVersion請求,生成了隨機版本號12345(約定大於1000)。轉回A執行緒繼續執行寫入OCS,請求將Key:Hello Value:World寫入,此時快取系統發現傳入的版本號資訊不符(1 != 12345),寫入失敗,A執行緒任務結束;B執行緒也成功修改了DB資料內容為Key:Hello Value:OCS。
此時OCS中的資料為Key:Hello Value:NULL Version:12345;DB中的資料為Key:Hello Value:OCS,後續讀取任務時會再次嘗試將DB中的資料寫入到OCS中。
(2)快取資料的寫入同步的與DB一致性問題
隨著網站規模成長和可靠性的提升,會面臨多IDC的部署,每個IDC都有一套獨立的DB和快取系統,這時快取一致性又成了突顯的問題。
首先快取系統為了確保高效率,會杜絕磁碟IO,即使是寫BINLOG;當然快取系統為了效能可以只同步刪除,不同步寫入,那麼快取的同步一般會優先於DB同步到達(畢竟快取系統的效率要高得多),那麼就會出現快取中無數據,DB中是舊數據的場景。此時,有業務請求數據,讀取快取Not Found,從DB讀取並加載到快取中的仍然是舊數據,DB數據同步到達時也只更新了DB,快取髒數據無法被清除。
從上面的情況可以看出,不一致的根本原因是異質系統之間無法協同同步,無法保證DB資料先同步,快取資料後同步。所以就要考慮快取系統如何等待DB同步,或是能否做到兩者共用一套同步機制?快取同步也依賴DB BINLOG是一個可行的方案。
IDC1中的DB,透過BINLOG同步給IDC2中的DB,此事IDC2-DB資料修改也會產生自身的BINLOG,快取的資料同步就可以透過IDC2-DB BINLOG進行。快取同步模組分析BINLOG後,失效對應的快取Key,同步從並行改為串行,確保了先後順序。
(3)快取穿透(DB承受了沒有必要的查詢流量)
方法一:是布隆過濾器。它是一種空間效率極高的機率型演算法和資料結構,用來判斷一個元素是否在集合中(類似Hashset)。它的核心是一個很長的二進位向量和一系列的hash函數。使用Google的guava實作布隆過濾器。 1)存在誤算率,隨著存入的元素數量增加,誤算率也隨著增加2)一般情況下不能從布隆過濾器刪除元素3)數組長度以及hash函數個數確定過程複雜,布隆過濾器的使用場景? 1)垃圾郵件位址過濾(位址數量很龐大)2)爬蟲URL位址去重3)解決快取擊穿問題
方法二:儲存空結果,並設定空結果的時間
(4)快取雪崩(快取設定同一過期時間,造成的DB洪峰)
#方法一:大多數系統設計者考慮用加鎖或佇列的方式保證快取的單執行緒(進程)寫,從而避免失效時大量的並發請求落在底層儲存系統上
方法二:失效時間隨機值
(5)快取擊穿(熱點Key,大量並發讀取請求引起的小雪崩)
快取在某個時間點過期的時候,恰好在這個時間點對這個Key有大量的並發請求過來,這些請求發現快取過期一般都會從後端DB載入資料並回設到緩存,這個時候大並發的請求可能會瞬間把後端DB壓垮
方法一:1.使用分散是緩存支援的互斥鎖(mutex key),去set一個mutex key,當操作返回成功時,再進行load db的操作並回設緩存,也就是load DB 只會一個線程處理。
方法二:提前"使用互斥鎖(mutex key):在value內部設定1個超時值(timeout1), timeout1比實際的memcache timeout(timeout2)小。當從cache讀取到timeout1發現它已經過期時候,馬上延長timeout1並重新設定到cache。然後再從資料庫載入資料並設定到cache。增加了業務程式碼的侵入過多,以及增加了編碼複雜性
方法三: 「永不過期」: 從redis上看,確實沒有設定過期時間,這就保證了,不會出現熱點key過期問題,也就是「物理」不過期。從功能上看,如果不過期,那不就成靜態的了嗎?所以我們把過期時間存在key對應的value裡,如果發現要過期了,通過一個後台的異步線程進行緩存的構建,也就是“邏輯”過期
(6)快取系統常見的快取滿了和資料遺失問題
需要根據特定業務分析,通常我們採用LRU策略處理溢出,Redis的RDB和AOF持久化策略來保證一定情況下的資料安全。
更多程式相關知識,請造訪:程式設計影片!!
以上是一起分析Redis快取一致性、快取穿透、快取擊穿及快取雪崩問題的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

Redis集群模式通過分片將Redis實例部署到多個服務器,提高可擴展性和可用性。搭建步驟如下:創建奇數個Redis實例,端口不同;創建3個sentinel實例,監控Redis實例並進行故障轉移;配置sentinel配置文件,添加監控Redis實例信息和故障轉移設置;配置Redis實例配置文件,啟用集群模式並指定集群信息文件路徑;創建nodes.conf文件,包含各Redis實例的信息;啟動集群,執行create命令創建集群並指定副本數量;登錄集群執行CLUSTER INFO命令驗證集群狀態;使

如何清空 Redis 數據:使用 FLUSHALL 命令清除所有鍵值。使用 FLUSHDB 命令清除當前選定數據庫的鍵值。使用 SELECT 切換數據庫,再使用 FLUSHDB 清除多個數據庫。使用 DEL 命令刪除特定鍵。使用 redis-cli 工具清空數據。

要從 Redis 讀取隊列,需要獲取隊列名稱、使用 LPOP 命令讀取元素,並處理空隊列。具體步驟如下:獲取隊列名稱:以 "queue:" 前綴命名,如 "queue:my-queue"。使用 LPOP 命令:從隊列頭部彈出元素並返回其值,如 LPOP queue:my-queue。處理空隊列:如果隊列為空,LPOP 返回 nil,可先檢查隊列是否存在再讀取元素。

在CentOS系統上,您可以通過修改Redis配置文件或使用Redis命令來限制Lua腳本的執行時間,從而防止惡意腳本佔用過多資源。方法一:修改Redis配置文件定位Redis配置文件:Redis配置文件通常位於/etc/redis/redis.conf。編輯配置文件:使用文本編輯器(例如vi或nano)打開配置文件:sudovi/etc/redis/redis.conf設置Lua腳本執行時間限制:在配置文件中添加或修改以下行,設置Lua腳本的最大執行時間(單位:毫秒)

使用 Redis 命令行工具 (redis-cli) 可通過以下步驟管理和操作 Redis:連接到服務器,指定地址和端口。使用命令名稱和參數向服務器發送命令。使用 HELP 命令查看特定命令的幫助信息。使用 QUIT 命令退出命令行工具。

Redis計數器是一種使用Redis鍵值對存儲來實現計數操作的機制,包含以下步驟:創建計數器鍵、增加計數、減少計數、重置計數和獲取計數。 Redis計數器的優勢包括速度快、高並發、持久性和簡單易用。它可用於用戶訪問計數、實時指標跟踪、遊戲分數和排名以及訂單處理計數等場景。

Redis數據過期策略有兩種:定期刪除:定期掃描刪除過期鍵,可通過 expired-time-cap-remove-count、expired-time-cap-remove-delay 參數設置。惰性刪除:僅在讀取或寫入鍵時檢查刪除過期鍵,可通過 lazyfree-lazy-eviction、lazyfree-lazy-expire、lazyfree-lazy-user-del 參數設置。

在Debian系統中,readdir系統調用用於讀取目錄內容。如果其性能表現不佳,可嘗試以下優化策略:精簡目錄文件數量:盡可能將大型目錄拆分成多個小型目錄,降低每次readdir調用處理的項目數量。啟用目錄內容緩存:構建緩存機制,定期或在目錄內容變更時更新緩存,減少對readdir的頻繁調用。內存緩存(如Memcached或Redis)或本地緩存(如文件或數據庫)均可考慮。採用高效數據結構:如果自行實現目錄遍歷,選擇更高效的數據結構(例如哈希表而非線性搜索)存儲和訪問目錄信
