Redis 面試篇

Redis相關面試題

在這里插入圖片描述

緩存三劍客

面試官:什么是緩存穿透 ? 怎么解決 ?

緩存穿透是指查詢一個一定不存在的數據,如果從存儲層查不到數據則不寫入緩存,這將導致這個不存在的數據每次請求都要到 DB 去查詢,可能導致 DB 掛掉。這種情況大概率是遭到了攻擊。

解決方案的話:

  1. 緩存空對象(實現簡單,維護方便),但是會有額外的內存消耗,可以設置合理的TTL,數據可能不一致
  2. 布隆過濾器

面試官:好的,你能介紹一下布隆過濾器嗎?

布隆過濾器主要是用于檢索一個元素是否在一個集合中。我們當時使用的是redisson實現的布隆過濾器。

它的底層主要是先去初始化一個比較大數組,里面存放的二進制0或1。在一開始都是0,當一個key來了之后經過3次hash計算,模于數組長度找到數據的下標然后把數組中原來的0改為1,這樣的話,三個數組的位置就能標明一個key的存在。查找的過程也是一樣的。

當然是有缺點的,布隆過濾器有可能會產生一定的誤判,我們一般可以設置這個誤判率,大概不會超過5%,其實這個誤判是必然存在的,要不就得增加數組的長度,其實已經算是很劃分了,5%以內的誤判率一般的項目也能接受,不至于高并發下壓倒數據庫。

面試官:什么是緩存擊穿 ? 怎么解決 ?

熱點key問題:一個被高并發訪問并且緩存重建業務較復雜的key突然失效了,無數的請求訪問會在瞬間給數據庫帶來巨大的沖擊。

解決方案有兩種方式:

  1. 互斥鎖:當緩存失效時,線程1先獲取一個互斥鎖,查詢數據庫實現緩存重建,此時其他線程獲取不到鎖只能休眠再重試,最后緩存重建完成后,其他線程可以查到緩存。

    在這里插入圖片描述

  2. 邏輯過期:

    在這里插入圖片描述

    1. 在設置key的時候,設置一個過期時間字段一塊存入緩存中,不給當前key設置過期時間
    2. 當查詢的時候,從redis取出數據后判斷時間是否過期
    3. 如果過期則開通另外一個線程進行數據同步,當前線程正常返回數據,這個數據不是最新

當然兩種方案各有利弊:

  • 強一致性:分布式鎖的方案,性能上可能沒那么高,鎖需要等,也有可能產生死鎖的問題
  • 高可用性:邏輯刪除,則優先考慮的高可用性,性能比較高,但是數據同步這塊做不到強一致。

面試官:什么是緩存雪崩 ? 怎么解決 ?

存雪崩是指在同一時段大量的緩存key同時失效或者Redis服務宕機,導致大量請求到達數據庫,帶來巨大壓力。

與緩存擊穿的區別:雪崩是很多key,擊穿是某一個key緩存。

解決方案:

  • 給不同的Key的TTL添加隨機值
  • 利用Redis集群提高服務的可用性
  • 給緩存業務添加降級限流策略
  • 給業務添加多級緩存

**面試官:**緩存的淘汰策略

  • 內存淘汰(redis會自動將一些不常用的緩存清理)
  • 超時剔除(超過了TTL,會自動清理)
  • 主動更新(主動刪除緩存)

數據庫緩存不一致

面試官:redis做為緩存,mysql的數據如何與redis進行同步呢?(雙寫一致性)

性能高,數據不是強一致:我們當時是把商鋪的熱點數據存入到了緩存中,雖然是熱點數據,但是實時要求性并沒有那么高,所以,我們當時采用的延遲雙刪。

性能低,數據強一致:我們當時是把搶券的庫存存入到了緩存中,這個需要實時的進行數據同步,為了保證數據的強一致,我們當時采用的是redisson提供的讀寫鎖來保證數據的同步。

延遲雙刪:不能保證強一致,有臟數據的風險

