Redis面試內容,Redis過期策略,Redis持久化方式,緩存穿透、緩存擊穿和緩存雪崩,以及解決辦法

文章目錄

  • 一、redis
    • 什么是Redis
    • Redis使用場景
      • 1、緩存
      • 2、數據共享[分布式](https://so.csdn.net/so/search?q=分布式&spm=1001.2101.3001.7020)
      • 3、分布式鎖
      • 4、全局ID
      • 5、計數器
      • 6、限流
      • 7、位統計
    • Redis有5中數據類型: SSHLZ
    • Redis中一個key的值每天12點過期,給我一個你的解決方式
      • 定期掃描策略
      • 惰性策略
      • 從節點的過期策略
      • Redis對于超過內存限制的處理
      • Redis 提供了幾種可選策略來進行處理,這些策略在 4.0 之前四種,4.0之后又新增了兩種
      • 淺談LRU與LFU
    • redis 集群模式與哨兵模式的區別
      • 1、主從復制(Replication)
        • 1.1 主從數據庫
        • 1.2 主從復制的特點
        • 1.3 主從復制的優缺點
      • 2、哨兵([Sentinel](https://so.csdn.net/so/search?q=Sentinel&spm=1001.2101.3001.7020))
        • 2.1 Redis哨兵主要功能
      • 2.2 Redis哨兵高可用原理
        • 2.3 Redis哨兵故障切換的過程
        • 2.4 Redis哨兵模式的工作方式
        • 2.5 Redis哨兵模式的優缺點
      • 3、集群(Cluster)
        • 3.1 Redis-Cluster集群的配置
        • 3.2 Redis-Cluster集群的特點
        • 3.3 Redis-Cluster集群的工作方式
        • 3.4 Redis-Cluster集群的優缺點
    • redis 持久化 —— RDB(Redis DataBase)和 AOF(Append Only File)
      • 一、redis持久化----兩種方式
      • 二、redis持久化----RDB
      • 三、redis持久化----AOF
      • 四、redis持久化----AOF重寫
      • 五、redis持久化----如何選擇RDB和AOF
      • 六、Redis的兩種持久化方式也有明顯的缺點
    • redids事務 ACID
      • Redis 的事務需要先劃分出三個階段
      • 從嚴格意義上來說,Redis 是沒有事務的。因為事務必須具備四個特點:
      • 原子性
      • 一致性
      • 隔離性
      • 持久性
    • 談一談緩存穿透、緩存擊穿和緩存雪崩,以及解決辦法

今天來跟大家分享一下個人對Redis方面的理解,話不多說,直接上內容。。。
redis的面試

一、redis

什么是Redis

Redis(Remote Dictionary Server) 是一個使用 C 語言編寫的,開源的(BSD許可)高性能非關系型(NoSQL)的鍵值對數據庫。

Redis 可以存儲鍵和五種不同類型的值之間的映射。鍵的類型只能為字符串,值支持五種數據類型:S字符串、S集合、H散列表、L列表、Z有序集合

與傳統數據庫不同的是 Redis 的數據是存在內存中的,所以讀寫速度非常快,因此 redis 被廣泛應用于緩存方向,每秒可以處理超過 10萬次讀寫操作,是已知性能最快的Key-Value DB。另外,Redis 也經常用來做分布式鎖。除此之外,Redis 支持事務 、持久化、LUA腳本、LRU驅動事件、多種集群方案。

Redis使用場景

1、緩存

String類型

例如:熱點數據緩存(例如報表、明星出軌),對象緩存、全頁緩存、可以提升熱點數據的訪問數據。

2、數據共享分布式

String 類型,因為 Redis 是分布式的獨立服務,可以在多個應用之間共享

例如:分布式Session

3、分布式鎖

String 類型setnx方法,只有不存在時才能添加成功,返回true

public static boolean getLock(String key) {Long flag = jedis.setnx(key, "1");if (flag == 1) {jedis.expire(key, 10);}return flag == 1;
}public static void releaseLock(String key) {jedis.del(key);
}

4、全局ID

int類型,incrby,利用原子性

incrby userid 1000

分庫分表的場景,一次性拿一段

5、計數器

int類型,incr方法

例如:文章的閱讀量、微博點贊數、允許一定的延遲,先寫入Redis再定時同步到數據庫

6、限流

int類型,incr方法

以訪問者的ip和其他信息作為key,訪問一次增加一次計數,超過次數則返回false

7、位統計

String類型的bitcount(1.6.6的bitmap數據結構介紹)

字符是以8位二進制存儲的

Redis有5中數據類型: SSHLZ

  • String (字符串)
  • Set (集合)
  • Hash (散列)
  • List (列表)
  • Zset (有序集合)

Redis中一個key的值每天12點過期,給我一個你的解決方式

鏈接:【精選】Redis對于過期key的處理_redis過期key_不會說話的劉同學的博客-CSDN博客

對于過期鍵的處理,Redis一共提供了兩種過期策略,不同的策略也會影響Redis的性能

下面我就來具體講講這兩種過期策略

定期掃描策略

Redis會將每個設置了過期時間的key放入一個獨立的字典中,之后會定時遍歷這個字典來刪除到期的key

Redis默認每秒進行10次過期掃描,過期掃描不會遍歷過期字典中所有的key,而是采用了一種簡單的貪心策略,如下:

  • (1) 從過期字典中隨機選擇出 20 個key
  • (2) 刪除這 20 個key中已經過期的key
  • (3) 如果過期的key的比例超過1/4,那就重復步驟 (1)

這種隨機從字典里選擇刪除key在一定程度下可以保證主線程在處理過期key的時候不會占用太多的時間

但是如果Redis實例中所有的key都在同一時間過期,那么Redis會持續掃描過期字典集合,直到過期字典中過期的key比例低于 1/4,Redis才會停止掃描,這就會導致Redis會在過期key清理上花費很多的時間,從而導致其他的命令無法執行

因此Redis為了解決這一問題,Redis也給掃描時間設置了一個上限,默認不會超過 25ms,但是這種方案還是會有缺陷

如果客戶端發送了一個命令,此時服務器正在進行過期掃描,那么客戶端的這一請求至少需要等待 25ms 后才能進行處理,如果客戶端的超時時間設置得要比 25ms 低,那么就會出現大量得鏈接超時,從而造成業務端的異常

我們在做業務處理的時候,給大量的key不要設置為同一過期時間,應當給過期key設置一個隨機的時間

惰性策略

定時掃描策略由于是隨機的從過期字典里選取key再進行刪除,因此也會有"漏網之魚"

為了避免這種情況,Redis在定時掃描策略的基礎上還加了一個惰性策略

惰性策略就是在客戶端訪問這個key的時候,如果這個過期key還存在,那么還會對key的過期時間進行檢查,如果過期了就立即刪除并且不會把值返回給客戶端

惰性策略是直接對定時掃描策略的增強,彌補了定時掃描策略的不足

從節點的過期策略

使用Redis就難免會使用到集群,從節點不會主動的進行過期掃描,任然還是以數據同步的方式來對過期數據進行處理

主節點在key到期時,會在AOF文件里增加一條del指令,然后再同步到所有的從節點,從節點執行這條 del 指令來刪除過期的 key

由于主從同步數據是異步進行的,如果主節點過期的key的del指令沒有及時同步到從節點的話,就會出現主從數據不一致

Redis對于超過內存限制的處理

上面我們就已經提到Redis的過期key處理,但是想一下如果Redis中所有的key都沒有設置過期時間又或者key的過期時間非常的長,只要key還沒過期,所有的key都會存在于Redis中,只要Redis沒有宕機,久而久之Redis的內存容量就會超出物理內存限制,此時如果再有數據傳入,那么Redis就會將數據存放直接保存到磁盤中

這種與磁盤頻繁的交互會讓Redis的性能急劇下降,此時Redis就是去了原本存在的意義

為了防止Redis發生與磁盤交互的行為,Redis提供了最大內存的使用限制,我們可以在 conf 配置參數 maxmemory 來限制Redis的使用內存

在這里插入圖片描述

當然這里只配置了內存使用限制還不行,還需要配置處理策略(當內存使用超過了內存使用限制時該怎么做),同樣也需要在 conf 文件中配置 maxmemory-policy 參數

在這里插入圖片描述

Redis 提供了幾種可選策略來進行處理,這些策略在 4.0 之前四種,4.0之后又新增了兩種

noeviction: 不會繼續服務寫請求,讀請求可以繼續進行。這樣可以保證不會丟失數據,但是會讓線上的業務不能持續運行。這也是默認的處理策略
volatile-lru:嘗試淘汰設置了過期時間的key,最少使用的key優先被淘汰。沒有設置過期時間的key不會被淘汰,這樣可以保證需要持久化的數據不會突然丟失
volatile-lru: 與 volatile-lru 不同的是,它會使用 LFU 算法淘汰設置了過期時間的key
volatile-ttl:跟上面幾乎一樣,不過淘汰的策略不是LRU,而是比較key的剩余壽命ttl的值,ttl越小越優先被淘汰
volatile-random:跟上面幾乎一樣,不過淘汰的key是過期key集合中隨機的key
allkeys-lru:區別于volatile-lru,這個策略要淘汰的key對象是全體的key集合,而不只是過期的key集合。這意味著一些沒有設置過期時間的key也會被淘汰
allkeys-lfu:與allkeys-lru算法不同的是,算法淘汰設置了過期時間的key
allkeys-random:跟上面幾乎一樣,不過淘汰的key是隨機的key。

上面的 volatile-xxx 策略只會針對已經設置了過期時間的 key 進行淘汰,allkeys-xxx 策略會對所有的key 進行淘汰

如果客戶端不會設置key的過期時間,那么可以選擇 allkeys-xxx 策略,如果需要保證數據的持久化,那么就可以選擇 volatile-xxx 策略,因為這種策略只針對于設置了過期時間的key,沒有設置過期時間的key不會被LRU算法淘汰

淺談LRU與LFU

上面的淘汰策略里使用到了一種LRU和LFU的淘汰算法機制,我們再來看看這兩種機制的區別

LRU全稱 Least Recently Used,即最近最少使用,意思是當數據最近被訪問了,那么在未來被訪問的幾率會比較大

我們可以把LRU理解為是一個雙向鏈表結構,所有的數據都在這條鏈表中,當訪問了鏈表中某個元素時,會把被訪問元素移動到鏈表的頭部,在淘汰的時候會把靠近鏈表末尾的元素給淘汰掉

假設現在有A、B、C、D、E四個元素,對應在鏈表中

在這里插入圖片描述

當訪問了 D 元素的時候,D 元素會被移動到鏈表頭部

在這里插入圖片描述

越靠近鏈表頭部的位置就表示最近被訪問到,越靠近鏈表末尾的位置就表示不會被訪問到,這樣在鏈表末尾的 C、E 就有可能會被淘汰掉

Redis 使用的時一種近似LRU算法,它跟LRU算法不太一樣,之所以不完全使用LRU算法,是因為其需要消耗大量的額外內存,需要對現有的數據結構進行較大的改造

Redis為了實現近似LRU算法,給每個key增加了一個額外的小字段,這個字段的長度是 24 個bit,也就是最后一次被訪問的時間戳

這個算法也很簡單,就是隨機采樣出 5 (可以通過 maxmemory_samples 參數設置) 個key, 然后進行淘汰掉,如果淘汰后還是超出最大的內存限制,那就繼續隨機采樣淘汰,直到內存低于最大內存限制為止

這里要注意的是,這個采樣是根據淘汰策略來的,如果是 allkeys-xxx 策略,那么就是從所有的 key 字段中隨機采樣,如果是 volatile-xxx 策略,就從帶過期時間的key字典中隨機采樣

LFU全稱 Least frequently used ,使用頻次最少的,即為不經常使用的 ,意思是當數據訪問的頻率或次數很低,那么在未來訪問的幾率也很低

與LRU不同的是,LFU主要關注數據訪問的頻率或次數,而LRU關注的是數據的最近有沒有被訪問

在數據被訪問的時候,LFU 會把訪問的頻率或次數記錄下來,當需要淘汰的時候會把訪問頻率或次數低的數據給淘汰掉,相對于LRU來說,LFU沒有那么復雜

我們還是以A、B、C、D、E 五個元素為例,假設它們對應的訪問頻次為 10、4、9、2、6

在這里插入圖片描述

假設 C 元素被訪問了一次,那么 C 的頻次就會加 1 ,從 9 變成 10 ,那么當需要對數據進行淘汰的時候,其中的 B 和 D 元素的訪問頻率是最低的,就有可能會被淘汰

LFU 在Redis 4.0 之后才被引入進來,具體要使用那種淘汰策略,還需要依據具體的場景來選擇

1.如何保證順序性
2若何保證不重復消費

redis 集群模式與哨兵模式的區別

Redis ClusterRedis的分布式集群解決方案,在 3.0 版本正式推出。在3.0之前的集群方案主要是主從復制和哨兵機制,3種方案各有優缺點。

  • 主從復制(Replication)主要是備份數據、讀寫分離、負載均衡,一個Master可以有多個Slaves服務器作為備份。

  • 哨兵(Sentinel)是為了高可用,可以管理多個Redis服務器,提供了監控,提醒以及自動的故障轉移的功能。sentinel發現master掛了后,就會從slave(從服務器)中重新選舉一個master(主服務器)。

  • 集群(cluster)則是為了解決單機Redis容量有限/能力有限的問題,將數據按一定的規則分配到多臺機器,提高并發量,內存/QPS不受限于單機,可受益于分布式集群高擴展性。

1、主從復制(Replication)

同Mysql主從復制的原因一樣,Redis雖然讀取寫入的速度都特別快,但是也會產生讀壓力特別大的情況。為了解決單點數據庫問題,分擔讀壓力,Redis支持主從復制(把數據復制多個副本部署到其他節點上),讀寫分離,實現Redis的高可用性,冗余備份保證數據和服務的高度可靠性。一個Master可以有多個Slaves。

①從數據庫向主數據庫發送sync(數據同步)命令。
②主數據庫接收同步命令后,會保存快照,創建一個RDB文件。
③當主數據庫執行完保持快照后,會向從數據庫發送RDB文件,而從數據庫會接收并載入該文件。
④主數據庫將緩沖區的所有寫命令發給從服務器執行。
⑤以上處理完之后,之后主數據庫每執行一個寫命令,都會將被執行的寫命令發送給從數據庫。
注意:在Redis2.8之后,主從斷開重連后會根據斷開之前最新的命令偏移量進行增量復制.

在這里插入圖片描述

1.1 主從數據庫

在復制的概念中,數據庫分為兩類,一類是主數據庫(master),另一類是從數據庫(slave)。主數據庫可以進行讀寫操作,當寫操作導致數據變化時會自動將數據同步給從數據庫。而從數據庫一般是只讀的,并接受主數據庫同步過來的數據。一個主數據庫可以擁有多個從數據庫,而一個從數據庫只能擁有一個主數據庫。

1.2 主從復制的特點
  • 主數據庫可以進行讀寫操作,當讀寫操作導致數據變化時會自動將數據同步給從數據庫
  • 從數據庫一般都是只讀的,并且接收主數據庫同步過來的數據
  • 一個master可以擁有多個slave,但是一個slave只能對應一個master
  • slave掛了不影響其他slave的讀和master的讀和寫,重新啟動后會將數據從master同步過來
  • master掛了以后,不影響slave的讀,但redis不再提供寫服務,master重啟后redis將重新對外提供寫服務
  • master掛了以后,不會在slave節點中重新選一個master
1.3 主從復制的優缺點

優點:

  • 支持主從復制,主機會自動將數據同步到從機,數據備份的同時可以進行讀寫分離,提高服務器性能;

  • 為了分載Master的讀操作壓力,Slave服務器可以為客戶端提供只讀操作的服務,寫服務仍然必須由Master來完成;

  • Slave同樣可以接受其它Slaves的連接和同步請求,這樣可以有效的分載Master的同步壓力;

  • Master Server是以非阻塞的方式為Slaves提供服務。所以在Master-Slave同步期間,客戶端仍然可以提交查詢或修改請求;

  • Slave Server同樣是以非阻塞的方式完成數據同步。在同步期間,如果有客戶端提交查詢請求,Redis則返回同步之前的數據;
    缺點:

  • Redis不具備自動容錯和恢復功能,主機從機的宕機都會導致前端部分讀寫請求失敗,需要等待機器重啟或者手動切換前端的IP才能恢復;

  • 主機宕機,宕機前有部分數據未能及時同步到從機,切換IP后還會引入數據不一致的問題,降低了系統的可用性;

  • 如果多個Slave斷線了,需要重啟的時候,盡量不要在同一時間段進行重啟。因為只要Slave啟動,就會發送sync請求和主機全量同步,當多個 Slave 重啟的時候,可能會導致 Master IO劇增從而宕機。

  • Redis較難支持在線擴容,在集群容量達到上限時在線擴容會變得很復雜;

2、哨兵(Sentinel)

主從同步/復制的模式,當主服務器宕機后,需要手動把一臺從服務器切換為主服務器,這就需要人工干預,費事費力,還會造成一段時間內服務不可用。這不是一種推薦的方式,更多時候,我們優先考慮哨兵模式。哨兵是Redis集群架構中非常重要的一個組件,哨兵的出現主要是解決了主從復制出現故障時需要人為干預的問題。

哨兵模式是一種特殊的模式,首先Redis提供了哨兵的命令,哨兵是一個獨立的進程,作為進程,它會獨立運行。其原理是哨兵通過發送命令,等待Redis服務器響應,從而監控運行的多個Redis實例。

Redis Sentinel是社區版本推出的原生高可用解決方案,其部署架構主要包括兩部分:Redis Sentinel集群和Redis數據集群。

其中Redis Sentinel集群是由若干Sentinel節點組成的分布式集群,可以實現故障發現、故障自動轉移、配置中心和客戶端通知。Redis Sentinel的節點數量要滿足2n+1(n>=1)的奇數個。

在這里插入圖片描述

在這里插入圖片描述

規劃
Redis-Master :192.168.181.130 6379
Redis-slave1 :192.168.181.131 6379
Redis-slave2 :192.168.181.132 6379

Redis-Sentinel1:192.168.181.130 26379
Redis-Sentinel2:192.168.181.131 26379
Redis-Sentinel3:192.168.181.132 26379

2.1 Redis哨兵主要功能
  • 集群監控:負責監控Redis master和slave進程是否正常工作

  • 消息通知:如果某個Redis實例有故障,那么哨兵負責發送消息作為報警通知給管理員

  • 故障轉移:如果master node掛掉了,會自動轉移到slave node上

  • 配置中心:如果故障轉移發生了,通知client客戶端新的master地址

2.2 Redis哨兵高可用原理

當主節點出現故障時,由Redis Sentinel自動完成故障發現和轉移,并通知應用方,實現高可用性。

  • 哨兵機制建立了多個哨兵節點(進程),共同監控數據節點的運行狀況。
  • 同時哨兵節點之間也互相通信,交換對主從節點的監控狀況。
  • 每隔1秒每個哨兵會向整個集群:Master主服務器+Slave從服務器+其他Sentinel(哨兵)進程,發送一次ping命令做一次心跳檢測。

這個就是哨兵用來判斷節點是否正常的重要依據,涉及兩個概念:主觀下線和客觀下線。

  • 主觀下線:一個哨兵節點判定主節點down掉是主觀下線。
  • 客觀下線:只有半數哨兵節點都主觀判定主節點down掉,此時多個哨兵節點交換主觀判定結果,才會判定主節點客觀下線。

基本上哪個哨兵節點最先判斷出這個主節點客觀下線,就會在各個哨兵節點中發起投票機制Raft算法(選舉算法),最終被投為領導者的哨兵節點完成主從自動化切換的過程。

2.3 Redis哨兵故障切換的過程

假設主服務器宕機,哨兵1先檢測到這個結果,系統并不會馬上進行 failover 過程,僅僅是哨兵1主觀的認為主服務器不可用,這個現象稱為主觀下線。當后面的哨兵也檢測到主服務器不可用,并且數量達到一定值時,那么哨兵之間就會進行一次投票,投票的結果由一個哨兵發起,進行 failover 操作。切換成功后,就會通過發布訂閱模式,讓各個哨兵把自己監控的從服務器實現切換主機,這個過程稱為客觀下線。對于客戶端而言,一切都是透明的。

2.4 Redis哨兵模式的工作方式
  1. 每個Sentinel(哨兵)進程以每秒鐘一次的頻率向整個集群中的Master主服務器,Slave從服務器以及其他Sentinel(哨兵)進程發送一個 PING 命令。
  2. 如果一個實例(instance)距離最后一次有效回復 PING 命令的時間超過 down-after-milliseconds 選項所指定的值, 則這個實例會被 Sentinel(哨兵)進程標記為主觀下線(SDOWN)
  3. 如果一個Master主服務器被標記為主觀下線(SDOWN),則正在監視這個Master主服務器的所有 Sentinel(哨兵)進程要以每秒一次的頻率確認Master主服務器的確進入了主觀下線狀態
  4. 當有足夠數量的 Sentinel(哨兵)進程(大于等于配置文件指定的值)在指定的時間范圍內確認Master主服務器進入了主觀下線狀態(SDOWN), 則Master主服務器會被標記為客觀下線(ODOWN)
  5. 在一般情況下, 每個 Sentinel(哨兵)進程會以每 10 秒一次的頻率向集群中的所有Master主服務器、Slave從服務器發送 INFO 命令。
  6. 當Master主服務器被 Sentinel(哨兵)進程標記為客觀下線(ODOWN)時,Sentinel(哨兵)進程向下線的 Master主服務器的所有 Slave從服務器發送 INFO 命令的頻率會從 10 秒一次改為每秒一次。
  7. 若沒有足夠數量的 Sentinel(哨兵)進程同意 Master主服務器下線, Master主服務器的客觀下線狀態就會被移除。若 Master主服務器重新向 Sentinel(哨兵)進程發送 PING 命令返回有效回復,Master主服務器的主觀下線狀態就會被移除。
2.5 Redis哨兵模式的優缺點

優點:

哨兵模式是基于主從模式的,所有主從的優點,哨兵模式都具有。
主從可以自動切換(自動化故障恢復),系統更健壯,可用性更高。
缺點:

Redis較難支持在線動態擴容,在集群容量達到上限時在線擴容會變得很復雜。
Redis 數據節點中 slave 節點作為備份節點不提供服務.

3、集群(Cluster)

Redis 的哨兵模式基本已經可以實現高可用,讀寫分離 ,但是在這種模式下每臺 Redis 服務器都存儲相同的數據,浪費內存且有木桶效應,所以在redis3.0上加入了 Cluster 集群模式,實現了 Redis 的分布式存儲,也就是說每臺 Redis 節點上存儲不同的內容。

Redis Cluster是社區版推出的Redis分布式集群解決方案,主要解決Redis分布式方面的需求,比如,當遇到單機內存,并發和流量等瓶頸的時候,Redis Cluster能起到很好的負載均衡的目的。

Redis Cluster著眼于提高并發量。集群至少需要3主3從,且每個實例使用不同的配置文件,主從不用配置,集群會自己選。

在redis-cluster架構中,redis-master節點一般用于接收讀寫,而redis-slave節點則一般只用于備份, 其與對應的master擁有相同的slot集合,若某個redis-master意外失效,則再將其對應的slave進行升級為臨時redis-master。

當有請求是在向slave發起時,會直接重定向到對應key所在的master來處理。 但如果不介意讀取的是redis-cluster中有可能過期的數據并且對寫請求不感興趣時,則亦可通過readonly命令,將slave設置成可讀,然后通過slave獲取相關的key,達到讀寫分離。具體可以參閱redis官方文檔等相關內容。

在這里插入圖片描述

3.1 Redis-Cluster集群的配置

使用集群,只需要將每個數據庫節點的cluster-enable配置打開即可。根據官方推薦,集群部署至少要 3 臺以上的master節點(因為選舉投票的機制,所以必須為奇數),最好使用 3 主 3 從六個節點的模式。在測試環境中,只能在一臺機器上面開啟6個服務實例來模擬。

3.2 Redis-Cluster集群的特點

所有的redis節點彼此互聯(PING-PONG機制),內部使用二進制協議優化傳輸速度和帶寬。
節點的fail是通過集群中超過半數的節點檢測失效時才生效。
客戶端與 Redis 節點直連,不需要中間代理層.客戶端不需要連接集群所有節點,連接集群中任何一個可用節點即可。
所有的節點都是一主一從(也可以是一主多從),其中從節點不提供服務,僅作為備用
支持在線增加、刪除節點
客戶端可以連接任何一個主節點進行讀寫

3.3 Redis-Cluster集群的工作方式

在 Redis 的每一個節點上,都有這么兩個東西,一個是插槽(slot),它的的取值范圍是:0-16383。還有一個就是cluster,可以理解為是一個集群管理的插件。當我們的存取的 Key到達的時候,Redis 會根據 crc16的算法得出一個結果,然后把結果對 16384 求余數,這樣每個 key 都會對應一個編號在 0-16383 之間的哈希槽,通過這個值,去找到對應的插槽所對應的節點,然后直接自動跳轉到這個對應的節點上進行存取操作。

Redis 集群使用數據分片(sharding)而非一致性哈希(consistency hashing)來實現: 一個 Redis 集群包含 16384 個哈希槽(hash slot), 數據庫中的每個鍵都屬于這 16384 個哈希槽的其中一個, 集群使用公式 CRC16(key) % 16384 來計算鍵 key 屬于哪個槽, 其中 CRC16(key) 語句用于計算鍵 key 的 CRC16 校驗和 。

集群中的每個節點負責處理一部分哈希槽。 舉個例子, 一個集群可以有三個哈希槽, 其中:

節點 A 負責處理 0 號至 5500 號哈希槽。
節點 B 負責處理 5501 號至 11000 號哈希槽。
節點 C 負責處理 11001 號至 16384 號哈希槽。
這種將哈希槽分布到不同節點的做法使得用戶可以很容易地向集群中添加或者刪除節點。

為了保證高可用,redis-cluster集群引入了主從模式,一個主節點對應一個或者多個從節點,當主節點宕機的時候,就會啟用從節點。當其它主節點ping一個主節點A時,如果半數以上的主節點與A通信超時,那么認為主節點A宕機了。如果主節點A和它的從節點A1都宕機了,那么該集群就無法再提供服務了。

3.4 Redis-Cluster集群的優缺點

優點

解決分布式負載均衡的問題。具體解決方案是分片/虛擬槽slot。
可實現動態擴容
P2P模式,無中心化
缺點

為了性能提升,客戶端需要緩存路由表信息
Slave在集群中充當“冷備”,不能緩解讀壓力

redis 持久化 —— RDB(Redis DataBase)和 AOF(Append Only File)

關于Redis,目前都是使用Redis作為數據緩存,緩存的目標主要是那些需要經常訪問的數據,或計算復雜而耗時的數據。緩存的效果就是減少了數據庫讀的次數,減少了復雜數據的計算次數,從而提高了服務器的性能。

一、redis持久化----兩種方式

1、redis提供了兩種持久化的方式,分別是RDB(Redis DataBase)和AOF(Append Only File)。

2、RDB,簡而言之,就是在不同的時間點,將redis存儲的數據生成快照并存儲到磁盤等介質上

3、AOF,則是換了一個角度來實現持久化,那就是將redis執行過的所有寫指令記錄下來,在下次redis重新啟動時,只要把這些寫指令前到后再重復執行一遍,就可以實現數據恢復了。

4、其實RDBAOF兩種方式也可以同時使用,在這種情況下,如果redis重啟的話,則會優先采用AOF方式來進行數據恢復,這是因為AOF方式的數據恢復完整度更高。

5、如果你沒有數據持久化的需求,也完全可以關閉RDB和AOF方式,這樣的話,redis將變成一個純內存數據庫,就像memcache一樣。

二、redis持久化----RDB

1、RDB方式,是將redis某一時刻的數據持久化到磁盤中,是一種快照式的持久化方法。

2、redis在進行數據持久化的過程中,會先將數據寫入到一個臨時文件中,待持久化過程都結束了,才會用這個臨時文件替換上次持久化好的文件。正是這種特性,讓我們可以隨時來進行備份,因為快照文件總是完整可用的。

3、對于RDB方式,redis會單獨創建(fork)一個子進程來進行持久化,而主進程是不會進行任何IO操作的,這樣就確保了redis 極高的性能。

4、如果需要進行大規模數據的恢復,且對于數據恢復的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。

5、雖然RDB有不少優點,但它的缺點也是不容忽視的。如果你對數據的完整性非常敏感,那么RDB方式就不太適合你,因為即使你每5分鐘都持久化一次,當redis故障時,仍然會有近5分鐘的數據丟失。所以,redis還提供了另一種持久化方式,那就是AOF。

三、redis持久化----AOF

1、AOF,英文是Append Only File,即只允許追加不允許改寫的文件

2、如前面介紹的,AOF方式是將執行過的寫指令記錄下來,在數據恢復時按照從前到后的順序再將指令都執行一遍,就這么簡單。

3、我們通過配置redis.conf中的appendonly yes就可以打開AOF功能。如果有寫操作(如SET等),redis就會被追加到AOF文件的末尾。

4、默認的AOF持久化策略是每秒鐘fsync一次fsync是指把緩存中的寫指令記錄到磁盤中),因為在這種情況下,redis仍然可以保持很好的處理性能,即使redis故障,也只會丟失最近1秒鐘的數據。

5、如果在追加日志時,恰好遇到磁盤空間滿、inode滿斷電等情況導致日志寫入不完整,也沒有關系,redis提供了redis-check-aof工具,可以用來進行日志修復

6、因為采用了追加方式,如果不做任何處理的話,AOF文件會變得越來越大,為此,redis提供了AOF文件重寫(rewrite)機制,即當AOF文件的大小超過所設定的閾值時,redis就會啟動AOF文件的內容壓縮,只保留可以恢復數據的最小指令集。舉個例子或許更形象,假如我們調用了100次INCR指令,在AOF文件中就要存儲100條指令,但這明顯是很低效的,完全可以把這100條指令合并成一條SET指令,這就是重寫機制的原理。

7、在進行AOF重寫時,仍然是采用先寫臨時文件,全部完成后再替換的流程,所以斷電、磁盤滿等問題都不會影響AOF文件的可用性,這點大家可以放心。

8、AOF方式的另一個好處,我們通過一個“場景再現”來說明。某同學在操作redis時,不小心執行了FLUSHALL,導致redis內存中的數據全部被清空了,這是很悲劇的事情。不過這也不是世界末日,只要redis配置了AOF持久化方式,且AOF文件還沒有被重寫(rewrite),我們就可以用最快的速度暫停redis并編輯AOF文件,將最后一行的FLUSHALL命令刪除,然后重啟redis,就可以恢復redis的所有數據到FLUSHALL之前的狀態了。是不是很神奇,這就是AOF持久化方式的好處之一。但是如果AOF文件已經被重寫了,那就無法通過這種方法來恢復數據了

9、雖然優點多多,但AOF方式也同樣存在缺陷,比如在同樣數據規模的情況下,AOF文件要比RDB文件的體積大。而且,AOF方式的恢復速度也要慢于RDB方式。

如果你直接執行BGREWRITEAOF命令,那么redis會生成一個全新的AOF文件,其中便包括了可以恢復現有數據的最少的命令集。

10、如果運氣比較差,AOF文件出現了被寫壞的情況,也不必過分擔憂,redis并不會貿然加載這個有問題的AOF文件,而是報錯退出。這時可以通過以下步驟來修復出錯的文件:

1.備份被寫壞的AOF文件
2.運行redis-check-aof –fix進行修復
3.用diff -u來看下兩個文件的差異,確認問題點
4.重啟redis,加載修復后的AOF文件

四、redis持久化----AOF重寫

1、AOF重寫的內部運行原理,我們有必要了解一下。

2、在重寫即將開始之際,redis會創建(fork)一個“重寫子進程”,這個子進程會首先讀取現有的AOF文件,并將其包含的指令進行分析壓縮并寫入到一個臨時文件中。

3、與此同時,主工作進程會將新接收到的寫指令一邊累積到內存緩沖區中,一邊繼續寫入到原有的AOF文件中,這樣做是保證原有的AOF文件的可用性,避免在重寫過程中出現意外。

4、當“重寫子進程”完成重寫工作后,它會給父進程發一個信號,父進程收到信號后就會將內存中緩存的寫指令追加到新AOF文件中

5、當追加結束后,redis就會用新AOF文件來代替舊AOF文件,之后再有新的寫指令,就都會追加到新的AOF文件中了。

五、redis持久化----如何選擇RDB和AOF

1、對于我們應該選擇RDB還是AOF,官方的建議是兩個同時使用。這樣可以提供更可靠的持久化方案。

2、redis的備份和還原,可以借助第三方的工具redis-dump。

六、Redis的兩種持久化方式也有明顯的缺點

1、RDB需要定時持久化,風險是可能會丟兩次持久之間的數據,量可能很大。

2、AOF每秒fsync一次指令硬盤,如果硬盤IO慢,會阻塞父進程;風險是會丟失1秒多的數據;在Rewrite過程中,主進程把指令存到mem-buffer中,最后寫盤時會阻塞主進程。

redids事務 ACID

Redis 的事務需要先劃分出三個階段

事務開啟:使用 MULTI 可以標志著執行該命令的客戶端從非事務狀態切換至事務狀態;
命令入隊MULTI 開啟事務之后,非 WATCH、EXEC、DISCARD、MULTI
等特殊命令,客戶端的命令不會被立即執行,而是放入一個事務隊列;
如果收到 EXEC 命令,事務隊列里的命令將會被執行
如果收到 DISCARD 命令,則事務被丟棄
命令入隊過程如果出錯(如使用了不存在的命令),則事務隊列會被拒接執行;

執行事務:執行事務期間出現了異常(如命令和操作的數據類型不匹配),事務隊列的里的命令還是繼續執行下去,直到全部命令執行完,不會回滾。
WATCH 可用于監控 redis 變量值,在命令 EXEC 之前,redis 里的數據是有機會被其他客戶端的命令修改的。使用 WATCH
監控的變量被修改后,執行 EXEC 時則會返回執行失敗的 nil 回復

從嚴格意義上來說,Redis 是沒有事務的。因為事務必須具備四個特點:

原子性(Atomicity)
一致性(Consistency)
隔離性(Isolation)
持久性(Durability)

Redis 是做不到這四點,只是具備其中一些特征,redis的事務是個偽事務,而且不支持回滾。

原子性

EXEC命令執行前:

在命令入隊時就報錯,(如內存不足,命令名稱錯誤),redis 就會報錯并且記錄下這個錯誤。此時,客戶還能繼續提交命令操作;等到執行EXEC時,redis 就會拒絕執行所有提交的命令操作,返回事務失敗的結果 nil。

EXEC命令執行后:

命令和操作的數據類型不匹配,但 redis 實例沒有檢查出錯誤。在執行完 EXEC 命令以后,redis 實際執行這些指令,就會報錯。此時事務是不會回滾的,但事務隊列的命令還是繼續被執行。事務的原子性無法保證。

EXEC執行時發生故障:

如果 redis 開啟了 AOF 日志,那么,只會有部分的事務操作被記錄到 AOF 日志中。需要使用 redis-check-aof 工具檢查 AOF 日志文件,這個工具可以把未完成的事務操作從 AOF 文件中去除。事務的原子性得到保證。

一致性

EXEC命令執行前:

入隊報錯事務會被放棄執行,具有一致性。

EXEC命令執行后:

實際執行時報錯,錯誤的指令不會執行,正確的指令可以正常執行,一致性可以保證。

EXEC執行時發生故障:

RDB 模式,RDB 快照不會在事務執行時執行,事務結果不會保存在RDB;
AOF 模式,可以使用 redis-check-aof 工具檢查 AOF 日志文件,把未完成的事務操作從 AOF 文件中去除。可以保證一致性。

隔離性

EXEC 命令執行前:

隔離性需要通過 WATCH 機制保證。因為 EXEC 命令執行前,其他客戶端命令可以被執行,相關變量會被修改;但可以使用 WATCH 機制監控相關變量。一旦相關變量被修改,則 EXEC 后則事務失敗返回,具有隔離性。

EXEC 命令執行后:

Redis 是單線程執行,事務隊列里的命令和其他客戶端的命令只能二選一被順序執行,因此具有隔離性

持久性

如果 redis 沒有使用 RDB 或 AOF,事務的持久化是不存在的;
RDB 模式:那么在一個事務執行后,而下一次的 RDB快照還未執行前,如果發生了實例宕機,數據丟失,這種情況下,事務修改的數據也是不能保證持久化;
AOF 模式:因為 AOF 模式的三種配置選項 no、everysec 和 always
都會存在數據丟失的情況。所以,事務的持久性屬性也還是得不到保證。
總結

  1. Redis 的事務機制可以保證一致性和隔離性;
  2. 但是無法保證持久性;
  3. 具備了一定的原子性,但不支持回滾。

談一談緩存穿透、緩存擊穿和緩存雪崩,以及解決辦法

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/160249.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/160249.shtml
英文地址,請注明出處:http://en.pswp.cn/news/160249.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Cookie、Session、CBV加裝飾器的三種方法

【0】cookie、session和Token的發展史 【1】Cookie的形式 存儲形式:k:v鍵值對存儲位置:客戶端缺點:不安全,信息可能會泄露 【2】session的形式 標識符,表示我是當前用戶加密出來的數據對敏感信息進行加密…

排序算法-----快速排序(非遞歸實現)

目錄 前言 快速排序 基本思路 非遞歸代碼實現 前言 很久沒跟新數據結構與算法這一欄了,因為數據結構與算法基本上都發布完了,哈哈,那今天我就把前面排序算法那一塊的快速排序完善一下,前面只發布了快速排序遞歸算法,…

單鏈表相關面試題--3.鏈表的中間節點

3.鏈表的中間節點 876. 鏈表的中間結點 - 力扣(LeetCode) /* 解題思路: 通過快慢指針找到中間節點,快指針每次走兩步,慢指針每次走一步,當快指針走到結尾的時候,慢指針正好走到中間位置 */ typ…

HTTPS協議的加密流程

目錄 一,HTTPS是什么 二,兩種加密方式 三,HTTPS的加密過程 3.1 引入對稱加密 3.2 引入非對稱加密 3.3 引入證書 一,HTTPS是什么 HTTPS也是一個應用層協議,它是在HTTP協議的基礎上引入了一個加密層。因為HTTP協議…

每天一道算法題(十)——獲取和為k的子數組

文章目錄 1、問題2、示例3、解決方法(1)方法1——雙指針 總結 1、問題 給你一個整數數組 nums 和一個整數 k ,請你統計并返回 該數組中和為 k 的子數組的個數 。 子數組是數組中元素的連續非空序列。 2、示例 示例 1: 輸入&#x…

多分類自定義采樣比例

多分類自定義采樣比例 import torch from torch.utils.data import DataLoader, Dataset, WeightedRandomSampler from torchvision import transforms from torchvision.datasets import ImageFolder# 假設你有一個自定義的數據集類 class CustomDataset(Dataset):def __init…

51單片機按鍵控制LED燈亮滅的N個玩法

51單片機按鍵控制LED燈亮滅的N個玩法 1.概述 這篇文章介紹按鍵的使用,以及通過控制LED燈的小實驗,發現按鍵中存在的問題,然后思考并解決這些問題。達到熟練使用按鍵控制元器件。 2.搭建硬件環境 1.硬件準備 名稱型號數量單片機STC12C205…

2023全球數字貿易創新大賽9-12

目錄 回答評委提問:先說痛點-再說怎樣解決 食品安全溯源是否全流程 星火? 鏈網

Sleuth

Sleuth 一 引言 隨著服務的越來越多,對調?鏈的分析會越來越復雜。它們之間的調?關系也許如下圖: 問題: 1:微服務之間的調?錯綜復雜,?戶發送的請求經歷那些服務,調?鏈不清楚,沒有? 個?…

【SpringCloud微服務全家桶學習筆記-Hystrix(服務降級,熔斷,接近實時的監控,服務限流等)】

服務雪崩 (微服務面臨的問題) 多個微服務之間調用的時候,假設微服務A調用微服務B和微服務C,微服務B和微服務C又調用其它的微服務,這就是所謂的“扇出”。如果扇出的鏈路上某個微服務的調用響應時間過長或者不可用&…

HarmonyOS開發(五):常用基礎組件

1、組件介紹 組件(Component),是界面搭建及顯示的最小單元。 組件根據功能可以分為五大類:基礎組件、容器組件、媒體組件、繪制組件、畫布組件 2、基礎組件 基礎組件是視圖層的基本組成單元,它包含:Text、Image、T…

OpenCV C++ 張正友相機標定【相機標定原理、相機標定流程、圖像畸變矯正】

文章目錄 3.1 標定原理3.2 相機標定流程步驟1:采集棋盤格圖像,批處理(調整尺寸、重命名)步驟2:提取棋盤格內角點坐標步驟3:進一步提取亞像素角點信息在棋盤標定圖上繪制找到的內角點(非必須,僅為了顯示)步驟4:相機標定--計算出相機內參數矩陣和畸變系數步驟5:畸變圖像…

Spring (二)@Order, Ordered 失效

Spring (二)Order, Ordered 失效 先上例子 public class OrderAnnotationExample {Order(2)static class MyBeanFactoryPostProcessor1 implements BeanFactoryPostProcessor {Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFa…

如何加速JavaScript 代碼運行速度

如何加速JavaScript 代碼運行速度 前言減少DOM訪問避免不必要的變量延遲script加載異步和同步使用異步編程避免使用With關鍵詞 前言 本文主要通過五個方面來講解如何使Js代碼得到性能優化,從而實現加快Js代碼運行速度的作用。那么好,本文正式開始。 減…

感染了后綴為.[bkpsvr@firemail.cc].EKING勒索病毒如何應對?數據能夠恢復嗎?

導言: 在當前數字時代,勒索病毒成為網絡威脅的一大隱患。本文將深入介紹一種名為[bkpsvrfiremail.cc].EKING的勒索病毒,以及如何應對遭受其攻擊后,有效地恢復被加密的數據文件,并提供一些預防措施以減少感染的風險。數…

sqlserver==索引解析,執行計劃,索引大小

1創建測試表 -- 創建大型表 CREATE TABLE LargeTableWithIndex (ID int IDENTITY(1,1) PRIMARY KEY,IndexedColumn int,NonIndexedColumn nvarchar(255),OtherData nvarchar(255) );2插入測試數據 -- 使用 T-SQL 插入大量數據 DECLARE @i int = 1; WHILE @i <= 100000 -- …

Mac中LaTex無法編譯的問題

最近在使用TexStudio時&#xff0c;遇到一個棘手的問題&#xff1a; 無法編譯&#xff0c;提示如下&#xff1a; kpathsea: Running mktexfmt xelatex.fmt /Library/TeX/texbin/mktexfmt: kpsewhich -var-valueTEXMFROOT failed, aborting early. BEGIN failed–compilation a…

[Linux] Network: IPv6 link-local 地址是否可用不自動生成

原來有一段時間在做擴充產品的VLAN個數&#xff0c;然后就遇到過一個問題&#xff1a;說這個Linux的默認配置里&#xff0c;會為每一個網絡接口添加一個link-local的地址&#xff0c;就是FE80::開頭的地址&#xff0c;在RFC-4291里有如下的定義&#xff1a; Link-Local unicas…

redis運維(十二) 位圖

一 位圖 ① 概念 1、說明&#xff1a;位圖還是在操作字符串2、位圖玩字符串在內存中存儲的二進制3、ASCII字符通過映射轉化為二進制4、操作的是字符串value ② ASCII字符鋪墊 1、控制ASCII字符 2、ASCII可顯示字符 ③ SETBIT 細節&#xff1a; setbit 命令的返回值是之…