300分鐘吃透分布式緩存-10講:MC是怎么定位key的?

我們在進行 Mc 架構剖析時,除了學習 Mc 的系統架構、網絡模型、狀態機外,還對 Mc 的 slab 分配、Hashtable、LRU 有了簡單的了解。本節課,將進一步深入學習這些知識點。

接下來,進入 Memcached 進階的學習。會講解 Mc 是如何進行 key 定位,如何淘汰回收過期失效 key 的,還將分析 Mc 的內存管理 slab 機制,以及 Mc 進行數據存儲維護的關鍵機理,最后還會對 Mc 進行完整的協議分析,并以 Java 語言為例,介紹 Mc 常用的 client,以及如何進行調優及改進。

key 定位

哈希表

Mc 將數據存儲在 Item 中,然后這些 Item 會被 slabclass 的 4 個 LRU 管理。這些 LRU 都是通過雙向鏈表實現數據記錄的。雙向鏈表在進行增加、刪除、修改位置時都非常高效,但其獲取定位 key 的性能非常低下,只能通過鏈表遍歷來實現。因此,Mc 還通過 Hashtable,也就是哈希表,來記錄管理這些 Item,通過對 key 進行哈希計算,從而快速定位和讀取這些 key/value 所在的 Item,如下圖所示。
在這里插入圖片描述
哈希表也稱散列表,可以通過把 key 映射到哈希表中的一個位置來快速訪問記錄,定位 key 的時間復雜度只有 O(1)。Mc 的哈希表實際是一個一維指針數組,數組的每個位置稱作一個 bucket,即一個桶。性能考慮的需要,Mc 的哈希表的長度設置為 2 的 N 次方。Mc 啟動時,默認會構建一個擁有 6.4萬 個桶的哈希表,隨著新 key 的不斷插入,哈希表中的元素超過閥值后,會對哈希表進行擴容,最大可以構建 2 的 32 次方個桶的哈希表,也就是說 Mc 哈希表經過多次擴容后,最多只能有不超過 43億 個桶。

哈希表設計

對于哈希表設計,有 2 個關鍵點,一個是哈希算法,一個是哈希沖突解決方案。Mc 使用的哈希算法有 2 種,分別是 Murmur3 Hash 和 Jenkins Hash。Mc 當前版本,默認使用 Murmur3 Hash 算法。不同的 key 通過 Hash 計算,被定位到了相同的桶,這就是哈希沖突。Mc 是通過對每個桶啟用一個單向鏈表,來解決哈希沖突問題的。

定位 key

Memcached 定位 key 時,首先根據 key 采用 Murmur3 或者 Jenkins 算法進行哈希計算,得到一個 32 位的無符號整型輸出,存儲到變量 hv 中。因為哈希表一般沒有 2^32 那么大,所以需要將 key 的哈希值映射到哈希表的范圍內。Mc 采用最簡單的取模算法作為映射函數,即采用 hv%hashsize 進行計算。由于普通的取模運算比較耗時,所以 Mc 將哈希表的長度設置為 2 的 n 次方,采用位運算進行優化,即采用 hv&hashmask 來計算。hashmask 即 2 的 n 次方 減 1。

定位到 key 所在的桶的位置后,如果是插入一個新數據,則將數據 Item 采用頭部插入法插入桶的單向鏈表中。如果是查找,則輪詢對應哈希桶中的那個單向鏈表,依次比對 key 字符串,key 相同則找到數據 Item。
在這里插入圖片描述
如果哈希表桶中元素太多,這個鏈表輪詢耗時會比較長,所以在哈希表中元素達到桶數的 1.5 倍之后,Mc 會對哈希表進行 2 倍擴容。由于哈希表最多只有 43 億左右個桶,所以性能考慮,單個 Mc 節點最多存儲 65億 個 key/value。如果要存更多 key,則需要修改 Mc 源碼,將最大哈希,即 HASHPOWER_MAX, 進行調大設置。

哈希表擴容

當 Mc 的哈希表中,Item 數量大于 1.5 倍的哈希桶數量后,Mc 就對哈希表進行擴容處理。如下圖所示,Mc 的哈希擴容是通過哈希維護線程進行處理的。準備開始擴容時,哈希維護線程會首先將所有 IO 工作線程和輔助線程進行暫停,其中輔助線程包括 LRU 維護線程、slab 維護線程、LRU 爬蟲線程。待這些線程暫停后,哈希維護線程會將當前的主哈希表設為舊哈希表,然后將新的主哈希表擴容之前的 2 倍容量。然后,工作線程及輔助線程繼續工作,同時哈希維護線程開始逐步將 Item 元素從舊哈希表遷移到主哈希表。
在這里插入圖片描述
Mc 在啟動時,會根據設置的工作線程數,來構建 一個 Item 鎖哈希表,線程越多,構建的鎖哈希表越大,對于 4 個線程,鎖哈希表有 4096 個桶,對于 10 個線程,鎖哈希表會有 8192 個桶,Item 鎖哈希表最多有 32k 個桶,1k 是 1024,即最多即 32768 個桶。Mc 的鎖哈希表中,每個桶對應一個 Item 鎖,所以 Mc 最多只有 32768 個 Item 鎖。