在這里插入圖片描述

  1. 不論先刪除哪個都有臟數據的風險
  2. 所以要刪除兩次緩存就是為了降低臟數據的風險
  3. 延遲刪除,因為數據庫是主從模式,讀寫是分離的,延時一會讓主節點把數據同步到從節點

分布式鎖:保證強一致,但是性能低。

在這里插入圖片描述

共享鎖:讀鎖readLock,加鎖之后,其他線程可以共享讀操作
排他鎖:獨占鎖writeLock也叫,加鎖之后,阻塞其他線程讀寫操作

異步通知:保證數據最終一致性。

在這里插入圖片描述

持久化

面試官:redis做為緩存,數據的持久化是怎么做的?

在Redis中提供了兩種數據持久化的方式:1、RDB 2、AOF

面試官:這兩種持久化方式有什么區別呢?

RDB是一個快照文件,它是把redis內存存儲的數據寫到磁盤上,當redis實例宕機恢復數據的時候,方便從RDB的快照文件中恢復數據。

AOF的含義是追加文件,當redis操作寫命令的時候,都會存儲這個文件中,當redis實例宕機恢復數據的時候,會從這個文件中再次執行一遍命令來恢復數據。

面試官:這兩種方式,哪種恢復的比較快呢?

RDB因為是二進制文件,在保存的時候體積也是比較小的,它恢復的比較快,但是它有可能會丟數據,我們通常在項目中也會使用AOF來恢復數據,雖然AOF恢復的速度慢一些,但是它丟數據的風險要小很多,在AOF文件中可以設置刷盤策略,我們當時設置的就是每秒批量寫入一次命令

RDB和AOF各有自己的優缺點,如果對數據安全性要求較高,在實際開發中往往會結合兩者來使用。

在這里插入圖片描述

數據過期策略

面試官:假如redis的key過期之后,會立即刪除嗎?

惰性刪除:在設置該key過期時間后,我們不去管它,當使用key時,再檢查其是否過期,如果過期就刪掉它,反之返回該key。

定期刪除:每隔一段時間,我們就對一些key進行檢查,刪除里面過期的key。

定期清理的兩種模式:

  • SLOW模式是定時任務,執行頻率默認為10hz,每次不超過25ms,以通過修改配置文件redis.conf 的 hz 選項來調整這個次數
  • FAST模式執行頻率不固定,每次事件循環會嘗試執行,但兩次間隔不低于2ms,每次耗時不超過1ms

Redis的過期刪除策略:惰性刪除 + 定期刪除兩種策略進行配合使用。

數據淘汰策略

面試官:假如緩存過多,內存是有限的,內存被占滿了怎么辦?

嗯,這個在redis中提供了很多種,默認是noeviction,不刪除任何數據,內部不足直接報錯

是可以在redis的配置文件中進行設置的,里面有兩個非常重要的概念,一個是LRU,另外一個是LFU

LRU:最少最近使用,用當前時間減去最后一次訪問時間,這個值越大則淘汰優先級越高。

LFU:最少頻率使用。會統計每個key的訪問頻率,值越小淘汰優先級越高

面試官:數據庫有1000萬數據,Redis只能緩存20w數據,如何保證Redis中的數據都是熱點數據 ?

可以使用 allkeys-lru (挑選最近最少使用的數據淘汰)淘汰策略,那留下來的都是經常訪問的熱點數據

面試官:Redis的內存用完了會發生什么?

這個要看redis的數據淘汰策略是什么,如果是默認的配置,redis內存用完以后則直接報錯。我們當時設置的 allkeys-lru 策略。把最近最常訪問的數據留在緩存中。

Redis分布式鎖

面試官:Redis分布式鎖如何實現 ?

嗯,在redis中提供了一個命令setnx(SET if not exists)

由于redis的單線程的,用了命令之后,只能有一個客戶端對某一個key設置值,在沒有過期或刪除key的時候是其他客戶端是不能設置這個key的

面試官:好的,那你如何控制Redis實現分布式鎖有效時長呢?

的確,redis的setnx指令不好控制這個問題,我們當時采用的redis的一個框架redisson實現的。

