這篇文章跟大家分享一些Redis中關於分散式快取的面試題,內含答案解析。有一定的參考價值,有需要的朋友可以參考一下,希望對大家有幫助。
redis 和 memcached 有什麼不同? redis 的線程模型是什麼?為什麼 redis 單線程卻能支撐高並發?
面試官心理分析
這個是問redis 的時候,最基本的問題吧,redis 最基本的一個內部原理與特點,就是redis 其實是個單執行緒工作模型,你要是這個都不知道,那後面玩兒redis 的時候,出了問題豈不是什麼都不知道?
還有可能面試官會問你redis 和memcached 的區別,但是memcached 是早些年各大互聯網公司常用的緩存方案,但是現在近幾年基本上都是redis,沒什麼公司用memcached了。 【相關推薦:Redis影片教學】
面試題剖析
redis 和memcached 有啥區別?
redis 支援複雜的資料結構
redis 相較於 memcached 來說,擁有更多的資料結構,能支援更豐富的資料操作。如果需要快取能夠支援更複雜的結構和操作, redis 會是不錯的選擇。
redis 原生支援叢集模式
在redis3.x 版本中,便能支援cluster 模式,而memcached 沒有原生的叢集模式,需要依賴客戶端來實作往叢集中分片寫入數據。
效能比較
由於redis 只使用單核心,而memcached 可以使用多核心,所以平均每一個核上redis 在儲存小數據時比memcached 性能更高。而在 100k 以上的數據中,memcached 效能要高於 redis。雖然 redis 最近也在儲存大數據的效能上進行最佳化,但比起 memcached,還是稍有遜色。
redis 的執行緒模型
redis 內部使用檔案事件處理器 file event handler
,這個檔案事件處理器是單執行緒的,所以redis 才叫做單線程的模型。它採用 IO 多工機制同時監聽多個 socket,將產生事件的 socket 壓入記憶體佇列中,事件分派器根據 socket 上的事件類型來選擇對應的事件處理器進行處理。
檔案事件處理器的結構包含4 個部分:
多個socket 可能會並發產生不同的操作,每個操作對應不同的檔案事件,但是IO 多工程式會監聽多個socket,會將產生事件的socket 放入佇列中排隊,事件分派器每次從佇列中取出一個socket,根據socket 的事件類型交給對應的事件處理器進行處理。
來看客戶端與redis 的一次溝通過程:
要明白,通訊是透過socket 來完成的,不懂的同學可以先去看看socket 網路程式設計。
首先,redis 服務端進程初始化的時候,會將 server socket 的 AE_READABLE
事件與連線回應處理器關聯。
客戶端socket01 向redis 進程的server socket 請求建立連接,此時server socket 會產生一個 AE_READABLE
事件,IO 多工程式監聽到server socket 產生的事件後,將該socket 壓入佇列中。檔案事件分派器從佇列中取得 socket,交給連接應答處理器。連接應答處理器會建立一個能與客戶端通訊的 socket01,並將該 socket01 的 AE_READABLE
事件與指令請求處理器關聯。
假設此時用戶端發送了一個 set key value
請求,此時redis 中的socket01 會產生 AE_READABLE
事件,IO 多重化程式將socket01壓入佇列,此時事件分派器從佇列中取得到socket01 產生的 AE_READABLE
事件,由於前方socket01 的 AE_READABLE
事件已經與指令請求處理器關聯,因此事件分派器將事件交給指令請求處理器來處理。指令要求處理器讀取 socket01 的 key value
並在自己記憶體中完成 key value
的設定。操作完成後,它會將 socket01 的 AE_WRITABLE
事件與命令回復處理器關聯。
如果此時客戶端準備好接收回傳結果了,那麼redis 中的socket01 會產生一個 AE_WRITABLE
事件,同樣壓入佇列中,事件分派器找到相關聯的指令回復處理器,由指令回復處理器對socket01 輸入本次操作的一個結果,例如 ok
,之後解除socket01 的 AE_WRITABLE
事件與指令回復處理器的關聯。
這樣便完成了一次通訊。關於 Redis 的一次溝通過程,建議讀者閱讀《Redis 設計與實作-黃健宏》進行系統學習。
為啥 redis 單執行緒模型也能效率這麼高?
edis 的並發競賽問題是什麼?如何解決這個問題?了解 redis 事務的 CAS 方案嗎?
面試官心理分析
這個也是線上非常常見的問題,就是多重客戶端同時並發寫一個key,可能本來應該先到的資料後到了,導致資料版本錯了;或是多客戶端同時取得一個key,修改值之後再寫回去,只要順序錯了,資料就錯了。
而且 redis 自己就有天然解決這個問題的 CAS 類別的樂觀鎖方案。
面試題剖析
某個時刻,多個系統實例都會去更新某個 key。可以基於 zookeeper 實作分散式鎖定。每個系統透過 zookeeper 取得分散式鎖定,確保同一時間,只能有一個系統實例在操作某個 key,別人都不允許讀取和寫入。
你要寫入快取的數據,都是從mysql 裡查出來的,都得寫入mysql 中,寫入mysql 中的時候必須保存一個時間戳,從mysql 查出來的時候,時間戳也查出來。
每次要寫之前,先判斷一下目前這個 value 的時間戳記是否比快取裡的 value 的時間戳記要新。如果是的話,那麼可以寫,否則,就不能用舊的資料覆蓋新的資料。
更多程式相關知識,請造訪:程式設計影片! !
以上是分享一些Redis中關於分散式快取的面試題(附答案解析)的詳細內容。更多資訊請關注PHP中文網其他相關文章!