主頁 >  其他 > Redis集群介紹及測驗思路

Redis集群介紹及測驗思路

2023-04-08 07:39:23 其他

作者:京東零售 李磊

Redis集群介紹

Redis集群一般有四種方式,分別為:主從復制、哨兵模式、Cluster以及各大廠的集群方案,在3.0版本之前只支持單實體模式,3.0之后支持了集群方式,在3.0之前各大廠為了解決單實體Redis的存盤瓶頸問題各自推出了自己的集群方案,其核心思想就是資料分片,主要有客戶端分片、代理分片、服務端分片,這里咱們只介紹前三種方式:主從、哨兵、Cluster,

1、主從復制

Redis單節點的資料是存盤在一臺服務器上的,如果服務器出現故障,會導致資料不可用,而且讀寫都是在同一臺服務器上,請求量大時會出現I/O瓶頸,為了避免單點故障和讀寫不分離,Redis提供了復制功能來實作Master中的資料向Slave資料庫的同步,Master可以有多個Slave節點,Slave節點也可以有Slave節點,從節點是級聯結構,如下圖所示:

主從復制作業原理

一般情況下為了讓資料讀寫分離,Master節點用來執行寫操作,Slave節點提供讀操作,Master執行寫操作時將變化的資料同步到Slave,其作業原理如下圖所示:

Redis主從復制基本原理有三種:全量復制、基于長連接的命令傳播、增量復制,

首先介紹一下全量復制,當主從服務器剛建立連接的時候,會按照三個階段完成資料的第一次同步,假設現在有實體1(192.168.1.1)和實體2(192.168.1.2),當我們在實體2上執行“replicaof 192.168.1.1 6379”命令后,實體2就變成了實體1的從庫,并開始從實體1上復制資料,有如下三個階段:

第一個階段,是主從庫之間建立連接、協商同步的程序,為全量復制做準備,具體來說,從庫給主庫發送psync命令,表示要進行資料同步,主庫根據這個命令的引數來啟動復制,psync命令包含了主庫的runID和復制進度offset兩個引數,

?runID:是每個Redis實體啟動時自動生成的一個隨機ID,用來唯一標記這個實體,當從庫和主庫第一次復制時,因為不知道主庫的runID,所以將runID設定為“?”,

?offset:設定為-1,表示第一次復制,

主庫收到psync命令后,會用FULLRESYNC回應命令帶上兩個引數:主庫runID和主庫目前的復制進度offset,回傳給從庫,從庫收到回應后會記錄下這兩個引數,FULLRESYNC回應表示第一次復制采用的全量復制,也就是說,主庫會把當前所有的資料都復制給從庫,

第二個階段,主庫將所有資料同步給從庫,從庫收到資料后,首先清空現有資料,然后在本地完成資料加載,這個程序依賴于記憶體快照生成的RDB檔案,具體來說,主庫執行bgsave命令,生成RDB檔案,接著將檔案發給從庫,

第三個階段,主庫會把第二階段執行程序中新接收到的寫命令,再發送給從庫,具體來說,當主庫完成RDB檔案發送后,就會把此時replication buffer中的修改和新增操作發給從庫,從庫再重新執行這些操作,這樣一來,主從庫就實作同步了,

以上是全量復制的基本流程,一旦主從庫完成了全量復制,它們之間就會一直維護一個網路連接,主庫會通過這個連接將后續陸續收到的命令操作再同步給從庫,這個程序也稱為基于長連接的命令傳播,可以避免頻繁建立連接的開銷,

長連接是基于網路的,那么它就存在網路斷開的風險,在Redis2.8之前,如果主從庫在命令傳播時出現了網路閃斷,那么從庫會和主庫重新進行一次全量復制,開銷非常大,在Redis2.8開始,網路閃斷之后,主從庫會采用增量復制的方式繼續同步,就只會把主從網路斷連期間主庫收到的命令同步給從庫,

增量復制核心在于repl_backlog_buffer這個緩沖區,當主從庫斷連后,主庫會把斷連期間收到的寫操作命令寫入replication buffer,同時也會寫入repl_backlog_buffer這個緩沖區,repl_backlog_buffer是一個環形緩沖區,主庫記錄自己寫到的位置,從庫也記錄自己讀到的位置,主從連接恢復之后,從庫首先給主庫發送psync命令,并把自己當前的slave_repl_offset發給主庫,主庫會判斷自己的master_repl_offset和slave_repl_offset之間的差距,一般來說master_repl_offset會大于slave_repl_offset,此時,主庫只用把master_repl_offset和slave_repl_offset之間的命令操作同步給從庫就行,

