首頁  >  文章  >  資料庫  >  為什麼都說redis很好用

為什麼都說redis很好用

王林
王林轉載
2021-03-03 09:36:231695瀏覽

為什麼都說redis很好用

前言:

相信對絕大多數程式設計師來說,redis中間件應該是大家非常熟悉的。但對於工作中常寫業務程式碼的程式設計師來說,他們在實際工作中可能只是用到了set value、get value等操作,對於redis缺乏整體認知。下面我就來為大家詳細介紹下redis。

Redis是什麼?

Redis是一個開源的底層使用C語言編寫的key-value儲存資料庫。可用於快取、事件發布訂閱、高速隊列等場景。而且支援豐富的資料類型:string(字串)、hash(哈希)、list(列表)、set(無序集合)、zset(sorted set:有序集合)

Redis在專案中的應用場景

1、快取資料

最常用,對經常需要查詢且變動不是很頻繁的資料常稱為熱點資料。

2、訊息佇列

相當於訊息訂閱系統,例如ActiveMQ、RocketMQ。如果對資料有較高一致性需求時,還是建議使用MQ)

3、計數器

例如統計點擊率、按讚率,redis具有原子性,可以避免並發問題

4、電商網站資訊

大型電商平台初始化頁面資料的快取。例如去哪裡網買機票的時候首頁的價格和你點進去的價格會有差異。

5、熱點資料

例如新聞網站即時熱點、微博熱搜等,需要頻繁更新。總資料量比較大的時候直接從資料庫查詢會影響效能

給個愛的理由

#在單節點伺服器我們通常是這樣的

為什麼都說redis很好用

#隨著企業的發展、業務的擴展。面對海量的數據,直接使用MySql會導致效能下降,數據的讀寫也會非常慢。於是我們就可以搭配快取來處理大量資料。

於是現在我們是這樣的:

為什麼都說redis很好用

上圖只是簡述了快取的作用,當資料繼續增大我們需要利用主從複製技術來達到讀寫分離

資料庫層直接與快取進行交互,如果快取中有資料直接回傳客戶端,如果沒有才會從MySql去查詢。從而減小了資料庫的壓力,提升了效率。

平常發布了一款新手機,會有搶購活動。同一時段,服務端會收到很多的下單請求。

我們需要使用redis的原子操作來實作這個「單執行緒」。首先我們把庫存存在一個清單中,假設有10件庫存,就往清單中push10個數,這個數沒有實際意義,只代表10件庫存。搶購開始後,每到來一個用戶,就從名單中pop一個數,表示用戶搶購成功。當清單為空時,表示已經被搶光了。因為清單的pop操作是原子的,即使有很多用戶同時到達,也是依次執行的

題外話:還有的搶購是直接在前端頁面限制請求,這些請求直接被前端攔截,並沒有到後端伺服器

Redis為什麼會這麼快?

1、Redis是純記憶體操作,需要的時候需要我們手動持久化到硬碟中

2、Redis是單線程,從而避開了多線程中上下文頻繁切換的操作。

3、Redis資料結構簡單、對資料的操作也比較簡單

4、使用底層模型不同,它們之間底層實作方式以及與客戶端之間通訊的應用協定不一樣,Redis直接自己建構了VM 機制,因為一般的系統呼叫系統函數的話,會浪費一定的時間去移動和請求

5、使用多路I/O復用模型,非阻塞I/ O

多路I/O 重複使用: I/O 多路復用技術是為了解決進程或執行緒阻塞到某個I/O 系統呼叫而出現的技術,可以監視多個描述符,一旦某個描述符就緒(一般是讀就緒或寫就緒,就是這個檔案描述符進行讀寫操作之前),能夠通知程式進行對應的讀寫操作