Mc 哈希表在讀取、變更以及擴容遷移過程中,先將 key hash 定位到 Item 鎖哈希表的鎖桶,然后對 Item 鎖進行加鎖,然后再進行實際操作。實際上,除了在哈希表,在其他任何時候,只要涉及到在對 Item 的操作,都會根據 Item 中的 key,進行 Item 哈希鎖桶加鎖,以避免 Item 被同時讀寫而產生臟數據。Mc 默認有 4096 個鎖桶,所以對 key 加鎖時,沖突的概率較小,而且 Mc 全部是內存操作,操作速度很快,即便申請時鎖被占用,也會很快被釋放。

Mc 哈希表在擴容時,哈希表維護線程,每次按 桶鏈表緯度 遷移,即一次遷移一個桶里單向鏈表的所有 Item 元素。在擴容過程中,如果要查找或插入 key,會參照遷移位置選擇哈希表。如果 key 對應的哈希桶在遷移位置之前,則到新的主哈希表進行查詢或插入,否則到舊哈希表進行查詢和插入。待全部擴容遷移完畢,所有的處理就會全部在新的主哈希表進行。

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

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

相關文章

QT應用軟件【協議篇】周立功CAN接口卡代碼示例

文章目錄 USBCAN系列CAN接口卡規格參數資料下載QT引用周立功的庫安裝sdk代碼USBCAN系列CAN接口卡 USBCAN系列CAN接口卡兼容USB2.0全速規范,可支持1/2/4/8路CAN接口。采用該接口卡,PC機可通過USB連入CAN網絡,進行CAN總線數據采集和處理,主要具備以下幾大優勢特點: 支持車載…

正交匹配追蹤(Orthogonal Matching Pursuit, OMP)的MATLAB實現