2、哨兵模式

sentinel,中文名哨兵,Redis的sentinel系統用于管理多個Redis實體,該系統主要執行以下四個任務:

1.監控(Monitoring):Sentinel會不斷的檢查主服務器和從服務器是否正常運作,

2.自動故障轉移(Automatic failover):當主節點不能正常作業時,哨兵會開始自動故障轉移操作,它會將失效主節點的其中一個從節點升級為新的主節點,并讓其他從節點改為復制新的主節點,

3.通知(Notification):哨兵可以將故障轉移的結果發送給客戶端,

4.配置提供者(Configuration provider):客戶端在初始化時,通過連接哨兵來獲得當前Redis服務的主節點地址,

其中,監控和自動故障轉移功能,使得哨兵可以及時發現主節點故障并完成轉移;而配置提供者和通知功能,則需要在與客戶端的互動中才能體現,

哨兵用于實作Redis集群的高可用性,本身也是分布式的,作為一個哨兵集群去運行,Sentinel的行程之間使用流言協議(gossip protocols)來接收關于主服務器是否下線的資訊, 并使用投票協議(agreement protocols)來決定是否執行自動故障遷移, 以及選擇哪個從服務器作為新的主服務器,下面分別介紹一下監控和自動故障轉移的基本原理:

Sentinel集群監控原理

1.每個 Sentinel 以每秒一次的頻率向它所知的主從服務器以及其它 Sentinel 實體發送一個 PING 命令,

2.如果一個實體距離最后一次有效回復 PING 命令的時間超過指定的值, 那么這個實體會被 Sentinel 標記為主觀下線,

3.正在監視這個主服務器的所有 Sentinel 要以每秒一次的頻率確認主服務器的確進入了主觀下線狀態,

4.有足夠數量的 Sentinel 在指定的時間范圍內同意這一判斷, 那么這個主服務器被標記為客觀下線,

5.每個 Sentinel 會以每 10 秒一次的頻率向它已知的所有主從服務器發送 INFO 命令,當一個主服務器被 Sentinel 標記為客觀下線時, Sentinel 向下線主服務器的所有從服務器發送 INFO 命令的頻率會從 10 秒一次改為每秒一次,

6.Sentinel 和其它 Sentinel 協商主節點的狀態,如果主節點處于 ODOWN(客觀下線) 狀態,則投票自動選出新的主節點,將剩余的從節點指向新的主節點進行資料復制,

7.當沒有足夠數量的 Sentinel 同意主服務器 下線時, 主服務器的客觀下線狀態就會被移除,主服務器重新向 Sentinel 的 PING 命令回傳有效回復時,主服務器主觀下線狀態就會被移除 ,

哨兵是如何對Slave進行監控的呢?當然是通過Master來實作的,哨兵向Master發送INFO命令,Master收到命令后便將Slave串列告訴哨兵,然后哨兵根據Slave串列資訊與每一個Slave建立連接,并且根據這個連接持續監控Slave,

Sentinel集群故障自動轉移

故障轉移簡單來說有以下三個流程:

1.Sentinel系統挑選出現故障的主服務器屬下的其中一個從服務器,并將選中的從服務器升級為新的主服務器,

2.Sentinel系統向出現故障的主服務器屬下的所有從服務器發送新的復制命令,讓他們成為新的主服務器的從服務器,當所有從服務器都開始復制新的主服務器時,故障轉移操作執行完畢,

3.Sentinel系統還會繼續監聽已下線的故障服務器,如果它重新上線時,會將它設定為新的主服務器的從服務器,

示意圖

如上圖所示,Server1為Master節點,Server2、Server3、Server4為主服務器Server1的從節點,而Sentinel系統正在監視所有4個服務器

故障轉移

如上圖所示,主服務server1掛掉了,處于下線狀態,那么server2、server3、server4對主服務器的復制操作將被終止,Server2被Sentinel系統升級為新的Master,然后將Server2和Server3轉為新Master的從服務器,完成故障轉移,同時繼續監聽已下線的Server1,

如上圖所示當Server1恢復后,Sentinel系統將它設定為新的主服務器Server2的從服務器,集群恢復原有狀態,

3、Cluster集群

