memcache核心,一文搞定!面試再也不怕了!

2022-06-23 20:38:52 字數 3033 閱讀 3050

memcache是網際網路分層架構中,使用最多的的kv快取。面試的過程中,memcache相關的問題幾乎是必問的,關於memcache的面試提問,你能回答到哪一個層次呢?

畫外音:很可能關乎,你拿到offer的薪酬檔位。

這一類問題,考察用沒用過,知不知道,相對比較好回答。

關於memcache一些基礎特性,使用過的小夥伴基本都能回答出來:

(1)mc的核心職能是kv記憶體管理,value儲存最大為1m,它不支援複雜資料結構(雜湊、列表、集合、有序集合等);

(2)mc不支援持久化;

(3)mc支援key過期;

(4)mc持續執行很少會出現記憶體碎片,速度不會隨著服務執行時間降低;

(5)mc使用非阻塞io複用網路模型,使用監聽執行緒/工作執行緒的多執行緒模型;

面對這類封閉性的問題,一定要斬釘截鐵,毫無猶豫的給出回答。

這一類問題,考察對於一個工具,只停留在使用層面,還是有原理性的思考。

業務決定技術方案,mc的誕生,以“以服務的方式,而不是庫的方式管理kv記憶體”為設計目標,它顛覆的是,kv記憶體管理元件庫,複雜資料結構與持久化並不是它的初衷。

當然,用“顛覆”這個詞未必不合適,庫和服務各有使用場景,只是在分散式的環境下,服務的使用範圍更廣。設計目標,誕生背景很重要,這一定程度上決定了實現方案,就如redis的出現,是為了有一個更好用,更多功能的快取服務。

畫外音:我很喜歡問這個問題,大部分候選人面對這個沒有標準答案的問題,狀態可能是蒙圈。

懶淘汰(lazy expiration)。

提前分配記憶體。

目的是提高吞吐量。

多執行緒能夠充分的利用多核,但會帶來一些鎖衝突。

面對這類半開放的問題,有些並沒有標準答案,一定要回答出自己的思考和見解。

這一類問題,探測候選人理解得有多透,掌握得有多細,對技術有多刨根究底。

畫外音:所謂“好奇心”,真的很重要,只想要“一份工作”的技術人很難有這種好奇心。

開講之前,先解釋幾個非常重要的概念:

chunk:它是將記憶體分配給使用者使用的最小單元。

item:使用者要儲存的資料,包含key和value,最終都儲存在chunk裡。

slab:它會管理一個固定chunk size的若干個chunk,而mc的記憶體管理,由若干個slab組成。

畫外音:為了避免複雜性,本文先不引入page的概念了。

如上圖所示,一系列slab,分別管理128b,256b,512b…的chunk記憶體單元。

將上圖中管理128b的slab0放大:

能夠發現slab中的一些核心資料結構是:

會從最接近item大小的slab的chunk中,通過free_chunk_list快速找到對應的chunk,如上圖所示,與item大小最接近的chunk是128b。

為什麼不會出現記憶體碎片呢?拿到一個128b的chunk,去儲存一個100b的item,餘下的28b不會再被其他的item所使用,即:實際上浪費了儲存空間,來減少記憶體碎片,保證訪問的速度。

畫外音:理論上,記憶體碎片幾乎不存在。

memcache通過slab,chunk,free_chunk_list來快速分配記憶體,儲存使用者的item,那它又是如何快速實現key的查詢的呢?

沒有什麼特別演算法:

用最樸素的方式,實現key的快速查詢。

當item總數達到hash表長度的1.5倍時,hash表會動態擴容,rehash將資料重新分佈,以保證查詢效率不會不斷降低。

擴充套件hash表之後,同一個key在新舊hash表內的位置會發生變化,如何保證資料的一致性,以及如何保證遷移過程服務的可用性呢(肯定不能加一把大鎖,遷移完成資料,再重新服務吧)?

雜湊表擴充套件,資料遷移是一個耗時的操作,會有一個專門的執行緒來實施,為了避免大鎖,採用的是“分段遷移”的策略。

當item數量達到閾值時,遷移執行緒會分段遷移,對hash表中的一部分桶進行加鎖,遷移資料,解鎖:

新的問題來了,對於已經存在與舊hash表中的item,可以通過上述方式遷移,那麼在item遷移的過程中,如果有新的item插入,是應該插入舊hash表還是新hash表呢?

memcache的做法是,判斷舊hash表中,item應該插入的桶,是否已經遷移至新表中:

為什麼要這麼做呢,不能直接插入新hash表嗎?

memcache沒有給出官方的解釋,樓主揣測,這種方法能夠保證一個桶內的資料,只在一個hash表中(要麼新表,要麼舊錶),任何場景下都不會出現,舊錶新表查詢兩次,以提升查詢速度。

實現“超時”和“過期”,最常見的兩種方法是:

mc的查詢業務非常簡單,只會返回cache hit與cache miss兩種結果,這種場景下,非常適合使用懶淘汰的方式。

懶淘汰的核心是:

舉個例子,假如set了一個key,有效期100s:

這種方式的實現代價很小,消耗資源非常低:

記憶體總是有限的,chunk數量有限的情況下,能夠儲存的item個數是有限的,假如chunk被用完了,該怎麼辦?

仍然是上面的例子,假如128b的chunk都用完了,使用者又set了一個100b的item,要不要擠掉已有的item?

要。這裡的啟示是:

(1)即使item的有效期設定為“永久”,也可能被淘汰;

(2)如果要做全量資料快取,一定要仔細評估,cache的記憶體大小,必須大於,全量資料的總大小,否則很容易採坑;

這裡涉及lru淘汰機制。

如果作業系統的記憶體管理,最常見的淘汰演算法是fifo和lru:

使用lru演算法擠掉item,需要增加兩個屬性:

思路比結論重要。

一文收集全部足浴配方 再也不用去足浴店了

古語云 百病從寒起,寒從腳下生 ,經常在睡覺之前用熱水兼中藥泡腳,不僅可以有效地驅寒,還能有效預防甚至 疾病。中藥泡腳是利用熱水促進藥物滲透...

作為一個文科生,看了這些遇到數學考試就再也不怕了!

數學在考試中的位置 分值極為重要,可以說 得數學者得天下 ,數學能夠學好,對升入理想大學起到很大的作用。對文科生來說更是如此,因為,許多文科...