redis是個大話題,只要是去面試j**a開發,幾乎必問。基礎一點的問redis是什麼東西?用來做什麼?redis支援哪些資料型別?redis的效能為什麼那麼好?複雜一點的就會問到快取穿透、快取擊穿、快取雪崩等問題。而我在面試的時候也被問到了redis為什麼用來做快取的問題。
所以我覺得很有必要總結一下redis作為快取使用,可能會引發的問題。以達到溫故而知新的效果
ps:在本文章中,就不討論redis能用來幹啥?這種基礎問題了
在討論redis作為快取使用,可能會引發的問題之前,我們得了解官方是怎麼定義redis
redis是乙個開源的記憶體中的資料結構儲存系統,它可以用作:資料庫、快取和訊息中介軟體。
它支援多種型別的資料結構,如字串(strings),雜湊(hash),列表(list),集合(set),有序集合(sorted set或者是zset)。
redis 內建了複製(replication),lua指令碼(lua scripting), lru驅動事件(lru eviction),事務(transactions) 和不同級別的磁碟持久化(persistence),並通過 redis哨兵(sentinel)和自動分割槽(cluster)提供高可用性(high **ailability)。
redis也提供了兩種持久化策略,這些策略可以讓使用者將自己的資料儲存到磁碟上面進行儲存。根據實際情況,可以每隔一定時間將資料集以快照的形式儲存在磁碟(rdb策略),或者將所有操作成功的命令追加到命令日誌中(aof策略),它會在執行命令時,將被執行的命令複製到硬碟裡面,實現實時持久化資料的效果。當然,根據實際開發的需求,你也可以關閉持久化功能,單純的將redis作為乙個高效的網路的快取資料功能使用。
redis由c語言開發,並且將資料儲存在記憶體中,可以說redis完全是基於記憶體進行操作,對資料讀寫的速度極快、效能極好。官方提供的資料是可以達到每秒100000+的吞吐量(每秒內查詢次數),如此優秀的機制使redis極其適合作為快取使用。
程式在處理快取時,一般是先從快取查詢,如果快取沒有這個key(理解為資料),則會從資料庫中查詢,並將查詢到的資料儲存到快取中去。
好,問題來了,如果有個壞心眼的人向伺服器發起請求,去查詢乙個一定不存在的資料,由於快取中沒有查到對應的資料時需要從資料庫查詢,查不到資料則不寫入快取,這將導致這個不存在的資料每次請求都要到資料庫去查詢,快取形同虛設,這就是
快取穿透。
解決方案:
1)最粗暴也是最常用的方法就是,如果乙個查詢的資料為空(不管是資料不存在還是系統故障),我們就把這個空結果進行快取,但要把它的過期時間設定得很短,最長不超過5分鐘,這樣能有效的解決快取穿透問題。
2)其次,可以採用布隆過濾器,也能解決快取穿透問題
快取擊穿和快取穿透在本質上很相似,都是查詢資料時快取失去了作用,導致請求直接去資料庫查詢資料,但是造成快取失效的原因卻是天差地別。
大量使用者在同一時間內訪問某熱點資料時,儲存在快取中的熱點資料卻突然失效(過期時間),結果就是大量的請求直接訪問資料庫,使資料庫的壓力變大,甚至導致資料庫宕機,這就是快取擊穿。
解決方案:比較常用的方法是加
互斥鎖(mutex)保證資料的
一致性。簡單地來說,就是在快取失效的時候(判斷拿出來的值為空),不是立即去訪問資料庫,而是先使用快取工具的某些帶成功操作返回值的操作(比如redis的setnx或者memcache的add)去set另乙個請求所需要的資料,當操作返回成功時,再進行訪問資料庫的操作並回設快取;否則,就重試整個get快取的方法。
如果快取的資料集中在一段時間內
大批失效,而不巧的是在這段時間內又有大量使用者發起請求訪問資料,這樣就會造成
大量的快取擊穿,所有的請求都會直接去訪問資料庫,導致資料庫在短時間內宕機,這就是快取雪崩。
ps:這裡我使用了誇張的修辭手法。快取雪崩不一定會造成資料庫宕機,但快取如果發生雪崩現象,那肯定是很嚴重的
解決方案:
1)加鎖排隊。加互斥鎖,新增資訊佇列
2)資料預熱。可以通過快取reload機制,預先去更新快取,再即將發生大併發訪問前手動觸發載入快取不同的key,設定不同的過期時間,讓快取失效的時間點盡量均勻
3)設定熱點快取永不過時
筆者: 以上問題及解決方案純粹個人見解,如果有錯誤的地方,還請指正
centos下安裝mysql可能會出現的報錯
報錯1 解決 the mysql server is running with the skip grant tables option so it cannot execute this statement 解決 flush privileges 報錯2 unknown system variab...
mac 安裝 swoole 可能會出現的錯誤
2018年4月,由於homebrew的變動,導致無法使用brew install的方式安裝php的擴充套件,現在改為用pecl安裝,pecl安裝swoole的方法為 pecl install swoole可能出現的報錯及解決方法解決方法1 cp r usr local opt openssl inc...
關於REDIS資料訪問可能會出現的一些問題
當我們把json資料作為value存入redis時,redis會自動的在每個 符號前加上 起到轉譯的作用,並且會對所有的中文字元重新編碼,我們通過工程呼叫redis中的資料,將其取出來,redis會自動將中文字元轉換為原來的編碼方式,同時也會去掉 符號前的 我們在工程中加入一行 在控制台列印出了取出...