Redis進階知識一覽

Redis的持久化機制

RDB: Redis DataBase

  1. 什麼是RDB
    RDB∶每隔一段時間,把內存中的數據寫入磁盤的臨時文件,作爲快照,恢復的時候把快照文件讀進內存。如果宕機重啓,那麼內存裏的數據肯定會沒有的,那麼再次啓動redis後,則會恢復。

  2. 備份與恢復
    內存備份-->磁盤臨時文件
    臨時文件-->恢復到內存

  3. RDB優劣勢

    • 優勢
      1. 每隔一段時間備份,全量備份
      2. 災備簡單,可以遠程傳輸
      3. 子進程備份的時候,主進程不會有任何io操作(不會有寫入修改或刪除),保證備份數據的的完整性
      4. 相對AOF來說,當有更大文件的時候可以快速重啓恢復
    • 劣勢
      1. 發生故障時,有可能會丟失最後一次的備份數據
      2. 子進程所佔用的內存比會和父進程一模一樣,這會造成CPU負擔
      3. 由於定時全量備份是重量級操作,所以對於實時備份,就無法處理了。
  4. RDB的配置

    1. 保存位置,可以在redis.conf自定義∶/user/local/redis/working/dump.rdb
    2. 保存機制∶
save 900 1       # 如果1個緩存更新,則15分鐘後備份
save 300 10      # 如果10個緩存更新,則5分鐘後備份
save 60 10000    # 如果10000個緩存更新,則1分鐘後備份
  1. stop-writes-on-bgsave-error
    • yes∶如果save過程出錯,則停止寫操作
    • no∶ 可能造成數據不一致
  2. rdbcompression
    • yes∶開啓rdb壓縮模式
    • no∶關閉,會節約cpu損耗,但是文件會大,道理同nginx
  3. rdbchecksum
    • yes∶使用CRC64算法校驗對rdb進行數據校驗,有10%性能損耗
    • no∶不校驗

總結
RDB適合大量數據的恢復,但是數據的完整性和一致性可能會不足

AOF: Append Only File

  RDB會丟失最後一次備份的rdb文件,但是其實也無所謂,其實也可以忽略不計,畢竟是緩存,丟了就丟了,但是如果追求數據的完整性,那就的考慮使用AOF了。
AOF特點

  1. 以日誌的形式來記錄用戶請求的寫操作。讀操作不會記錄,因爲寫操作纔會存存儲。
  2. 文件以追加的形式而不是修改的形式。
  3. redis的aof恢復其實就是把追加的文件從開始到結尾讀取執行寫操作。

優勢

  1. AOF更加耐用,可以以秒級別爲單位備份,如果發生問題,也只會丟失最後一秒的數據,大大增加了可靠性和數據完整性。所以AOF可以每秒備份一次,使用fsync操作。
  2. 以log日誌形式追加,如果磁盤滿了,會執行redis-check-aof 工具
  3. 當數據太大的時候,redis可以在後臺自動重寫aof。當redis繼續把日誌追加到老的文件中去時,重寫也是非常安全的,不會影響客戶端的讀寫操作。
  4. AO日誌包含了所有寫操作,會更加便於redis的解析恢復。

劣勢

  1. 相同的數據,同一份數據,AOF比RDB大
  2. 針對不同的同步機制,AOF會比RDB慢,因爲AOF每秒都會備份做寫操作,這樣相對與RDB來說就略低。 每秒備份fsync沒毛病,但是如果客戶端的每次寫入就做一次備份fsync 的話,那麼redis的性能就會下降。
  3. AOF發生過bug,就是數據恢復的時候數據不完整,這樣顯得AOF會比較脆弱,容易出現bug,因爲AOF沒有RDB那麼簡單,但是呢爲了防止bug的產生,AOF就不會根據日的指令去重構,而是根據當時緩存中存在的數據指令去做重構,這樣就更加健壯和可靠了。

AOF的配置

# AOF 默認關閉,yes可以開啓
appendonly no

# A0F 的文件名
appendfilename "appendonly.aof"

# no∶不同步
# everySec∶每秒備份,推薦使用
# always∶每次操作都會備份,安全並且數據完整,但是慢性能差
appendfsync everysec