Redis的哨兵模式基本已經可以實作高可用,讀寫分離 ,但是在這種模式下每臺Redis服務器都存盤相同的資料,很浪費記憶體,所以在redis3.0上加入了Cluster集群模式,實作了Redis的分布式存盤,也就是說每臺 Redis 節點上存盤不同的內容,Redis集群是由多個主從節點群組成的分布式服務集群,具有復制、高可用和分片特性,這種集群模式沒有中心節點,可水平擴展,主要是針對海量資料、高并發、高可用的場景,

Cluster集群模式主要有以下三個特性:

1.分片存盤:Redis3.0加入了 Redis 的集群模式,實作了資料的分布式存盤,對資料進行分片,將不同的資料存盤在不同的master節點上面,從而解決了海量資料的存盤問題,

2.指令轉換:Redis集群采用去中心化的思想,沒有中心節點的說法,對于客戶端來說,整個集群可以看成一個整體,可以連接任意一個節點進行操作,就像操作單一Redis實體一樣,不需要任何代理中間件,當客戶端操作的key沒有分配到該node上時,Redis會回傳轉向指令,指向正確的Redis節點,

3.主從和哨兵:Redis也內置了高可用機制,支持N個master節點,每個master節點都可以掛載多個slave節點,當master節點掛掉時,集群會提升它的某個slave節點作為新的master節點,

如上圖所示,Redis集群可以看成多個主從架構組合起來的,每一個主從架構可以看成一個節點,

Redis集群資料分片原理

集群的整個資料庫被分為 16384 個槽(slot),資料庫中的每個鍵都屬于這 16384 個槽的其中一個,集群中的每個節點可以處理 0 個或最多 16384 個槽,

Key 與哈希槽映射程序可以分為兩大步驟:

1.根據鍵值對的 key,使用 CRC16 演算法,計算出一個 16 bit 的值,

2.將 16 bit 的值對 16384 執行取模,得到 0 ~ 16383 的數表示 key 對應的哈希槽,

另外,Cluster 還允許用戶強制某個 key 掛在特定槽位上,通過在 key 字串里面嵌入 tag 標記,這就可以強制 key 所掛在的槽位等于 tag 所在的槽位,

Cluster集群請求路由方式

客戶端直連 Redis 服務,進行讀寫操作時,若Key 對應的 Slot在當前直連的節點上,則可直接讀寫,但也有可能并不在當前直連的節點上,則經過“重定向”才能轉發到正確的節點,如下圖所示

和普通的查詢路由相比,Redis Cluster 借助客戶端實作的請求路由是一種混合形式的查詢路由,它并非從一個 Redis 節點到另外一個 Redis,而是借助客戶端轉發到正確的節點,實際應用中,可以在客戶端快取 Slot 與 Redis 節點的映射關系,當接收到 MOVED 回應時修改快取中的映射關系,如此,基于保存的映射關系,請求時會直接發送到正確的節點上,從而減少一次互動,提升效率,

那么客戶端具體是怎么確定訪問的資料到底分布在哪個實體上呢?

Redis 實體會將自己的哈希槽資訊通過 Gossip 協議發送給集群中其他的實體,實作了哈希槽分配資訊的擴散,這樣,集群中的每個實體都有所有哈希槽與實體之間的映射關系資訊,在切片資料的時候是將 key 通過 CRC16 計算出一個值再對 16384 取模得到對應的 Slot,這個計算任務可以在客戶端上執行發送請求的時候執行,但是,定位到槽以后還需要進一步定位到該 Slot 所在 Redis 實體,當客戶端連接任何一個實體,實體就將哈希槽與實體的映射關系回應給客戶端,客戶端就會將哈希槽與實體映射資訊快取在本地,當客戶端請求時,會計算出鍵所對應的哈希槽,在通過本地快取的哈希槽實體映射資訊定位到資料所在實體上,再將請求發送給對應的實體,

這個時候大家可能會有個疑問:哈希槽與實體之間的映射關系由于新增實體或者負載均衡重新分配導致改變了咋辦?

集群中的實體通過 Gossip 協議互相傳遞訊息獲取最新的哈希槽分配資訊,但是,客戶端無法感知,Redis Cluster 提供了重定向機制:客戶端將請求發送到實體上,這個實體沒有相應的資料,該 Redis 實體會告訴客戶端將請求發送到其他的實體上,

