redis面試提問

来源:https://www.cnblogs.com/dark-gan/archive/2023/10/25/17787807.html
-Advertisement-
Play Games

redis面試提問 轉載:https://blog.csdn.net/uuqaz/article/details/127088333 Redis 是面試中繞不過的檻,只要在簡歷中寫了用過 Redis,肯定逃不過。今天我們就來模擬一下麵試官在 Redis 這個話題上是如何一步一步深入,全面考察候選人對 ...


redis面試提問

轉載:https://blog.csdn.net/uuqaz/article/details/127088333

Redis 是面試中繞不過的檻,只要在簡歷中寫了用過 Redis,肯定逃不過。今天我們就來模擬一下麵試官在 Redis 這個話題上是如何一步一步深入,全面考察候選人對於 Redis 的掌握情況。

小二:面試官,你好。我是來參加面試的。

面試官:你好,小二。我看了你的簡歷,熟練掌握 Redis,那麼我就隨便問你幾個 Redis 相關的問題吧。首先我的問題是,Redis 是單線程還是多線程呢 ?

小二:

Redis 不同版本之間採用的線程模型是不一樣的,在 Redis4.0 版本之前使用的是單線程模型,在 4.0 版本之後增加了多線程的支持。

在 4.0 之前雖然我們說 Redis 是單線程,也只是說它的網路 I/O 線程以及 Set 和 Get 操作是由一個線程完成的。但是 Redis 的持久化、集群同步還是使用其他線程來完成。

4.0 之後添加了多線程的支持,主要是體現在大數據的非同步刪除功能上,例如 unlink key、flushdb async、flushall async 等

面試官:回答的很好,那為什麼 Redis 在 4.0 之前會選擇使用單線程?而且使用單線程還那麼快 ?

小二:

選擇單線程個人覺得主要是使用簡單,不存在鎖競爭,可以在無鎖的情況下完成所有操作,不存在死鎖和線程切換帶來的性能和時間上的開銷,但同時單線程也不能完全發揮出多核 CPU 的性能。

至於為什麼單線程那麼快我覺得主要有以下幾個原因:

Redis 的大部分操作都在記憶體中完成,記憶體中的執行效率本身就很快,並且採用了高效的數據結構,比如哈希表和跳錶。

使用單線程避免了多線程的競爭,省去了多線程切換帶來的時間和性能開銷,並且不會出現死鎖。

採用 I/O 多路復用機制處理大量客戶端的 Socket 請求,因為這是基於非阻塞的 I/O 模型,這就讓 Redis 可以高效地進行網路通信,I/O 的讀寫流程也不再阻塞。

面試官:不錯,那 Redis 是如何實現數據不丟失的呢 ?

小二:

Redis 數據是存儲在記憶體中的,為了保證 Redis 數據不丟失,那就要把數據從記憶體存儲到磁碟上,以便在伺服器重啟後還能夠從磁碟中恢複原有數據,這就是 Redis 的數據持久化。Redis 數據持久化有三種方式。

1)AOF 日誌(Append Only File,文件追加方式) :記錄所有的操作命令,並以文本的形式追加到文件中。

2)RDB 快照(Redis DataBase) :將某一個時刻的記憶體數據,以二進位的方式寫入磁碟。

3)混合持久化方式 :Redis 4.0 新增了混合持久化的方式,集成了 RDB 和 AOF 的優點。

面試官:那你分別說說 AOF 和 RDB 的實現原理 吧。

小二:

AOF 採用的是寫後日誌的方式,Redis 先執行命令把數據寫入記憶體,然後再記錄日誌到文件中。AOF 日誌記錄的是操作命令,不是實際的數據,如果採用 AOF 方法做故障恢復時需要將全量日誌都執行一遍。

 

RDB 採用的是記憶體快照的方式,它記錄的是某一時刻的數據,而不是操作,所以採用 RDB 方法做故障恢復時只需要直接把 RDB 文件讀入記憶體即可,實現快速恢復。

面試官:你剛提到了 AOF 採用的是 “寫後日誌” 的方式,我們平時用的 MySQL 則採用的是 “寫前日誌”,那 Redis 為什麼要先執行命令,再把數據寫入日誌呢 ?