# 重寫的時候是否要同步,no可以保證數據安全
no-appendfsync-on-rewrite no

# 重寫機制∶避免文件越來越大,自動優化壓縮指令,會fork一個新的進程去完成重寫動作,新進程裏的內存數據會被重寫,此時舊的aof文件不會被讀取使用,類似rdb
# 當前A0F文件的大小是上次AOF大小的100% 並且文件體積達到64m,滿足兩者則觸發重寫
auto-aof-rewrite-percentage 100 
auto-aof-rewrite-min-size 64mb

到底採用RDB還是AOF呢?

  1. 如果你能接受一段時間的緩存丟失,那麼可以使用RDB
  2. 如果你對實時性的數據比較care,那麼就用AOF
  3. 使用RDB和AOF結合一起做持久化,RDB做冷備,可以在不同時期對不同版本做恢復,AOF做熱備,保證數據僅僅只有1秒的損失。當AOF破損不可用了,那麼再用RDB恢復,這樣就做到了兩者的相互結合,也就是說Redis恢復會先加載AOF,如果AOF有問題會再加載RDB,這樣就達到冷熱備份的目的了。

Redis 緩存過期處理與內存淘汰機制

計算機內存有限,越大越貴,Redis的高併發高性能都是基於內存的,用硬盤的話GG。

已過期的key如何處理?
設置了expire的key緩存過期了,但是服務器的內存還是會被佔用,這是因爲redis所基於的兩種刪除策略。
redis有兩種策略∶

  1. (主動)定時刪除
    • 定時隨機的檢查過期的key,如果過期則清理刪除。(每秒檢查次數在redis.conf中的hz配置)
  2. (被動)惰性刪除
    • 當客戶端請求一個已經過期的key的時候,那麼redis會檢查這個key是否過期,如果過期了,則刪除,然後返回一個nil。這種策略對cpu比較友好,不會有太多的損耗,但是內存佔用會比較高。

所以,雖然key過期了,但是隻要沒有被redis清理,那麼其實內存還是會被佔用着的。

那麼如果內存被Redis緩存佔用滿了咋辦?
內存佔滿了,可以使用硬盤,來保存,但是沒意義,因爲硬盤沒有內存快,會影響redis性能。所以,當內存佔用滿了以後,redis提供了一套緩存淘汰機制∶ ME MORY MANAGEMENT。
maxmemory ∶當內存已使用率到達,則開始清理緩存

* noeviction∶舊緩存永不過期,新緩存設置不了,返回錯誤
* allkeys-lru∶清除最少用的舊緩存,然後保存新的緩存(推薦使用)
* allkeys-random∶在所有的緩存中隨機刪除(不推薦)
* volatie-lru∶在那些設置了expire過期時間的緩存中,清除最少用的舊緩存,然後保存新的緩存
* volatile-random∶在那些設置了expire過期時間的緩存中,隨機刪除緩存
* volatile-ttl∶在那些設置了expire過期時間的緩存中,刪除即將過期的

哨兵模式

Master掛了,如何保證可用性,實現繼續讀寫
什麼是哨兵?
Sentinel(哨兵)是用於監控Redis集羣中Master狀態的工具,是 Redis 高可用解決方案,哨兵可以監視一個或者多個redis master服務,以及這些master服務的所有從服務; 當某個master服務宕機後,會把這個master下的某個從服務升級爲master來替代已宕機的master繼續工作。示例圖:

配置哨兵監控master
創建並且配置sentinel.conf∶

  • 普通配置
port 26379
pidfile "/usr/local/redis/sentinel/redis-sentinel.pid"
dir "/usr/local/redis/sentinel"
daemonize yes 
protected-mode no
logfile "/usr/local/redis/sentinel/redis-sentinel.1og"
  • 核心配置
# 配置哨兵
sentinel monitor mymaster 127.0.0.1 6379 2 
#密碼
sentinel auth-pass <master-name> <password>
# master被sentinel認定爲失效的間隔時間
sentinel down-after-milliseconds mymaster 30000 
# 剩餘的slaves重新和新的master做同步的並行個數
sentinel parallel-syncs mymaster 1
# 主備切換的超時時間,哨兵要去做故障轉移,這個時候哨兵也是一個進程,如果他沒有去執行,超過這個時間後,會由其他的哨兵來處理
sentinel failover-timeout mymaster 180000