在redisson中需要手動加鎖,并且可以控制鎖的失效時間和等待時間,當鎖住的一個業務還沒有執行完成的時候,在redisson中引入了一個看門狗機制,就是說每隔一段時間就檢查當前業務是否還持有鎖,如果持有就增加加鎖的持有時間,當業務執行完成之后需要使用釋放鎖就可以了

還有一個好處就是,在高并發下,一個業務有可能會執行很快,先客戶1持有鎖的時候,客戶2來了以后并不會馬上拒絕,它會自旋不斷嘗試獲取鎖,如果客戶1釋放之后,客戶2就可以馬上持有鎖,性能也得到了提升。

面試官:好的,redisson實現的分布式鎖是可重入的嗎?

是可以重入的。這樣做是為了避免死鎖的產生。這個重入其實在內部就是判斷是否是當前線程持有的鎖,如果是當前線程持有的鎖就會計數,如果釋放鎖就會在計算上減一。在存儲數據的時候采用的hash結構,大key可以按照自己的業務進行定制,其中小key是當前線程的唯一標識,value是當前線程重入的次數。

面試官:redisson實現的分布式鎖能解決主從一致性的問題嗎?

這個是不能的,比如,當線程1加鎖成功后,master節點數據會異步復制到slave節點,此時當前持有Redis鎖的master節點宕機,slave節點被提升為新的master節點,假如現在來了一個線程2,再次加鎖,會在新的master節點上加鎖成功,這個時候就會出現兩個節點同時持有一把鎖的問題。

我們可以利用redisson提供的紅鎖來解決這個問題,它的主要作用是,不能只在一個redis實例上創建鎖,應該是在多個redis實例上創建鎖,并且要求在大多數redis節點上都成功創建鎖,紅鎖中要求是redis的節點數量要過半。這樣就能避免線程1加鎖成功后master節點宕機導致線程2成功加鎖到新的master節點上的問題了。

但是,如果使用了紅鎖,因為需要同時在多個節點上都添加鎖,性能就變的很低了,并且運維維護成本也非常高,所以,我們一般在項目中也不會直接使用紅鎖,并且官方也暫時廢棄了這個紅鎖

面試官:好的,如果業務非要保證數據的強一致性,這個該怎么解決呢?

redis本身就是支持高可用的,做到強一致性,就非常影響性能,所以,如果有強一致性要求高的業務,建議使用zookeeper實現的分布式鎖,它是可以保證強一致性的。

Redis集群

面試官:Redis集群有哪些方案, 知道嘛 ?

在Redis中提供的集群方案總共有三種:主從復制、哨兵模式、Redis分片集群

面試官:那你來介紹一下主從同步

是這樣的,單節點Redis的并發能力是有上限的,要進一步提高Redis的并發能力,可以搭建主從集群,實現讀寫分離。一般都是一主多從,主節點負責寫數據,從節點負責讀數據,主節點寫入數據之后,需要把數據同步到從節點中。

面試官:能說一下,主從同步數據的流程?

主從同步分為了兩個階段,一個是全量同步,一個是增量同步

全量同步是指從節點第一次與主節點建立連接的時候使用全量同步,流程是這樣的:

在這里插入圖片描述

第一:從節點請求主節點同步數據,其中從節點會攜帶自己的replication id和 offset 偏移量。

第二:主節點判斷是否是第一次請求,主要判斷的依據就是,主節點與從節點是否是同一個replication id,如果不是,就說明是第一次同步,那主節點就會把自己的replication id和offset發送給從節點,讓從節點與主節點的信息保持一致。

第三:在同時主節點會執行bgsave,生成rdb文件后,發送給從節點去執行,從節點先把自己的數據清空,然后執行主節點發送過來的rdb文件,這樣就保持了一致

當然,如果在rdb生成執行期間,依然有請求到了主節點,而主節點會以命令的方式記錄到緩沖區,緩沖區是一個日志文件,最后把這個日志文件發送給從節點,這樣就能保證主節點與從節點完全一致了,后期再同步數據的時候,都是依賴于這個日志文件,這個就是全量同步

增量同步流程

