redis學習

1、爲什麼使用redis

(一)性能
     我們在碰到需要執行耗時特別久,且結果不頻繁變動的SQL,就特別適合將運行結果放入緩存。

這樣,後面的請求就去緩存中讀取,使得請求能夠迅速響應。

(二)併發

      在大併發的情況下,所有的請求直接訪問數據庫,數據庫會出現連接異常

這個時候,就需要使用redis做一個緩衝操作,讓請求先訪問到redis,而不是直接訪問數據庫。

2、單線程的redis爲什麼這麼快

redis是單線程工作模型:
(一) 純內存操作
(二) 單線程操作,避免了頻繁的上下文切換
(三) 採用了非阻塞I/O多路複用機制

3、redis的數據類型,以及每種數據類型的使用場景

(一) String
這個其實沒啥好說的,最常規的set/get操作,value可以是String也可以是數字。一般做一些複雜的計數功能的緩存。

(二) hash
這裏value存放的是結構化的對象,比較方便的就是操作其中的某個字段。博主在做單點登錄的時候,就是用這種數據結構存儲用戶信息,以cookieId作爲key,設置30分鐘爲緩存過期時間,能很好的模擬出類似session的效果

(三) list
使用List的數據結構,可以做簡單的消息隊列的功能。另外還有一個就是,可以利用lrange命令,做基於redis的分頁功能,性能極佳,用戶體驗好。本人還用一個場景,很合適---取行情信息。就也是個生產者和消費者的場景。LIST可以很好的完成排隊,先進先出的原則。

(四) set
因爲set堆放的是一堆不重複值的集合。所以可以做全局去重的功能。爲什麼不用JVM自帶的Set進行去重?因爲我們的系統一般都是集羣部署,使用JVM自帶的Set,比較麻煩,難道爲了一個做一個全局去重,再起一個公共服務,太麻煩了。
另外,就是利用交集、並集、差集等操作,可以計算共同喜好,全部的喜好,自己獨有的喜好等功能。

(五) sorted set
sorted set多了一個權重參數score,集合中的元素能夠按score進行排列。可以做排行榜應用,取TOP N操作。

4、redis的過期策略以及內存淘汰機制

redis採用的是 定期刪除+惰性刪除策略

爲什麼不用定時刪除策略?

定時刪除,用一個定時器來負責監視key,過期則自動刪除。雖然內存及時釋放,但是十分消耗CPU資源

在大併發請求下,CPU要將時間應用在處理請求,而不是刪除key,因此沒有采用這一策略.

定期刪除,redis默認每隔100ms檢查,是否有過期的key,有過期key則刪除。需要說明的是,redis不是每個100ms將所有的key檢查一次,而是隨機抽取進行檢查(如果每隔100ms,全部key進行檢查,redis豈不是卡死)。

於是,惰性刪除派上用場。也就是說在你獲取某個key的時候,redis會檢查一下這個key是否過期了?如果過期了此時就會刪除。

如果定期刪除沒刪除key。然後也沒有即時去請求key,也就是說惰性刪除也沒生效。這樣,redis的內存會越來越高。那麼就應該採用內存淘汰機制

在 redis.conf 中有一行配置

# maxmemory-policy volatile-lru

該配置就是配內存淘汰策略的。

1)noeviction:當內存不足以容納新寫入數據時,新寫入操作會報錯

2)allkeys-lru:當內存不足以容納新寫入數據時,在鍵空間中,移除最近最少使用的key推薦使用

3)allkeys-random:當內存不足以容納新寫入數據時,在鍵空間中,隨機移除某個key

4)volatile-lru:當內存不足以容納新寫入數據時,在設置了過期時間的鍵空間中,移除最近最少使用的key。這種情況一般是把redis既當緩存,又做持久化存儲的時候才用。不推薦   // TODO 爲什麼不用這個???

5)volatile-random:當內存不足以容納新寫入數據時,在設置了過期時間的鍵空間中,隨機移除某個key。依然不推薦

6)volatile-ttl:當內存不足以容納新寫入數據時,在設置了過期時間的鍵空間中,有更早過期時間的key優先移除。不推薦

ps:如果沒有設置 expire 的key, 不滿足先決條件(prerequisites); 那麼 volatile-lru, volatile-random 和 volatile-ttl 策略的行爲, 和 noeviction(不刪除) 基本上一致。 

6、redis和數據庫雙寫一致性問題

     數據庫和緩存雙寫,就必然會存在不一致的問題。如果對數據有強一致性要求,不能放緩存我們所做的一切,只能保證最終一致性。另外,我們所做的方案其實從根本上來說,只能說降低不一致發生的概率,無法完全避免。因此,有強一致性要求的數據,不能放緩存。

首先,採取正確更新策略:先更新數據庫,再刪緩存。其次,因爲可能存在刪除緩存失敗的問題,提供一個補償措施即可,例如利用消息隊列。

7、Redis持久化存儲

Redis中數據存儲模式有兩種:cache-only以及persistence

cache-only: 只作爲"緩存"服務,不提供數據的持久化操作,數據在服務停止後消失,因此在此模式下也不存在數據恢復的問題,該模式的優點是效率高,容易擴展,缺點是安全性較低。

persistence:該模式下將內存中的數據持久化到磁盤文件,服務重啓後數據可以恢復,優點是相對安全。