(學習影片分享: redis影片教學

Redis資料類型的應用程式場景

前面提到了Redis支援五種豐富的資料類型,那麼在不同場景下我們該怎麼選擇呢?

String

字串是最常用的資料類型,他能夠儲存任何類型的字串,當然也包括二進位、JSON化的物件、甚至是base64編碼之後的圖片。在Redis中一個字串最大的容量為512MB,可以說是無所不能了。

Hash

常用作儲存結構化資料、例如論壇系統中可以用來儲存使用者的Id、暱稱、頭像、積分等資訊。如果需要修改其中的信息,只需要透過Key取出Value進行反序列化修改某一項的值,再序列化儲存到Redis中,Hash結構存儲,由於Hash結構會在單一Hash元素在不足一定數量時進行壓縮存儲,所以可以大量節約內存。這一點在String結構裡是不存在的。

List

List的實作為雙向鍊錶,即可以支援反向查找和遍歷,更方便操作,不過帶來了部分額外的記憶體開銷,Redis 內部的許多實現,包括發送緩衝隊列等也都是用的這個資料結構。另外,可以利用 lrange 指令,做基於 Redis 的分頁功能,效能極佳,使用者體驗好。

Set

set 對外提供的功能與list 類似是一個列表的功能,特殊之處在於set 是可以自動排重的,當你需要存儲一個列表數據,又不希望出現重複資料時,這個時候就可以選擇使用set。

Sort Set

可以依照某個條件的權重進行排序,例如可以透過點擊數做出排行榜的資料應用程式。

Redis快取的資料一致性

真正意義上來講資料庫的資料和快取的資料是不可能一致的,資料分為最終一直和強一致兩類。如果業務中對資料的要求必須強一直那麼就不能使用快取。快取能做的只能保證資料的最終一致性。

我們能做的只能是盡可能的保證資料的一致性。不管是先刪庫再刪快取 還是 先刪快取再刪庫,都可能出現資料不一致的情況,因為讀寫操作是並發的,我們沒辦法保證他們的先後順序。具體因應策略還是要根據業務需求來定,這裡就不贅述了。

Redis的過期和記憶體淘汰

Redis儲存資料時我們可以設定他的過期時間。但是這個key是怎麼刪除的呢?

一開始我認為是定時刪除,後來發現並不是這樣,因為如果定時刪除,需要一個定時器來不斷的負責監控這個key,雖然內存釋放了,但是非常消耗cpu資源。

Redis過期刪除採用的是定期刪除,預設是每100ms檢測一次,遇到過期的key則進行刪除,這裡的檢測並不是順序檢測,而是隨機檢測。那這樣會不會有漏網之魚?顯然Redis也考慮到了這一點,當我們去讀/寫一個已經過期的key時,會觸發Redis的惰性刪除策略,直接回幹掉過期的key

內存淘汰是指用戶存儲的一部分key是可以被Redis自動的刪除,從而出現從快取中查不到資料的情況。加入我們的伺服器記憶體為2G、但是隨著業務的發展快取的資料已經超過2G了。但這並不影響我們程式的運行,因為作業系統的可見記憶體並不受實體記憶體的限制。實體記憶體不夠用沒關係,電腦會從硬碟中劃出一片空間來當作虛擬記憶體。這就是Redis設計兩個應用場景的初衷:快取、持久性儲存

快取擊穿

快取只是為了緩解資料庫壓力而添加的一層保護層,當從快取中查詢不到我們需要的資料就要去資料庫中查詢了。如果被駭客利用,頻繁去存取快取中沒有的數據,那麼快取就失去了存在的意義,瞬間所有請求的壓力都落在了資料庫上,這會導致資料庫連線異常。

解決方案:

1、後台設定定時任務,主動的去更新快取資料。這種方案很容易理解,但是當key比較分散的時候,操作起來還是比較複雜的

2、分級快取。例如設定兩層快取保護層,1級快取失效時間短,2級快取失效時間長。有請求過來優先從1級緩存去查找,如果在1級緩存中沒有找到相應數據,則對該線程進行加鎖,這個線程再從數據庫中取到數據,更新至1級和2級緩存。其他執行緒則直接從2級執行緒取得

3、提供一個攔截機制,內部維護一系列合法的key值。當請求的key不合法時,直接返回。

快取雪崩

快取雪崩就是指快取由於某些原因(例如宕機、cache服務掛了或不回應)整體crash掉了,導致大量請求到達後端資料庫,從而導致資料庫崩潰,整個系統崩潰,發生災難,也就是上面提到的快取擊穿。

為什麼都說redis很好用

如何避免雪崩:

1、為快取加上某一區間內的隨機生效時間,不同的key設定不同的失效時間,避免同一時間集體失效。

2、和快取擊穿解決方案類似,做二級緩存,原始快取失效時從拷貝快取中讀取資料。

3、利用加鎖或佇列方式避免過多請求同時對伺服器進行讀寫操作。

結語:

Redis的效能極高,讀取的速度是110000次/s,寫的速度是81000次/s,支援事務,支援備份,豐富的資料類型。

任何事情都是兩面性,Redis也是有缺點的:

1、由於是記憶體資料庫,所以單一機器儲存的資料量是有限的,需要開發者提前預估,需要及時刪除不需要的資料。

2、當修改Redis的資料之後需要將持久化到硬碟的資料重新加入到內容中,時間比較久,這時候Redis是無法正常運作的。

原文連結:https://www.pianshen.com/article/589052263/

相關推薦:redis資料庫教學

#

以上是為什麼都說redis很好用的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:pianshen.com。如有侵權,請聯絡admin@php.cn刪除