在這里插入圖片描述

當從節點服務重啟之后,數據就不一致了,所以這個時候,從節點會請求主節點同步數據,主節點還是判斷不是第一次請求,不是第一次就獲取從節點的offset值,然后主節點從命令日志中獲取offset值之后的數據,發送給從節點進行數據同步。

Redis的高并發高可用

面試官:怎么保證Redis的高并發高可用

首先可以搭建主從集群,再加上使用redis中的哨兵模式,哨兵模式可以實現主從集群的自動故障恢復(對主從服務的監控、自動故障恢復、通知);如果master故障,Sentinel會將一個slave提升為master。當故障實例恢復后也以新的master為主;同時Sentinel也充當Redis客戶端的服務發現來源,當集群發生故障轉移時,會將最新信息推送給Redis的客戶端,所以一般項目都會采用哨兵的模式來保證redis的高并發高可用。

面試官:你們使用redis是單點還是集群,哪種集群

我們當時使用的是主從(1主1從)加哨兵。一般單節點不超過10G內存,如果Redis內存不足則可以給不同服務分配獨立的Redis主從節點。盡量不做分片集群。因為集群維護起來比較麻煩,并且集群之間的心跳檢測和數據通信會消耗大量的網絡帶寬,也沒有辦法使用lua腳本和事務。

面試官:redis集群腦裂,該怎么解決呢?

有的時候由于網絡等原因可能會出現腦裂的情況,就是說,由于redis master節點和redis salve節點和sentinel處于不同的網絡分區,使得sentinel沒有能夠心跳感知到master,所以通過選舉的方式提升了一個salve為master,這樣就存在了兩個master,就像大腦分裂了一樣,這樣會導致客戶端還在old master那里寫入數據,新節點無法同步數據,當網絡恢復后,sentinel會將old master降為salve,這時再從新master同步數據,這會導致old master中的大量數據丟失。

關于解決的話,我記得在redis的配置中可以設置:第一可以設置最少的salve節點個數,比如設置至少要有一個從節點才能同步數據,第二個可以設置主從數據復制和同步的延遲時間,達不到要求就拒絕請求,就可以避免大量的數據丟失。

redis的分片集群

面試官:redis的分片集群有什么作用?

分片集群主要解決的是,海量數據存儲的問題,集群中有多個master,每個master保存不同數據,并且還可以給每個master設置多個slave節點,就可以繼續增大集群的高并發能力。同時每個master之間通過ping監測彼此健康狀態,就類似于哨兵模式了。當客戶端請求可以訪問集群任意節點,最終都會被轉發到正確節點。

面試官:Redis分片集群中數據是怎么存儲和讀取的?

Redis 集群引入了哈希槽的概念,有 16384 個哈希槽,集群中每個主節點綁定了一定范圍的哈希槽范圍, key通過 CRC16 校驗后對 16384 取模來決定放置哪個槽,通過槽找到對應的節點進行存儲。

取值的邏輯是一樣的

Redis是單線程

面試官:Redis是單線程的,但是為什么還那么快?

1、完全基于內存的,C語言編寫

2、采用單線程,避免不必要的上下文切換可競爭條件

3、使用多路I/O復用模型,非阻塞IO

例如:bgsave 和 bgrewriteaof 都是在后臺執行操作,不影響主線程的正常使用,不會產生阻塞

面試官:能解釋一下I/O多路復用模型?

I/O多路復用是指利用單個線程來同時監聽多個Socket ,并在某個Socket可讀、可寫時得到通知,從而避免無效的等待,充分利用CPU資源。目前的I/O多路復用都是采用的epoll模式實現,它會在通知用戶進程Socket就緒的同時,把已就緒的Socket寫入用戶空間,不需要挨個遍歷Socket來判斷是否就緒,提升了性能。

其中Redis的網絡模型就是使用I/O多路復用結合事件的處理器來應對多個Socket請求,比如,提供了連接應答處理器、命令回復處理器,命令請求處理器;