小二:這個主要是由於 Redis 在寫入日誌之前,不對命令進行語法檢查,所以只記錄執行成功的命令,避免出現記錄錯誤命令的情況,而且在命令執行後再寫日誌不會阻塞當前的寫操作。

面試官:那後寫日誌又有什麼風險呢 ?

小二:我... 這個我不會。

面試官:

好吧,後寫日誌主要有兩個風險可能會發生:

數據可能會丟失 :如果 Redis 剛執行完命令,此時發生故障宕機,會導致這條命令存在丟失的風險。

可能阻塞其他操作 :AOF 日誌其實也是在主線程中執行,所以當 Redis 把日誌文件寫入磁碟的時候,還是會阻塞後續的操作無法執行。

我還有個問題是 RDB 做快照時會阻塞線程嗎 ?

小二:Redis 提供了兩個命令來生成 RDB 快照文件,分別是 save 和 bgsave。save 命令在主線程中執行,會導致阻塞。而 bgsave 命令則會創建一個子進程,用於寫入 RDB 文件的操作,避免了對主線程的阻塞,這也是 Redis RDB 的預設配置。

面試官:RDB 做快照的時候數據能修改嗎 ?

小二:save 是同步的會阻塞客戶端命令,bgsave 的時候是可以修改的。

面試官:那 Redis 是怎麼解決在 bgsave 做快照的時候允許數據修改呢 ?

小二:額,這個我不太清楚...

 

面試官:

這裡主要是利用 bgsave 的子線程實現的,具體操作如下:

如果主線程執行讀操作,則主線程和 bgsave 子進程互相不影響;

如果主線程執行寫操作,則被修改的數據會複製一份副本,然後 bgsave 子進程會把該副本數據寫入 RDB 文件,在這個過程中,主線程仍然可以直接修改原來的數據。

 

要註意,Redis 對 RDB 的執行頻率非常重要,因為這會影響快照數據的完整性以及 Redis 的穩定性,所以在 Redis 4.0 後,增加了 AOF 和 RDB 混合的數據持久化機制:把數據以 RDB 的方式寫入文件,再將後續的操作命令以 AOF 的格式存入文件,既保證了 Redis 重啟速度,又降低數據丟失風險。

小二:學到了學到了。

面試官:那你再跟我說說 Redis 如何實現高可用 吧?

小二:Redis 實現高可用主要有三種方式:主從複製、哨兵模式,以及 Redis 集群。

1)主從複製

將從前的一臺 Redis 伺服器,同步數據到多台從 Redis 伺服器上,即一主多從的模式,這個跟 MySQL 主從複製的原理一樣。

 

2)哨兵模式

使用 Redis 主從服務的時候,會有一個問題,就是當 Redis 的主從伺服器出現故障宕機時,需要手動進行恢復,為瞭解決這個問題,Redis 增加了哨兵模式(因為哨兵模式做到了可以監控主從伺服器,並且提供自動容災恢復的功能)。

 

3)Redis Cluster(集群)

Redis Cluster 是一種分散式去中心化的運行模式,是在 Redis 3.0 版本中推出的 Redis 集群方案,它將數據分佈在不同的伺服器上,以此來降低系統對單主節點的依賴,從而提高 Redis 服務的讀寫性能。

 

面試官:使用哨兵模式在數據上有副本數據做保證,在可用性上又有哨兵監控,一旦 master 宕機會選舉 salve 節點為 master 節點,這種已經滿足了我們的生產環境需要,那為什麼還需要使用集群模式呢 ?

小二:哨兵模式歸根節點還是主從模式,在主從模式下我們可以通過增加 salve 節點來擴展讀併發能力,但是沒辦法擴展寫能力和存儲能力,存儲能力只能是 master 節點能夠承載的上限。所以為了擴展寫能力和存儲能力,我們就需要引入集群模式。

面試官:集群中那麼多 Master 節點,Redis Cluster 在存儲的時候如何確定選擇哪個節點呢 ?

小二:這應該是使用了某種 hash 演算法,但是我不太清楚。。。

 