Redis 如何告知客戶端重定向訪問新實體呢?分為兩種情況:MOVED 錯誤、ASK 錯誤,

MOVED 錯誤(負載均衡,資料已經遷移到其他實體上):當客戶端將一個鍵值對操作請求發送給某個實體,而這個鍵所在的槽并非由自己負責的時候,該實體會回傳一個 MOVED 錯誤指引轉向正在負責該槽的節點,

(error) MOVED 16330 172.17.18.2:6379

該回應表示客戶端請求的鍵值對所在的哈希槽 16330 遷移到了 172.17.18.2 這個實體上,埠是 6379,這樣客戶端就與 172.17.18.2:6379 建立連接,并發送 GET 請求,同時,客戶端還會更新本地快取,將該 slot 與 Redis 實體對應關系更新正確,

ASK 錯誤:如果某個 slot 的資料比較多,部分遷移到新實體,還有一部分沒有遷移咋辦?

如果請求的 key 在當前節點找到就直接執行命令,否則就需要 ASK 錯誤回應了,槽部分遷移未完成的情況下,如果需要訪問的 key 所在 Slot 正在從從 實體 1 遷移到 實體 2,實體 1 會回傳客戶端一條 ASK 報錯資訊:客戶端請求的 key 所在的哈希槽正在遷移到實體 2 上,你先給實體 2 發送一個 ASKING 命令,接著發送操作命令,

(error) ASK 16330 172.17.18.2:6379

比如客戶端請求定位到 key的槽16330 在實體 172.17.18.1 上,節點1如果找得到就直接執行命令,否則回應 ASK 錯誤資訊,并指引客戶端轉向正在遷移的目標節點 172.17.18.2:6379

注意:ASK 錯誤指令并不會更新客戶端快取的哈希槽分配資訊,所以客戶端再次請求 Slot 16330 的資料,還是會先給 172.17.18.1 實體發送請求,只不過節點會回應 ASK 命令讓客戶端給新實體發送一次請求,MOVED指令則更新客戶端本地快取,讓后續指令都發往新實體,

Cluster集群選舉演算法

1.集群的配置紀元 +1,是一個自曾計數器,初始值 0 ,每次執行故障轉移都會 +1,

2.檢測到主節點下線的從節點向集群廣播一條
CLUSTERMSG_TYPE_FAILOVER_AUTH_REQUEST訊息,要求所有收到這條訊息、并且具有投票權的主節點向這個從節點投票,

3.這個主節點尚未投票給其他從節點,那么主節點將向要求投票的從節點回傳一條
CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK訊息,表示這個主節點支持從節點成為新的主節點,

4.參與選舉的從節點都會接收
CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK訊息,如果收集到的票 >= (N/2) + 1 支持,那么這個從節點就被選舉為新主節點,

5.如果在一個配置紀元里面沒有從節點能收集到足夠多的支持票,那么集群進入一個新的配置紀元,并再次進行選舉,直到選出新的主節點為止,

流程如下圖所示:

Cluster集群故障轉移

Redis集群的故障轉移主要有三個流程:故障檢測、選主流程、故障轉移,下面分別簡單介紹一下,

?故障檢查

一個節點認為某個節點失聯了并不代表所有的節點都認為它失聯了,只有當大多數負責處理 slot 的節點都認定了某個節點下線了,集群才認為該節點需要進行主從切換,Redis 集群節點采用 Gossip協議來廣播自己的狀態以及自己對整個集群認知的改變,比如一個節點發現某個節點失聯了 (PFail),它會將這條資訊向整個集群廣播,其它節點也就可以收到這個節點的失聯資訊,

如果一個節點收到了某個節點失聯的數量 (PFail Count) 已經達到了集群的大多數,就可以標記該節點為確定下線狀態 (Fail),然后向整個集群廣播,強迫其它節點也接收該節點已經下線的事實,并立即對該失聯節點進行主從切換,

?選主流程

參考上一節的“Cluster集群選舉演算法”

?故障轉移

當一個 Slave 發現自己的主節點進入已下線狀態后,從節點將開始對下線的主節點進行故障轉移,

1.從下線的 Master 節點的 Slave 節點串列選擇一個節點成為新主節點,

2.新主節點會撤銷所有對已下線主節點的 slot 指派,并將這些 slots 指派給自己,

3.新的主節點向集群廣播一條 PONG 訊息,這條 PONG 訊息可以讓集群中的其他節點立即知道這個節點已經由從節點變成了主節點,并且這個主節點已經接管了原本由已下線節點負責處理的槽,