在Redis6.0之后,為了提升更好的性能,在命令回復處理器使用了多線程來處理回復事件,在命令請求處理器中,將命令的轉換使用了多線程,增加命令轉換速度,在命令執行的時候,依然是單線程

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

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

相關文章

群暉DS223 Docker搭建為知筆記

群暉DS223 Docker搭建為知筆記,打造你的專屬知識寶庫 一、引言 在數字化信息爆炸的時代,筆記軟件成為了我們管理知識、記錄靈感的得力助手。為知筆記,作為一款專注于工作筆記和團隊協作的云筆記產品,以其豐富的功能和便捷的使用體…

Linux網絡之數據鏈路層協議

目錄 數據鏈路層 MAC地址與IP地址 數據幀 ARP協議 NAT技術 代理服務器 正向代理 反向代理 上期我們學習了網絡層中的相關協議,為IP協議。IP協議通過報頭中的目的IP地址告知了數據最終要傳送的目的主機的IP地址,從而指引了數據在網絡中的一步…

分類評價指標

基礎概念解釋 TP、TN、FP、FN 這里T是True,F是False,P為Positive,N為Negative TP:被模型正確地預測為正樣本(原本為正樣本,預測為正樣本) TN:被模型正確地預測為負樣本&#xff0…

LeetCode 哈希章節

簡單 1. 兩數之和 給定一個整數數組 nums 和一個整數目標值 target,請你在該數組中找出 和為目標值 target 的那 兩個 整數,并返回它們的數組下標。 你可以假設每種輸入只會對應一個答案,并且你不能使用兩次相同的元素。 你可以按任意順序返…

WLAN(無線局域網)安全

WLAN安全涉及到保護無線局域網免受各種威脅和攻擊,以確保數據的保密性、完整性和可用性。以下是關于WLAN安全的多方面介紹: 一、主要安全威脅 竊聽:攻擊者利用特殊設備監聽無線信號,獲取傳輸中的數據,如用戶的賬號密…

江科大51單片機筆記【11】AT24C02(I2C總線)

一、存儲器 1.介紹 RAM的特點是存儲速度特別快,但是掉電會丟失;ROM的特點是存儲速度特別慢,但是掉電不會丟失 SRAM是所有存儲器最快的,一般用于電腦的CPU高速緩存,容量相對較少,成本較高;DRAM…

【C++指南】一文總結C++類和對象【中】

🌟 各位看官好,我是egoist2023! 🌍 種一棵樹最好是十年前,其次是現在! 🚀 今天來學習C類和對象的語法知識。注意:在本章節中,小編會以Date類舉例 👍 如果覺得…

PgSql 操作技巧

1、查詢數據導出csv數據 \COPY (SELECT w.* from t_sys_warn w ) TO /home/cuadmin/warn_output.csv WITH CSV HEADER;2、導出sql Insert語句 pg_dump -U 用戶名 -h 主機名 -p 端口號 -d 數據庫名 --inserts -t 表名 > 導出文件.sqlpg_dump -U username -d dbname -t tabl…

Unity ES3保存類的問題

有以下一個物品類 public class Item_Base//基礎物品 { public string ID; private Attribute_Data Item_attribute new(); } 當使用ES3保存這個類時,Item_attribute的數據不會被保存,因為它是私有private ES3保存類時,只會保存…

react基本功

useLayoutEffect useLayoutEffect 用于在瀏覽器重新繪制屏幕之前同步執行代碼。它與 useEffect 相同,但執行時機不同。 主要特點 執行時機:useLayoutEffect 在 DOM 更新完成后同步執行,但在瀏覽器繪制之前。這使得它可以在瀏覽器渲染之前讀取和修改 DOM,避免視覺上的閃爍…

Spring Boot筆記(上)

