京東二面,Redis為什麼那麼快?

程式設計師大彬發表於2022-03-12

本期是【大廠面試】系列文章的第6期,模擬Redis基礎知識高頻面試題目。

面試開始

面試官今天聊聊Redis吧

面試官都說Redis速度快,那Redis為什麼這麼快呢?

大彬:主要是因為以下幾點原因:

  • 基於記憶體:Redis是使用記憶體儲存,沒有磁碟IO上的開銷。資料存在記憶體中,讀寫速度快。
  • 單執行緒實現( Redis 6.0以前):Redis使用單個執行緒處理請求,避免了多個執行緒之間執行緒切換和鎖資源爭用的開銷。
  • IO多路複用模型:Redis 採用 IO 多路複用技術。Redis 使用單執行緒來輪詢描述符,將資料庫的操作都轉換成了事件,不在網路I/O上浪費過多的時間。
  • 高效的資料結構:Redis 每種資料型別底層都做了優化,目的就是為了追求更快的速度。

面試官嗯,剛說到Redis是單執行緒實現的,你認為Redis為何選擇單執行緒呢?

獨白:emm,這得問問Redis作者了...

大彬:1、單執行緒實現可以避免過多的上下文切換開銷。程式始終執行在程式中單個執行緒內,沒有多執行緒切換的場景。

大彬:2、避免同步機制的開銷:如果 Redis選擇多執行緒模型,需要考慮資料同步的問題,則必然會引入某些同步機制,會導致在運算元據過程中帶來更多的開銷,增加程式複雜度的同時還會降低效能。

大彬:3、實現簡單,方便維護:如果 Redis使用多執行緒模式,那麼所有的底層資料結構的設計都必須考慮執行緒安全問題,那麼 Redis 的實現將會變得更加複雜。

面試官Redis應用場景有哪些?

大彬快取熱點資料,緩解資料庫的壓力。

大彬:利用 Redis 原子性的自增操作,可以實現計數器的功能,比如統計使用者點贊數、使用者訪問數等。

大彬作為簡單的訊息佇列,實現非同步操作。

大彬限速器,可用於限制某個使用者訪問某個介面的頻率,比如秒殺場景用於防止使用者快速點選帶來不必要的壓力。

大彬好友關係,利用集合的一些命令,比如交集、並集、差集等,實現共同好友、共同愛好之類的功能。

面試官哦,Redis 怎麼實現訊息佇列?

獨白:臥槽,給自己挖坑了...

大彬:1、使用列表,讓生產者將任務使用LPUSH命令放進列表,消費者不斷用RPOP從列表取出任務。

大彬:2、釋出訂閱模式。類似於MQ的主題模式。只能消費訂閱之後釋出的訊息,一個訊息可以被多個訂閱者消費。

大彬:3、延時佇列。使用sortedset,拿時間戳作為score,訊息內容作為key,呼叫zadd來生產訊息,消費者用zrangebyscore指令獲取N秒之前的資料輪詢進行處理。

面試官來講講Redis主從複製的原理?

大彬:嗯,Redis的複製功能是支援多個資料庫之間的資料同步。主資料庫可以進行讀寫操作,當主資料庫的資料發生變化時會自動將資料同步到從資料庫。從資料庫一般是隻讀的,它會接收主資料庫同步過來的資料。

大彬:下面是主從複製的原理:

  1. 當啟動一個從節點時,它會傳送一個 PSYNC 命令給主節點;
  2. 如果是從節點初次連線到主節點,那麼會觸發一次全量複製。此時主節點會啟動一個後臺執行緒,開始生成一份 RDB 快照檔案;
  3. 同時還會將從客戶端 client 新收到的所有寫命令快取在記憶體中。RDB 檔案生成完畢後, 主節點會將RDB檔案傳送給從節點,從節點會先將RDB檔案寫入本地磁碟,然後再從本地磁碟載入到記憶體中
  4. 接著主節點會將記憶體中快取的寫命令傳送到從節點,從節點同步這些資料;
  5. 如果從節點跟主節點之間網路出現故障,連線斷開了,會自動重連,連線之後主節點僅會將部分缺失的資料同步給從節點。

面試官不錯,瞭解過期鍵的刪除策略嗎?

大彬:1、被動刪除。在訪問key時,如果發現key已經過期,那麼會將key刪除。

大彬:2、主動刪除。定時清理key,每次清理會依次遍歷所有DB,從db隨機取出20個key,如果過期就刪除,如果其中有5個key過期,那麼就繼續對這個db進行清理,否則開始清理下一個db。

大彬:3、記憶體不夠時清理。Redis有最大記憶體的限制,通過maxmemory引數可以設定最大記憶體,當使用的記憶體超過了設定的最大記憶體,就要進行記憶體釋放, 在進行記憶體釋放的時候,會按照配置的淘汰策略清理記憶體。

面試官:很好,今天就到這吧

相關文章