4.新的主節點開始接收處理槽有關的命令請求,故障轉移完成,

Cluster集群擴容與縮容

擴容

Redis集群主要有兩種擴容方式:垂直擴容和水平擴容,

垂直擴容:增加記憶體方式來增加快取實體的系統容量,比如從2G增加到4G,

水平擴容:通過增加節點的方式來增加整個快取系統的容量,

垂直擴容比較方便,但是受制于機制記憶體的限制,一個機器不可能無限增大記憶體, 所以到了一定階段肯定要進行水平擴容,下面我們主要講一下水平擴容,

水平擴容又有兩種方式:1、主節點數量不變;2、增加主節點數量

1、主節點數量不變:比如,當前有一臺物理機 A,構建了一個包含3個 Redis 實體的集群;擴容時,我們新增一臺物理機 B,拉起一個 Redis 實體并加入物理機 A 的集群;B 上 Redis 實體對 A 上的一個主節點進行復制,然后進行主備倒換;如此,Redis 集群還是3個主節點,只不過變成了 A2-B1 的結構,將一部分請求壓力分擔到了新增的節點上,同時物理容量上限也會增加,主要步驟如下:

1.將新增節點加入集群;

2.將新增節點設定為某個主節點的從節點,進而對其進行復制;

3.進行主備倒換,將新增的節點調整為主,

2、增加主節點數量:不增加主節點數量的方式擴容比較簡單,但是,從負載均衡的角度來看,并不是很好的選擇,例如,如果主節點數量較少,那么單個節點所負責的 Slot 的數量必然較多,很容易出現大量 Key 的讀寫集中于少數節點的現象,而增加主節點的數量,可以更有效的分攤訪問壓力,充分利用資源,主要步驟如下:

1.將新增節點加入集群;

2.將集群中的部分 Slot 遷移至新增的節點,

縮容

?如果下線的是slave,那么通知其他節點忘記下線的節點

?如果下線的是master,那么將此master的slot遷移到其他master之后,通知其他節點忘記此master節點

?其他節點都忘記了下線的節點之后,此節點就可以正常停止服務了

Redis集群測驗思路及常見問題

集群搭建好之后,就可以對集群的各種功能和使用進行測驗了,一般我們會從兩個方面來制定測驗計劃:1、集群功能測驗;2、集群調優測驗

1、集群功能測驗

集群功能測驗屬于最基本的測驗,是為了驗證集群所提供的各種功能是否能正常使用,主要有以下方面的內容:

?主從節點的資料備份是否正常

?主從節點的切換功能是否正常

?監控及故障轉移功能是否正常

?集群擴縮容功能是否正常

集群的功能測驗類似于黑盒測驗,內容比較簡單,在這里我們就不展開介紹了,下面主要介紹一下集群在使用程序中的調優測驗,

2、集群調優測驗

集群調優測驗,是為了驗證集群在提供服務時,如何最大限度避免因各種例外導致資料丟失或者快取功能失效,提前對配置進行調優或者提前預案,從而保證快取架構設計是最優的,需要注意的點主要有:集群腦裂、快取穿透、快取擊穿、快取雪崩、快取預熱、快取降級、快取更新,下面分別介紹一下定義以及解決方案,

集群腦裂

定義

當Redis主從集群環境出現兩個主節點為客戶端提供服務,這時客戶端請求命令可能會發生資料丟失的情況,腦裂產生的場景主要有兩個:

1.如果哨兵正在進行選舉,故障轉移的程序中原主節點恢復和客戶端的通信,那么證明原主節點沒有真正的故障,這時客戶端依舊可以向原主節點正常通信,但是當故障轉移結束后,就又產生了一個主節點,這就是腦裂產生的第一個場景,如下圖所示:

2. 網路磁區,主節點和客戶端,哨兵和從庫分割為了兩個網路,主庫和客戶端處在一個網路中,從庫和哨兵在另外一個網路中,此時哨兵也會發起主從切換,出現兩個主節點的情況,如下圖所示:

腦裂出現后帶來最嚴重的后果就是資料丟失,為什么會出現資料丟失的問題呢?

主要原因是新主庫確定后會向所有的實體發送slave of命令,讓所有實體重新進行全量同步,而全量同步首先就會將實體上的資料先清空,所以在主從同步期間在原主庫執行的命令將會被清空(上面場景二是同樣的道理,在網路磁區恢復后原主節點將被降級為從節點,并且執行全量同步導致資料丟失),所以這就是資料丟失的具體原因,如下圖所示:

解決方案

應對腦裂的解決辦法應該是去限制原主庫接收請求,Redis提供了兩個配置項:

1.min-replicas-to-write:主庫能進行資料同步的最少從庫數量,否則主節點拒絕寫入,

2.min-replicas-max-lag:主從庫間進行資料復制時,從庫給主庫發送ACK訊息的最大延遲(單位s),否則主節點拒絕寫入,

這兩個配置項必須同時滿足,不然主節點拒絕寫入,

即使原主假故障,假故障期間也無法回應哨兵心跳,也不能和從庫進行同步,自然就無法和從庫進行ACK確認,這倆配置項組合要求就無法得到滿足,原主庫就會被限制接收客戶端請求,客戶端也就不能在原主庫中寫新資料,等新主上線,就只有新主能接收和處理客戶端請求,此時,新寫的資料會被直接寫到新主,而原主會被哨兵降為從庫,即使它的資料被清空,也不會有新資料的丟失,示例如下:

假設:

min-replicas-to-write=1

min-replicas-max-lag設為12s

哨兵的down-after-milliseconds設為10s

主庫因某原因卡住15s,導致哨兵判斷主庫客觀下線,開始進行主從切換, 同時,因原主庫卡住15s,沒有一個從庫能和原主庫在12s內進行資料復制,原主庫也無法接收客戶端請求,主從切換完成后,也只有新主庫能接收請求,不會發生腦裂,也就不會發生資料丟失,

但是,在實際應用中,真的能完全避免資料的丟失嗎?我們看下面的例子:

假設:

min-replicas-to-write 置 1

min-replicas-max-lag 設定為 15s

哨兵的down-after-milliseconds 設定為 10s 哨兵主從切換需要 5s,主庫因為某些原因卡住12s,此時,還會發生腦裂嗎?主從切換完成后,資料會丟失嗎?

主庫卡住 12s,達到哨兵設定的切換閾值,所以哨兵會觸發主從切換,但哨兵切換時間5s,即哨兵還未切換完成,主庫就會從阻塞狀態中恢復回來,且沒有觸發 min-slaves-max-lag 閾值,所以主庫在哨兵切換剩下的 3s 內,依舊可以接收客戶端的寫操作,如果這些寫操作還未同步到從庫,哨兵就把從庫提升為主庫了,那么此時也會出現腦裂的情況,之后舊主庫降級為從庫,重新同步新主庫的資料,新主庫也會發生資料丟失,

所以,即使 Redis 配置了 min-replicas-to-write 和 min-replicas-max-lag,當腦裂發生時,還是無法嚴格保證資料不丟失,只是盡量減少資料的丟失,我們需要根據被測系統的性能、網路情況、流量情況來調優這兩個引數的配置,當出現例外的時候盡可能最小的縮減資料丟失的時間,

快取穿透

定義

當查詢Redis中沒有的資料時,該查詢會下沉到資料庫層,同時資料庫層也沒有該資料,當這種情況大量出現或被惡意攻擊時,介面的訪問全部透過Redis訪問資料庫,而資料庫中也沒有這些資料,我們稱這種現象為"快取穿透",快取穿透會穿透Redis的保護,提升底層資料庫的負載壓力,同時這類穿透查詢沒有資料回傳也造成了網路和計算資源的浪費,

解決方案

1.在介面訪問層對用戶做校驗,如介面傳參、登陸狀態、n秒內訪問介面的次數;

2.利用布隆過濾器,將資料庫層有的資料key存盤在位陣列中,以判斷訪問的key在底層資料庫中是否存在;核心思想是布隆過濾器,在redis里也有bitmap位圖的類似實作,布隆過濾器不能實作動態洗掉,有時間可以研究下布谷鳥過濾器,是布隆過濾器增強版本,布隆過濾器有誤判率,雖然不能完全避免資料穿透的現象,但已經可以將99.99%的穿透查詢給屏蔽在Redis層了,極大的降低了底層資料庫的壓力,減少了資源浪費,

基于布隆過濾器,我們可以先將資料庫中資料的key存盤在布隆過濾器的位陣列中,每次客戶端查詢資料時先訪問Redis:

?如果Redis內不存在該資料,則通過布隆過濾器判斷資料是否在底層資料庫內;