01 概要 Spring Boot 是 Java 領域最流行的 快速開發框架,專為簡化 Spring 應用的初始搭建和開發而設計。 一、Spring Boot 解決了什么問題? 傳統 Spring 痛點 ? 繁瑣的 XML 配置 ? 需要手動管理依賴版本 ? 部署依賴外部 Web 服務器(如 …

目標檢測YOLO實戰應用案例100講-基于毫米波雷達的多目標檢測 (續)

目錄 3.2 改進的CFAR目標檢測算法 3.3 算法步驟描述 3.4 實驗結果與分析 基于VGG16-Net的毫米波雷達目標檢測算法 4.1 VGG16-Net網絡模型 4.2 改進VGG16-Net網絡的目標檢測算法 4.3 算法步驟描述 4.4 實驗結果與分析 知識拓展 基于毫米波雷達的多目標檢測:使…

gitsubtree怎么添加新的子倉庫

要使用 git subtree 添加一個新的子倉庫&#xff0c;可以按照以下步驟操作&#xff1a; 1. 添加子倉庫 使用 git subtree add 命令將子倉庫的內容添加到主倉庫的指定目錄中。命令格式如下&#xff1a; git subtree add --prefix<子目錄路徑> <子倉庫地址> <子…

文本轉語音-音畫適時推送rtsp并播放

文本語音 rtsp適時播放叫號系統的底層邏輯 發布Linux, unix socket 和window win32做為音頻源的 python10下的(ffmpeg version 7.1) 可運行版本. 這兩天在弄這個&#xff0c;前2篇是通過虛擬聲卡&#xff0c;達到了最簡單的一個邏輯&#xff0c;播放文本就從聲卡發聲&#xff0…

從0開始的操作系統手搓教程33:掛載我們的文件系統

目錄 代碼實現 添加到初始化上 上電看現象 掛載分區可能是一些朋友不理解的——實際上掛載就是將我們的文件系統封裝好了的設備&#xff08;硬盤啊&#xff0c;SD卡啊&#xff0c;U盤啊等等&#xff09;&#xff0c;掛到我們的默認分區路徑下。這樣我們就能訪問到了&#xff…

【圖片批量轉換合并PDF】多個文件夾的圖片以文件夾為單位批量合并成一個PDF,基于wpf的實現方案

項目背景: 多個圖片分布在不同文件夾,如何以文件夾為單位批量合并成一個PDF,還要保證文件夾里面圖片大小和順序 實現功能: 1、單張圖片的轉換PDF:一張圖臨時轉一下 2、多張圖片轉換成PDF:多張圖單獨轉成PDF 3、多級目錄多張圖轉換成PDF:多級目錄多張圖單獨轉成多個PDF…

如何用Kimi生成PPT?秒出PPT更高效!

做PPT是不是總是讓你頭疼&#xff1f;&#x1f629; 快速制作出專業的PPT&#xff0c;今天我們要推薦兩款超級好用的AI工具——Kimi 和 秒出PPT&#xff01;我們來看看哪一款更適合你吧&#xff01;&#x1f680; &#x1f947; Kimi&#xff1a;讓PPT制作更輕松 Kimi的生成效…

從 MongoDB 到 TDengine,沃太能源實現 18 倍寫入性能提升

導讀 沃太能源是國內領先儲能設備生產廠商&#xff0c;數十萬儲能終端遍布世界各地。此前使用 MongoDB 存儲時序數據&#xff0c;但隨著設備測點增加&#xff0c;MongoDB 在存儲效率、寫入性能、查詢性能等方面暴露出短板。經過對比&#xff0c;沃太能源選擇了專業時序數據庫 …

數據庫基本建表操作

1.登錄數據庫并創建數據庫db_ck 創建完成后使用到我們創建的數據庫。 2.創建表t_hero 根據hero屬性包括&#xff08;id&#xff0c;name&#xff0c;nickname&#xff0c;age&#xff0c;gender&#xff0c;address&#xff0c;weapon&#xff0c;types&#xff09; 創建完…

OkHttp 之任務調度模塊源碼分析

一、引言 在現代網絡應用開發中&#xff0c;高效的任務調度機制對于提升系統性能和用戶體驗至關重要。OkHttp 作為一款廣泛使用的高性能 HTTP 客戶端庫&#xff0c;其任務調度模塊在處理網絡請求的并發、排隊和執行等方面發揮著關鍵作用。本文將深入 OkHttp 源碼&#xff0c;詳…