對於persistence持久化存儲,Redis提供了兩種方式:

Redis Database 簡稱(RDB)  以及   Append-only file 簡稱(AOF)

RDB

RDB是在某個時間點將數據寫入一個臨時文件,持久化結束後,用這個臨時文件替換上次持久化的文件,達到數據恢復。

優點:使用單獨子進程來進行持久化,主進程不會進行任何IO操作,保證了redis的高性能
缺點:RDB是間隔一段時間進行持久化,如果持久化之間redis發生故障,會發生數據丟失。所以這種方式更適合數據要求不嚴謹的時候

執行數據寫入到臨時文件的時間點是可以通過配置來自己確定的,通過配置redis在n秒內如果超過m個key被修改就執行一次RDB操作。這個操作就類似於在這個時間點來保存一次Redis的所有數據,一次快照數據。所有這個持久化方法也通常叫做 snapshots。

RDB默認開啓redis.conf 中的具體配置參數如下 :


# dbfilename:持久化數據存儲在本地的文件
dbfilename dump.rdb

# dir:持久化數據存儲在本地的路徑,如果是在/redis/redis-3.0.6/src下啓動的redis-cli,則數據會存儲在當前src目錄下
dir ./

## snapshot觸發的時機,save <seconds> <changes>  
## 如下爲900秒後,至少有一個變更操作,纔會snapshot  
## 對於此值的設置,需要謹慎,評估系統的變更操作密集程度  
## 可以通過“save “””來關閉snapshot功能  

# save時間: 更改了1個key時間隔900s進行持久化存儲;
save 900 1

# save時間: 更改了10個key300s進行存儲;
save 300 10

# save時間: 更改10000個key60s進行存儲。
save 60 10000

## 當snapshot時出現錯誤無法繼續時,是否阻塞客戶端“變更操作”,“錯誤”可能因爲磁盤已滿/磁盤故障/OS級別異常等  
stop-writes-on-bgsave-error yes  

## 是否啓用rdb文件壓縮,默認爲“yes”,壓縮往往意味着“額外的cpu消耗”,同時也意味這較小的文件尺寸以及較短的網絡傳輸時間  
rdbcompression yes

snapshot 觸發的時機,是有“間隔時間”和“變更次數”共同決定,同時符合2個條件纔會觸發snapshot, 否則“變更次數”會被繼續累加到下一個“間隔時間”上。snapshot過程中並不阻塞客戶端請求。snapshot首先將數據寫入臨時文件,當成功結束後,將臨時文件重名爲dump.rdb。

使用RDB恢復數據:自動的持久化數據存儲到dump.rdb後。實際只要重啓redis服務即可完成(啓動redis的server時會從dump.rdb中先同步數據)

AOF默認關閉,開啓方法,修改配置文件 reds.confappendonly yes

##此選項爲aof功能的開關,默認爲“no”,可以通過“yes”來開啓aof功能  
##只有在“yes”下,aof重寫/文件同步等特性纔會生效  
appendonly yes  

##指定aof文件名稱  
appendfilename appendonly.aof  

##指定aof操作中文件同步策略,有三個合法值:always everysec no,默認爲everysec  
appendfsync everysec  

##在aof-rewrite期間,appendfsync是否暫緩文件同步,"no"表示“不暫緩”,“yes”表示“暫緩”,默認爲“no”  
no-appendfsync-on-rewrite no  

##aof文件rewrite觸發的最小文件尺寸(mb,gb),只有大於此aof文件大於此尺寸是纔會觸發rewrite,默認“64mb”,建議“512mb”  
auto-aof-rewrite-min-size 64mb  

##相對於“上一次”rewrite,本次rewrite觸發時aof文件應該增長的百分比。  
##每一次rewrite之後,redis都會記錄下此時“新aof”文件的大小(例如A),那麼當aof文件增長到A*(1 + p)之後  
##觸發下一次rewrite,每一次aof記錄的添加,都會檢測當前aof文件的尺寸。  
auto-aof-rewrite-percentage 100

AOF和RDB各有優缺點,這是有它們各自的特點所決定:
        1) AOF更加安全,可以將數據更加及時的同步到文件中,但是AOF需要較多的磁盤IO開支,AOF文件尺寸較大,文件內容恢復數度相對較慢。
        2) snapshot安全性較差,它是“正常時期”數據備份以及master-slave數據同步的最佳手段,文件尺寸較小,恢復數度較快。

可以通過配置文件來指定它們中的一種,或者同時使用它們(不建議同時使用),或者全部禁用

        在架構良好的環境中,master 通常使用 AOF,slave 使用 snapshot,主要原因是

master需要首先確保數據完整性,它作爲數據備份的第一選擇;

slave提供只讀服務(目前slave只能提供讀取服務),它的主要目的就是快速響應客戶端read請求;

        但是如果你的redis運行在網絡穩定性差/物理環境糟糕情況下,建議你master和slave均採取AOF,這個在master和slave角色切換時,可以減少“人工數據備份”/“人工引導數據恢復”的時間成本;

        如果你的環境一切非常良好,且服務需要接收密集性的write操作,那麼建議master採取snapshot,而slave採用AOF。

 

 

 

 

 

 

 

 

 

發佈了77 篇原創文章 · 獲贊 37 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章