?如果布隆過濾器告訴我們該key在底層庫內不存在,則直接回傳null給客戶端即可,避免了查詢底層資料庫的動作;

?如果布隆過濾器告訴我們該key極有可能在底層資料庫記憶體在,那么將查詢下推到底層資料庫即可;

快取擊穿

定義

快取擊穿和快取穿透從名詞上可能很難區分開來,它們的區別是:穿透表示底層資料庫沒有資料且快取內也沒有資料,擊穿表示底層資料庫有資料而快取內沒有資料,當熱點資料key從快取內失效時,大量訪問同時請求這個資料,就會將查詢下沉到資料庫層,此時資料庫層的負載壓力會驟增,我們稱這種現象為"快取擊穿",

解決方案

?延長熱點key的過期時間或者設定永不過期,如排行榜,首頁等一定會有高并發的介面;

?利用互斥鎖保證同一時刻只有一個客戶端可以查詢底層資料庫的這個資料,一旦查到資料就快取至Redis內,避免其他大量請求同時穿過Redis訪問底層資料庫;

快取雪崩

定義

快取雪崩是快取擊穿的"大面積"版,快取擊穿是資料庫快取到Redis內的熱點資料失效導致大量并發查詢穿過redis直接擊打到底層資料庫,而快取雪崩是指Redis中大量的key幾乎同時過期,然后大量并發查詢穿過redis擊打到底層資料庫上,此時資料庫層的負載壓力會驟增,我們稱這種現象為"快取雪崩",

事實上快取雪崩相比于快取擊穿更容易發生,對于大多數公司來講,同時超大并發量訪問同一個過時key的場景的確太少見了,而大量key同時過期,大量用戶訪問這些key的幾率相比快取擊穿來說明顯更大,

解決方案

1.在可接受的時間范圍內隨機設定key的過期時間,分散key的過期時間,以防止大量的key在同一時刻過期;

2.對于一定要在固定時間讓key失效的場景(例如每日12點準時更新所有最新排名),可以在固定的失效時間時在介面服務端設定隨機延時,將請求的時間打散,讓一部分查詢先將資料快取起來;

3.延長熱點key的過期時間或者設定永不過期,這一點和快取擊穿中的方案一樣;

快取預熱

如字面意思,當系統上線時,快取內還沒有資料,如果直接提供給用戶使用,每個請求都會穿過快取去訪問底層資料庫,如果并發大的話,很有可能在上線當天就會宕機,因此我們需要在上線前先將資料庫內的熱點資料快取至Redis內再提供出去使用,這種操作就成為"快取預熱",

快取預熱的實作方式有很多,比較通用的方式是寫個批任務,在啟動專案時或定時去觸發將底層資料庫內的熱點資料加載到快取內,

快取降級

?快取降級是指當訪問量劇增、服務出現問題(如回應時間慢或不回應)或非核心服務影響到核心流程的性能時,即使是有損部分其他服務,仍然需要保證主服務可用,可以將其他次要服務的資料進行快取降級,從而提升主服務的穩定性,

?降級的目的是保證核心服務可用,即使是有損的,如某年雙十一的時候淘寶購物車無法修改地址只能使用默認地址,這個服務就是被降級了,這里阿里保證了訂單可以正常提交和付款,但修改地址的服務可以在服務器壓力降低,并發量相對減少的時候再恢復,

?降級可以根據實時的監控資料進行自動降級也可以配置開關人工降級,是否需要降級,哪些服務需要降級,在什么情況下再降級,取決于大家對于系統功能的取舍,

快取更新

快取服務(Redis)和資料服務(底層資料庫)是相互獨立且異構的系統,在更新快取或更新資料的時候無法做到原子性的同時更新兩邊的資料,因此在并發讀寫或第二步操作例外時會遇到各種資料不一致的問題,如何解決并發場景下更新操作的雙寫一致是快取系統的一個重要知識點,

參考檔案: 《Redis設計與實作》-黃健宏著
https://www.cnblogs.com/yizhiamumu/p/16704556.htmlhttps://cloud.tencent.com/developer/article/1981186

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/549420.html

標籤:其他

上一篇:[paper reading]|IC-FPS: Instance-Centroid Faster Point Sampling Module for 3D Point-base

下一篇:ChatGPT 與 Midjourney 強強聯手,讓先秦阿房宮重現輝煌!

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more