更新時間:2022-12-28 15:15:31 來源:動力節點 瀏覽1193次
1.談談Redis集群數據hash分片算法
Redis 集群將所有數據劃分16384個slots,每個節點負責其中一部分槽位。當Redis 集群的客戶端來連接集群時,它也會得到一份集群的槽位信息并將其緩存到客戶端本地,這樣當客戶端要查找某個key時,可以根據槽位定位算法定位到目標節點。
槽位定位算法
集群默認會對key值使用crc16算法進行hash,得到一個整數值,然后這個整數值對16384進行取模運算來得到具體的槽位。
Hash_slot = CRC16(key)mod13684
再根據槽位和節點的對應關系就可以定位到key具體是在那個Redis節點上。
2.Redis執行命令竟然有死循環阻塞Bug
Redis有個RANDOMKEY命令可以從Redis中隨機取出一個key,這個命令可能導致Redis死循環阻塞。
RANDOMKEY在隨機拿出一個key之后,首先會檢驗這個key是否過期,如果該key過期,那么Redis會刪除它,這個過程就是惰性刪除,但是清理完了之后還不能結束,Redis會再找出一個沒過期的key返回給客戶端。
此時,Redis則會繼續隨機拿出一個key,然后再判斷它是否過期,直到找到一個沒過期的key返回給客戶端。
這里就有一個問題,如果此時Redis中有大量的key過期,但還未來得及被清理掉,這個循環就會持續很久才能結束,這樣就會導致RANDOMKEY命令執行耗時變長,影響Redis性能。
以上流程,其實是master上執行的。如果在slave上執行RANDOMKEY,那么問題更嚴重。
slave是不會自己清理過期的key,當一個key要過期時,master會先清理刪除它,之后master向slave發送一個DEL命令,告知slave也刪除這個key,以此達到主從一致。
假設Redis中存在大量已過期還未來得及清理的key,那么在slave上執行RANDOMKEY時,就會發生一下問題:
1、slave隨機取出一個key,判斷是否已經過期。
2、key已經過期,但是slave不會刪除它,而是繼續隨機尋找不過期的key
3、由于大量key都已過期,那slave就會找不到符合條件的key,就會進入死循環。
這個Bug直到5.0才被修復,修復方法就是在slave中設置一個最大查找次數,無論找到與否,到了這個最大次數就退出循環。
3.一次線上事故,Redis主從切換導致了緩存雪崩
我們假設,slave的機器時鐘比master走的快很多。
此時,Redis master 里設置了過期時間的key,從slave角度來看,可能會有很多在master里沒過期,在slave里面已經過期了的數據。
如果此時操作主從切換,把slave提升為新的master,新的master就會開始大量清理過期的key,此時就會導致以下結果:
1、master大量清理過期key,主線程可能會發生阻塞,無法及時處理客戶端請求。
2、Redis中數據大量過期,引發緩存雪崩。
所以,我們一定要保證主從庫的機器時鐘一致,避免發生這些問題。
4.Redis持久化RDB、AOF、混合持久化
Redis持久化分為:RDB、AOF、混合持久化(redis4.0引入)
RDB的實現原理、優缺點
描述:類似于快照。在某個時間點,將 Redis 在內存中的數據庫狀態(數據庫的鍵值對等信息)保存到磁盤里面。RDB 持久化功能生成的 RDB 文件是經過壓縮的二進制文件。
有兩個 Redis 命令可以用于生成 RDB 文件,一個是 SAVE,另一個是 BGSAVE。
開啟:使用 save point 配置
save 900 1 #900秒內有1個key發生了變化,則觸發保存RDB文件
save 300 10 #300秒內有10個key發生了變化,則觸發保存RDB文件
save 60 10000 #60秒內有10000個key發生了變化,則觸發保存RDB文件
關閉:1)注釋掉所有save point 配置可以關閉 RDB 持久化。2)在所有 save point 配置后增加:save "",該配置可以刪除所有之前配置的 save point。
SAVE:生成 RDB 快照文件,但是會阻塞主進程,服務器將無法處理客戶端發來的命令請求,所以通常不會直接使用該命令。
BGSAVE:fork 子進程來生成 RDB 快照文件,阻塞只會發生在 fork 子進程的時候,之后主進程可以正常處理請求.
RDB 的優點:1)RDB 文件是是經過壓縮的二進制文件,占用空間很小,它保存了 Redis 某個時間點的數據集,很適合用于做備份。 比如說,你可以在最近的 24 小時內,每小時備份一次 RDB 文件,并且在每個月的每一天,也備份一個 RDB 文件。這樣的話,即使遇上問題,也可以隨時將數據集還原到不同的版本。
2)RDB 非常適用于災難恢復(disaster recovery):它只有一個文件,并且內容都非常緊湊,可以(在加密后)將它傳送到別的數據中心。
3)RDB 可以最大化 redis 的性能。父進程在保存 RDB 文件時唯一要做的就是 fork 出一個子進程,然后這個子進程就會處理接下來的所有保存工作,父進程無須執行任何磁盤 I/O 操作。
4)RDB 在恢復大數據集時的速度比 AOF 的恢復速度要快。
RDB 的缺點:1)RDB 在服務器故障時容易造成數據的丟失
2)RDB 保存時使用 fork 子進程進行數據的持久化,如果數據比較大的話,fork 可能會非常耗時,造成 Redis 停止處理服務N毫秒。如果數據集很大且 CPU 比較繁忙的時候,停止服務的時間甚至會到一秒。
3)Linux fork 子進程采用的是 copy-on-write 的方式。在 Redis 執行 RDB 持久化期間,如果 client 寫入數據很頻繁,那么將增加 Redis 占用的內存,最壞情況下,內存的占用將達到原先的2倍。剛 fork 時,主進程和子進程共享內存,但是隨著主進程需要處理寫操作,主進程需要將修改的頁面拷貝一份出來,然后進行修改。極端情況下,如果所有的頁面都被修改,則此時的內存占用是原先的2倍。
AOF的實現原理、優缺點
描述:保存 Redis 服務器所執行的所有寫操作命令來記錄數據庫狀態,并在服務器啟動時,通過重新執行這些命令來還原數據集。
可以通過配置:appendonly yes 開啟,使用配置 appendonly no 可以關閉 AOF 持久化
AOF 持久化功能的實現可以分為三個步驟:命令追加、文件寫入、文件同步。
appendfsync 參數有三個選項:
1)always:每處理一個命令都將 aof_buf 緩沖區中的所有內容寫入并同步到AOF 文件,即每個命令都刷盤。
2)everysec:將 aof_buf 緩沖區中的所有內容寫入到 AOF 文件,如果上次同步 AOF 文件的時間距離現在超過一秒鐘, 那么再次對 AOF 文件進行同步, 并且這個同步操作是異步的,由一個后臺線程專門負責執行,即每秒刷盤1次。
3)no:將 aof_buf 緩沖區中的所有內容寫入到 AOF 文件, 但并不對 AOF 文件進行同步, 何時同步由操作系統來決定。即不執行刷盤,讓操作系統自己執行刷盤。
2)AOF文件是一個純追加的日志文件。即使日志因為某些原因而包含了未寫入完整的命令(比如寫入時磁盤已滿,寫入中途停機等等), 我們也可以使用 redis-check-aof 工具也可以輕易地修復這種問題。
3)當 AOF文件太大時,Redis 會自動在后臺進行重寫:重寫后的新 AOF 文件包含了恢復當前數據集所需的最小命令集合。整個重寫是絕對安全,因為重寫是在一個新的文件上進行,同時 Redis 會繼續往舊的文件追加數據。當新文件重寫完畢,Redis 會把新舊文件進行切換,然后開始把數據寫到新文件上
4)AOF 文件有序地保存了對數據庫執行的所有寫入操作以 Redis 協議的格式保存, 因此 AOF 文件的內容非常容易被人讀懂, 對文件進行分析(parse)也很輕松。如果你不小心執行了 FLUSHALL 命令把所有數據刷掉了,但只要 AOF 文件沒有被重寫,那么只要停止服務器, 移除 AOF 文件末尾的 FLUSHALL 命令, 并重啟 Redis , 就可以將數據集恢復到 FLUSHALL 執行之前的狀態。
1)對于相同的數據集,AOF 文件的大小一般會比 RDB 文件大。
2)根據所使用的 fsync 策略,AOF 的速度可能會比 RDB 慢。通常 fsync 設置為每秒一次就能獲得比較高的性能,而關閉 fsync 可以讓 AOF 的速度和 RDB 一樣快。
生產環境都可以啟用,redis啟動時如果既有rdb文件,又有aof文件則優先選擇aof文件恢復數據,因為aof一般來說數據更安全一點。
混合持久化
通過如下配置開啟混合持久化(必須先開啟aof)
aof-use-rdb-preamble yes
混合持久化本質是通過 AOF 后臺重寫(bgrewriteaof 命令)完成的,不同的是當開啟混合持久化時,fork 出的子進程先將當前全量數據以 RDB 方式寫入新的 AOF 文件,然后再將 AOF 重寫緩沖區(aof_rewrite_buf_blocks)的增量命令以 AOF 方式寫入到文件,寫入完成后通知主進程將新的含有 RDB 格式和 AOF 格式的 AOF 文件替換舊的的 AOF 文件。
優點:結合 RDB 和 AOF 的優點, 更快的重寫和恢復。
缺點:AOF 文件里面的 RDB 部分不再是 AOF 格式,可讀性差。
以上就是“距離進入大廠就只差redis集群面試題”,你能回答上來嗎?如果想要了解更多的Java面試題相關內容,可以關注動力節點Java官網。
0基礎 0學費 15天面授
有基礎 直達就業
業余時間 高薪轉行
工作1~3年,加薪神器
工作3~5年,晉升架構
提交申請后,顧問老師會電話與您溝通安排學習