啓動哨兵x3
redis-sentinel sentinel.conf

測試

  1. master掛了,看slave是否成爲master
  2. master恢復,觀察slave狀態

結論:master掛了以後,由於哨兵監控,剩餘slave會進行選舉,選舉後其中一個成爲master,當原來的master恢復後,他會成爲slave。

一般master數據無法同步給slave的方案檢查爲如下∶

  1. 網絡通信問題,要保證互相ping通,內網互通。
  2. 關閉防火牆,對應的端口開放(虛擬機中建議永久關閉防火牆,雲服務器的話需要保證內網互通)。
  3. 統一所有的密碼,通過逐臺檢查機器以防某個節點被遺漏。

哨兵信息檢查

查看相關信息

# 查看reminis-master下的master節點信息
sentinel master reminis-master

# 查看reminis-master下的slaves節點信息
sentinel slaves reminis-master

# 查看reminis-master下的哨兵節點信息
sentinel sentinels reminis-master

SpringBoot集成Redis哨兵-配置

配置如下:

spring:
  redis:
    database: 1 
    password: reminis 
    sentinel:
    master: reminis-master
    nodes: 192.168.32.10:26379,192.168.32.12:26379,192.168.32.13:26379

Redis集羣

前面我們一起學習了主從複製以及哨兵,他們可以提高讀的併發,但是單個master容量有限,數據達到一定程度會有瓶頸,這個時候可以通過水平擴展爲多master-slave成爲集羣。那麼這一節開始我們就一起來學習redis-cluster∶他可以支撐多個master-slave,支持海量數據,實現高可用與高併發。

哨兵模式其實也是一種集羣,他能夠提高讀請求的併發,但是容錯方面可能會有一些問題,比如master同步數據給slave的時候,這其實是異步複製吧,這個時候master掛了,那麼slave上的數據就沒有master新,數據同步需要時間的,1-2秒的數據會丟失。master恢復並轉換成slave後,新數據則丟失。

特點:

  1. 每個節點知道彼此之間的關係,也會知道自己的角色,當然他們也會知道自己存在於一個集羣環境中,他們彼此之間可以交互和通信,比如ping pong。那麼這些關係都會保存到某個配置文件中,每個節點都有,這個我們在搭建的時候需要做配置的。
  2. 客戶端要和集羣建立連接的話,只需要和其中一個建立關係就行。
  3. 某個節點掛了,也是通過超過半數的節點來進行的檢測,客觀下線後主從切換,和我們之前在哨兵模式中提到的是一個道理。
  4. Redis中存在很多的插槽,又可以稱之爲槽節點,用於存儲數據,這個先不管,後面再說。

集羣容錯

構建Redis集羣,需要至少3個節點作爲master,以此組成一個高可用的集羣,此外每個master都需要配備一個slave,所以整個集羣需要6個節點,這也是最經典的Redis集羣,也可以稱之爲三主三從,容錯性更佳。所以在搭建的時候需要有6臺虛擬機。請各自準備6臺虛擬機,可以通過克隆去構建,使用單實例的Redis 去克隆即可。

  • 集羣也可以在單服務器構建,稱之爲僞集羣,但是生產環境肯定是真的,所以建議用6臺。
  • 克隆後務必關閉Redis。

構建Redis集羣

redis.conf 配置

# 開啓集羣模式
cluster-enabled yes

# 每一個節點需要有一個配置文件,需要6份。每個節點處於集羣的角色都需要告知其他所有節點,彼此知道,這個文件用於存儲集羣模式下的集羣狀態等信息,這個文件是由redis自己維護,我們不用管。如果你要重新創建集羣,那麼把這個文件刪了就行
cluster-config-file nodes-201.conf 

# 超時時間,超時則認爲master宕機,隨後主備切換
cluster-node-timeout 5000 
# 開啓AOF
 appendonly yes

啓動6個redis實例

  1. 啓動6臺
  2. 如果啓動過程出錯,把rdb等文件刪除清空

創建集羣

####
# 注意1∶如果你使用的是redis3.x版本,需要使用redis-trib.rb來構建集羣,最新版使用C語言來構建了,這個要注意
# 注意2∶以下爲新版的redis構建方式
####

