在平常的工作和生活中我發現
絕大部分寫業務的程式設計師在實際開發中使用
redis的時候,只會
用
setvalue和getvalue兩個操作,
這是
對
redis
的
整體缺乏一個認知。
所
以
我來
對
redis常見
的
問題做一個總結,希望能夠
幫助
大家彌補知識
中的
盲點。
1、為什麼使用redis
在專案中使用
redis,主要是從效能和併發兩個角度去考慮。當然,redis還具備可以做分散式鎖等其他功能,但是如果只是為了分散式鎖這些其他功能,完全還有其他中介軟體(如zookpeer等)代替,並不是非要使用redis。因此,這個問題主要從效能和併發兩個角度去答。
(一)效能
如
下圖所示,我們在碰到需要執行耗時特別久,且結果不頻繁變動的
SQL,就特別適合將執行結果放入快取。
然後,
後面的請求就去快取中讀取,使得請求能夠迅速響應。
(二)併發
如下圖所示,在大併發的情況下,所有的請求直接訪問資料庫,資料庫會出現連線異常。這個時候,就需要使用
redis做一個緩衝操作,讓請求先訪問到redis,而不是直接訪問資料庫。
2、使用redis有什麼缺點
我們
用
了
redis這麼久,這個問題是必須要
知道
的,基本上使用
redis都會碰到一些問題,常見的也就幾個。
3
、
redis的資料型別,以及每種資料型別的使用場景
可能很多人
覺得這個問題很基礎,其實我也這麼覺得。
但是
根據
很多
面試經驗發現,至少百分八十的人答不上這個問題。建議,在專案中用到後,再類比記憶,體會更深,不要硬記。基本上,一個合格的程式設計師,
以下
五種型別都會用到。
4
、單執行緒的
redis為什麼這麼快
這個問題其實是對
redis內部機制的一個考察。其實很多人其實都不知道redis是單執行緒工作模型。所以,這個問題還是應該要複習一下的。
5
、如何解決
redis的併發競爭key問題
這個問題大致就是同時有多個子系統去
set一個key。這個時候要注意什麼呢?大家思考過麼。需要說明一下,
我
提前百度了一下,發現答案基本都是推薦用
redis事務機制。
我是
不推薦使用
redis的事務機制。因為我們的生產環境,基本都是redis叢集環境,做了資料分片操作。你一個事務中有涉及到多個key操作的時候,這多個key不一定都儲存在同一個redis-server上。因此,redis的事務機制,十分雞肋。
解決辦法:
(1)如果對這個key操作,不要求順序
這種情況下,準備一個分散式鎖,大家去搶鎖,搶到鎖就做
set操作即可,比較簡單。
(2)如果對這個key操作,要求順序
假設有一個
key1,系統A需要將key1設定為valueA,系統B需要將key1設定為valueB,系統C需要將key1設定為valueC。
期望按照
key1的value值按照 valueA——valueB——valueC的順序變化。這種時候我們在資料寫入資料庫的時候,需要儲存一個時間戳。假設時間戳如下
系統
A key 1 {valueA 3:00}
系統
B key 1 {valueB 3:05}
系統
C key 1 {valueC 3:10}
那麼,假設這會系統
B先搶到鎖,將key1設定為{valueB 3:05}。接下來系統A搶到鎖,發現自己的valueA的時間戳早於快取中的時間戳,那就不做set操作了。以此類推。
還有
其他方法,比如利用佇列,將
set方法變成序列訪問也可以。總之,靈活變通。
6
、
redis的過期策略以及記憶體淘汰機制
這個問題其實相當重要,到底
redis有沒用到家,這個問題就可以看出來。比如你redis只能存5G資料,可是你寫了10G,那會刪5G的資料。怎麼刪的,這個問題思考過麼?
redis採用的是定期刪除+惰性刪除策略
定期刪除,
redis預設每個100ms檢查,是否有過期的key,有過期key則刪除。需要說明的是,redis不是每個100ms將所有的key檢查一次,而是隨機抽取進行檢查。因此,如果只採用定期刪除策略,會導致很多key到時間沒有刪除。於是,惰性刪除派上用場。也就是說在你獲取某個key的時候,redis會檢查一下,這個key如果設定了過期時間那麼是否過期了?如果過期了此時就會刪除。
7、如何應對快取穿透和快取雪崩問題
這兩個問題,說句實在話,一般中小型傳統軟體企業,很難碰到這個問題。如果有大併發的專案,流量有幾百萬左右。這兩個問題一定要深刻考慮。
快取穿透,即駭客故意去請求快取中不存在的資料,導致所有的請求都懟到資料庫上,從而資料庫連線異常。
快取雪崩,即快取同一時間大面積的失效,這個時候又來了一波請求,結果請求都懟到資料庫上,從而導致資料庫連線異常。
8
、
redis和資料庫雙寫一致性問題
一致性問題是分散式常見問題,還可以再分為最終一致性和強一致性。資料庫和快取雙寫,就必然會存在不一致的問題。答這個問題,先明白一個前提。就是如果對資料有強一致性要求,不能放快取。我們所做的一切,只能保證最終一致性。另外,我們所做的方案其實從根本上來說,只能說降低不一致發生的機率,無法完全避免。因此,有強一致性要求的資料,不能放快取。首先,採取正確更新策略,先更新資料庫,再刪快取。其次,因為可能存在刪除快取失敗的問題,提供一個補償措施即可,例如利用訊息佇列。
總結:
本文對
redis的常見問題做了一個總結。大部分是
我
自己在工作中遇到
的
,以及以前面試別人的時候,愛問的一些問題。最後,希望大家
能從中
有所收穫吧。
為了幫助大家學習和理解掌握,我也有免費的影片教程教大家如何快速簡單的去學習,也有專門的裙供大家在裡面分享在學習和工作中的問題,裡面會有大佬幫忙解答。
後臺私信回覆“
資料
”就可以馬上免費獲得
和收藏