面試官:那好,今天的面試就到這裡吧,你先回去等我們的面試通知。

小二:好的,謝謝面試官,你能告訴我 Redis Cluster 怎麼實現節點選擇的嗎?

面試官:

Redis Cluster 採用的是類一致性哈希演算法實現節點選擇的,至於什麼是一致性哈希演算法你自己回去看看。

Redis Cluster 將自己分成了 16384 個 Slot(槽位),哈希槽類似於數據分區,每個鍵值對都會根據它的 key,被映射到一個哈希槽中,具體執行過程分為兩大步。

1)根據鍵值對的 key,按照 CRC16 演算法計算一個 16 bit 的值。

2)再用 16bit 值對 16384 取模,得到 0~16383 範圍內的模數,每個模數代表一個相應編號的哈希槽。

每個 Redis 節點負責處理一部分槽位,假如你有三個 master 節點 ABC,每個節點負責的槽位如下:

節點 處理槽位
A 0-5000
B 5001 - 10000
C 10001 - 16383
這樣就實現了 cluster 節點的選擇。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 之前學習了一部分的C#基礎,但是感覺會的不多,很多地方依然需要通過做一點小Demo來進行鞏固,那麼這個C#的網路下載器,就來了 原理講解 首先我們編寫代碼之前,我們需要瞭解下網路下載的原理到底是什麼? 學習過C#中IO流部分的知識,或者你有其它的語言的基礎,學習過其它語言的文件IO的基礎,肯定瞭解過 ...
  • 一:背景 1. 講故事 上一篇我們聊到了 Console 為什麼會卡死,讀過那篇文章的朋友相信對 conhost.exe 有了一個大概的瞭解,這一篇更進一步聊一聊視窗的特殊事件 Ctrl+C 底層流轉到底是什麼樣的,為了方便講述,讓 chagtgpt 給我生成一段Ctrl+C 的業務代碼。 clas ...
  • C#棧和隊列的實現 用雙向鏈表實現一個隊列 public class DoubleNode { public int Value; public DoubleNode pre; public DoubleNode next; public DoubleNode(int value) { this.V ...
  • SSL和TLS 瞭解openssl之前,我們首先要瞭解SSL\TLS是什麼。 SSL(Secure Sockets Layer)是一個協議,叫作安全套接層協議。旨在為應用層數據提供加密的傳輸層通道。,即數據從應用層去往傳輸層,會首先被ssl給加密。 但是隨著時間的發展,SSL的繼任者TLS(Tran ...
  • 每次重裝系統後,都要重新安裝軟體,配置環境變數,極為繁瑣。故作環境環境變數備份,常用軟體恢復記錄,前提是你的軟體要安裝在非系統盤,D/E盤等 軟體安裝在非系統盤 開發軟體安裝在非系統盤,建好目錄。重裝系統後,只是重置系統盤,所以這些軟體不需要重新安裝。 譬如 java 相關目錄: PS D:\jav ...
  • 內置參考電壓的使用 應用筆記 前言 CH32V/F 系列單片機能夠在一定的電壓範圍內進行工作,以 CH32V203C8T6 晶元為例,在不使用 USB 外設時,最低工作電壓能夠達到 2.4V。較為寬泛的工作電壓,允許單片機直接使用電池供電,但由於 CH32V203C8T6 晶元沒有獨立的 Vref ...
  • 1、前言 《中庸》有:“九層之台,起於壘土” 之說,那麼對於我們搞技術的人,同樣如此! 對於Linux記憶體管理,你可以說沒有留意過,但是它存在於我們日常開發的方方面面,你所打開的文件,你所創建的變數,你所運行的程式,無不以此為基礎,它可以說是操作系統的基石;只是底層被封裝的太好了,以至於我們在做開發 ...
  • 1. 線程 1.1. MySQL服務端是多線程軟體。它的每個組件都使用線程 1.2. 每個線程至少有兩個唯一標識符 1.2.1. 操作系統線程ID 1.2.2. MySQL內部線程ID 2. 對象類型 2.1. OBJECT_TYPE列 2.2. EVENT 2.3. FUNCTION 2.4. P ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...