# 創建集羣,主節點和從節點比例爲1,1-3爲主,4-6爲從,1和4.2和5 3和6分別對應爲主從關係,這也是最經典用的最多的集羣模式
redis-cli --cluster create ip1:port1 ip2:port2 ip3:port 3 ip4:port4 ip5:port5 ip6:port6 --cluster-replicas 1

slots槽,用於裝數據,主節點有,從節點沒有

檢查集羣信息:redis-cli--cluster check 192.168.25.64:6380

總結

最後,讓我們來看一下下方的思維導圖進行梳理內容:

複習

  1. 本階段開篇講述了分佈式相關,其實分佈式和集羣的概念在前期就介紹過了,不同的節點做着不同的事,就是分佈式,不同的節點做着相同的事就是集羣。那麼Redis是NoSql,不僅僅是sql,功能更強勁,可以作爲緩存寫入內存,提供高速訪問,爲數據庫做了一道屏障,保護數據庫,把熱點數據放入緩存,從而提升項目的併發量與吞吐量。
  2. 介紹完Redis後我們又一起搭建了單機單實例版的Redis,需要注意,Redis雖然可以在win或mac上搭建,但是企業裏都是linux,所以我們一定要使用linux來搭建和配置。
  3. Redis提供命令行客戶端工具,也就是redis-cli進入命令行後可以進行相應的操作,我們講述了五大數據類型,分別爲∶string,list,hash,set與zset。每個數據類型包含了一些操作指令,這些沒有必要去死記硬背,遇到了,就去查一下api,百度一下即可。
  4. Redis是單線程的,但是他的性能卻很高,在這裏我們講述了Redis的單線程模型,這一點往往在面試過程中會被問到。
  5. 當單機的Redis安裝配置完畢以後,我們整合到了項目中,結合了SpringBoot,優化了首頁的輪播圖與分類,因爲這些完全可以放入緩存,沒有必要去查詢數據庫。當然,對幹前期單體階段的購物車,我們結合了redis實現了分佈式購物車,如此,不論用戶在任何電腦訪問,都能看到曾經的購物車數據,並且我們也實現了登錄後的同步購物車功能。
  6. Redis可以實現類似於MQ的發佈與訂閱,是屬於生產者與消費者模式,但是正所謂專人做專事,發佈訂閱機制沒有必要用Redis來實現,企業裏都是使用的MQ。
  7. Redis的持久化機制,RDB與AOF,這兩種模式大家一定要知道他們之間的區別,一個是全量備份,一個是增量定時,各有各的好,也有缺點,面試過程中會被問到。
  8. 單機Redis存在單點故障與讀併發量的限制,所以可以通過主從與哨兵來實現,主從解決讀寫分離,並且一主多從能夠提升讀的併發。哨兵提供監控機制,一旦主掛了,備則上位成爲主,如此實現高可用。
  9. 在Redis中可以設置無磁盤化,如果磁盤比較慢,可以打開,但是一般來說,服務器都會採用ssd,尤其針對數據存儲類的。
  10. 當key過期了,你會發現內存佔用率還是很高,這是因爲redis的機制,有被動主動之分。這一點在面試中可能會被問到喲。此外,對於內存寫滿後的kev淘汰機制,我們也在這裏提到過,不同的策略都可以配置。
  11. Redis除了單機與哨兵模式外,還能搭建集羣,最經典的還屬三主三從,搭建完畢後我們還整合了SpringBoot,其實由於springboot的yml配置特性,大大的減少了配置項,如果你使用springmvc,xml中的配置會有很多,而yml中的配置也就2-3行的事。
  12. 對於緩存來說,我們還需要預防緩存穿透與雪崩,穿透的話一般來說只需要針對空值緩存就行,過期時間設置5-10分鐘,這樣就流量就不會打在數據庫上導致死機宕機。雪崩其實也可以做到提前預防,那就是用到過期時間的key,時間全部錯開,此外,有些數據可以做永久保存的話那就直接保存好了,這樣就不會造成大面積的key失效了。
  13. 最後有一點還需要說的,就是當一次請求過來,如果查詢的key比較多,能做到批量就批量,如果是循環查詢緩存的話,一來吞吐量低,而來比較low。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章