壓縮感知(Compressed Sensing, CS)是一種利用稀疏信號的先驗知識,用遠少于奈奎斯特采樣定理要求的樣本數目恢復整個信號的技術。正交匹配追蹤(Orthogonal Matching Pursuit, OMP)是一種常見的貪婪算法(Gree…

【CF】團隊訓練賽2 J-Palindrome Reversion 題解

傳送門:Palindrome Reversion 標簽:字符串 題目大意 規定一個操作:選擇字符串中的一段區間[l,r]并使其翻轉。現在給出一個字符串s,你要判斷能否通過一次操作使其變為回文串。 輸入:一個字符串,其長度不超…

在蘋果電腦MAC上安裝Windows10(雙系統安裝的詳細圖文步驟教程)

在蘋果電腦MAC上安裝Windows10(雙系統安裝的詳細圖文步驟教程) 一、準備工作準備項1:U盤作為系統安裝盤準備項2:您需要安裝的系統鏡像 二、啟動轉換助理步驟1:找到啟動轉換助理步驟2:啟動轉換助理步驟3&…

波奇學Linux:進程通信管道

進程通信 管道:基于文件級別的單向通信 創建父子進程,使得進程的struct file*fd_array[]的文件描述符指向同一個struct file文件,這個文件是內存級文件。 父進程關寫端,子進程再關閉讀端。實現單向通信 子進程寫入,父進…

Java面向對象(三)

一、封裝: 一般意義的封裝:把一段重復代碼抽取成一個函數,稱為代碼的封裝(包裝)面向對象語言的封裝:將類的某些信息隱藏在類的內部(通過使用不同的訪問權限修飾符),不許…

C++ Primer 筆記(總結,摘要,概括)——第3章 字符串、向量和數組

目錄 3.1 命名空間的using聲明 3.2 標準庫類型string 3.2.1 定義和初始化string對象 3.2.2 string對象上的操作 3.2.3 處理string對象中的字符 3.3 標準庫類型vector 3.3.1 定義和初始化vector對象 3.3.2 向vector對象中添加元素 3.3.3 其他vector操作 3.4 迭代器介紹 3.4.…

如何使用rocketmq實現分布式事務?

什么是rocketmq事務消息 事務消息是 Apache RocketMQ 提供的一種高級消息類型,支持在分布式場景下保障消息生產和本地事務的最終一致性。 RocketMQ的分布式事務又稱為“半消息事務”。 事務消息處理流程 RocketMQ是靠半消息機制實現分布式事務 事務消息&#x…

Spring之AOP源碼解析(上)

Aop相關注解 EnableTransactionManagementEnableAspectJAutoProxyEnableAsync... 從注解切入來看看這些注解都干了什么 Import注解作用簡述 注入的類一般繼承ImportSelector或者ImportBeanDefinitionRegistrar接口 繼承ImportSelector接口:selectImports方法返回…

pandas/geopandas 筆記:判斷地點在不在路網上 不在路網的點和路網的距離

0 導入庫 import osimport pandas as pd pd.set_option(display.max_rows,5)import osmnx as oximport geopandas as gpd from shapely.geometry import Point 1 讀取數據 假設我們有 如下的數據: 1.1 新加坡室外基站位置數據 cell_stationpd.read_csv(outdoor…

TSINGSEE青犀AI智能分析網關V4初始配置與算法相關配置介紹

TSINGSEE青犀AI智能分析網關V4內置了近40種AI算法模型,支持對接入的視頻圖像進行人、車、物、行為等實時檢測分析,上報識別結果,并能進行語音告警播放。硬件管理平臺支持RTSP、GB28181協議、以及廠家私有協議接入,可兼容市面上常見…

通過例子學習golang的Goroutine

Go 語言中的 Goroutine 是一種輕量級的并發執行單位。它可以與其他 Goroutine 并發地執行,而不需要顯式地管理線程的創建和銷毀。Goroutine 是 Go 語言并發模型的核心組成部分,它使得編寫并發程序變得更加簡單和高效。 例一 創建兩個function&#xff0…

linux下ffmpeg調用GPU硬件解碼(VDPAU/VAAPI)保存文件

本文講解在linux下面,如何通過ffmpeg調用GPU硬件解碼,并保存解碼完的yuv文件。 其實,ffmpeg自帶的例子hw_decode.c這個文件,就已經能滿足要求了,因此,本文就嘗試講解以下hw_decode這個例子。hw_decode.c可以…

watchpoint

前言 內存被踩,通過 watchpoint 找到真兇 實例 以 smsc911x 網卡驅動為基體,進行實驗,和網卡本身功能無關, 每執行一次 ifconfig eth0 up,就會調用一次 smsc911x_open(),我在這里設計了一段代碼&#xf…

數學知識(四)(容斥原理、博弈論)

一、容斥原理 容斥原理公式 一共加或者減的式子個數 (一)利用容斥原理解決求能被質數整除的數的個數 890計算能被整除的數的個數 因為一共有2^n-1種選法,可以用位運算的方式枚舉,對于得到的每一種選法,根據存在的數…

六、回歸與聚類算法 - 邏輯回歸與二分類

線性回歸欠擬合與過擬合線性回歸的改進 - 嶺回歸分類算法:邏輯回歸模型保存與加載無監督學習:K-means算法 1、應用場景 2、原理 2.1 輸入 2.2 激活函數 3、損失以及優化 3.1 損失 3.2 優化 4、邏輯回歸API 5、分類的評估方法 5.1 精確率和召回率 5.2…

找出作弊的人

文章目錄 題目描述輸入描述輸出描述樣例1解釋:樣例2代碼 題目描述 公司組織了一次考試,現在考試結果出來了,想看一下有沒人存在作弊行為,但是員工太多了,需要先對員工進行一次過濾,再進一步確定是否存在作弊行為。 過濾的規則為:找到分差最小的員工ID對(p1,p2)列表…

【Spring】IoC容器 控制反轉 與 DI依賴注入 配置類實現版本 第四期

文章目錄 基于 配置類 方式管理 Bean一、 配置類和掃描注解二、Bean定義組件三、高級特性:Bean注解細節四、高級特性:Import擴展五、基于注解配置類方式整合三層架構組件總結 基于 配置類 方式管理 Bean Spring 完全注解配置(Fully Annotatio…

Kotlin學習 6

1.接口 interface Movable {var maxSpeed: Intvar wheels: Intfun move(movable: Movable): String}class Car(var name: String, override var wheels: Int 4, _maxSpeed: Int) : Movable {override var maxSpeed: Int _maxSpeedget() fieldset(value) {field value}overr…

C語言讀取 ini 配置文件,修改/添加鍵值對

C語言讀取 ini 配置文件,修改/添加鍵值對 C語言讀取 ini 配置文件,對section中的鍵值對進行修改/添加,如果section不存在,則在末尾將新的section/key/value 添加進去。 一、了解什么是INI文件? ini 文件是Initializ…