Maglev : A Fast and Reliable Software Network Load Balancer (using Consistent Hashing)

来源:https://www.cnblogs.com/feiquan/archive/2022/05/19/16289675.html
-Advertisement-
Play Games

轉自:https://www.evanlin.com/maglev/ 2016 年 6 月 2 日 前言(為什麼想讀這一篇論文) 這一篇論文吸引我註意的原因是,Consistent Hashing本來的特性就是作為分散式緩存之用。谷歌將他們的負載均衡器(代號:Maglev)發佈他的實作方式,裡面將一 ...


  轉自:https://www.evanlin.com/maglev/    

前言(為什麼想讀這一篇論文)

這一篇論文吸引我註意的原因是,Consistent Hashing本來的特性就是作為分散式緩存之用。谷歌將他們的負載均衡器(代號:Maglev)發佈他的實作方式,裡面將一致的哈希並做了一些小改版來符合他們的需求。

此前我一直在進一步學習,因為谷歌很好地利用了它的能力,因此更有效地提高了它的能力。就想要閱讀這一篇論文。

本篇導讀主要內容如下:

  • 介紹 Maglev 的特性和改進的部分
  • 回顧一致哈希
  • 介紹磁懸浮哈希



原始論文

Maglev:快速可靠的軟體網路負載均衡器



導讀

什麼是磁懸浮?

Maglev 是 Google 的軟體 Load Balancer ,是一般硬體的 Load Balancer ,他可以在一般的 Linux 機器上面運行。Maglev 在 Google 內部已經運行了超過六年(從 2008 年開始)。一個 Maglev 可以處理 10Gbps 的小封包鏈接。

 

磁懸浮主要的功能與特色

Maglev 作為 Google 內部的高效能體軟負載均衡器,他有以下兩個主要功能:

  • 新的一致性哈希演算法稱為磁懸浮哈希
  • 連接跟蹤

 

回過頭來,那什麼是 Consistent Hashing ?

講到 Consistent Hashing 就必須提到原本分散式緩存的准許靠是 Hash Table 的方式來結果,如:

  • 來源ip:1.2.3.4通過將來源ip做散列之後指向server1
  • 來源ip:1.2.3.5通過將來源ip做散列之後指向server2
  • 來源ip:1.2.4.6通過將來源ip做散列之後指向server3

如果你能確定如果server1發生故障,那麼1.2.3.4就無法連接到任何伺服器。

Consistent Hashing 就是在這裡發揮效果。根據定義的Consistent Hashing 為一個示例的以下表格的表格,根據Hashing 的表格需要不同的條件來滿足不同的節點信息,並且滿足兩個條件

  • Minimal Disruption:如果有被修改的部分,應該只需要到達該部分影響的部分就可以了。在 Consistent Hashing 裡面有下麵一個的方式.貫穿整個索引示例後,直接指定下一個節點作為哈希後的結果節點。簡單的示例如下:
    • 來源 IP 位置1.2.3.4,經過哈希處理後得到的位置 1024(假設)
    • 到表格 1024 查詢資料,發現 1024 的節點server1伺服器已經出現故障.
    • 尋找1024個最接近的下一個偏差(假設是1028個)並且到了server2
    • 分配server2

  • 負載平衡也有可能會過地地讓其他任何人都使用到,不會有某種程度的應用的疑慮。在 Consistent Hashing 裡面是使用 Virtual Node .
    • 簡單的說,也就是在加入節點的時候,會一併複製多個虛擬節點(通常使用節點#1, 節點#2 ... 修飾方式.
    • 透過多個虛擬節點散佈在各處,讓尋找的時間更變的分佈到不同的節點。

 

對於 Maglev 而言,原本的 Consistent Hashing 有什麼缺點(限制)?

Hashing 本身已經解決了許多問題,但是 Google 確實需要考慮以下幾個額外的問題:

  • 需要更均勻地配置每個節點位置:由於谷歌的每個節點都可能是一個可能的台機,因此,根據不同的演播信息,需要很大的查找表。
  • 需要更減少干擾:針對谷歌的需求,演演算法需要小量的干擾.

 

關於磁懸浮哈希演算法的介紹

可知需要額外考量(應該說是要強化)的更多部分,Google 提出了新的 Consistent Hashing 的演演算法,稱為Maglev Hashing Algorithm

主要概念:新增偏好列表概念

偏好列表(每一個偏好列表) 會分配給一個節點,讓自己的位置上去(Permutation)。直到整個表格是完整的。

 

功效:

這裡需要註意,如果相當接近ññ的話,功效很容易落入最差的狀況。

如果但是> >>>ñ,比較容易實現入戶的情況。

  • 平均狀況:O (l奧克米_ _)(lG)
  • 最差情況:Ø (2)(2)

其中:

  • 是表示查找表的大小.
  • ññ是表示節點的個數.

 

流程:

  • 首先 Maglev Hashing 會先把所有的 Preference List 產生出來。
  • 通過並產生好的偏好列表開始將節點一個個地加入產生出的查找表

 

程式碼分析:

計算“排列表格”排列表

下麵首先簡單排列generatePopulation(),主要目的是建立一個組合表的表格。

//name is the list of backend.
func generatePopulation() {
	//如果 []name 是空的就離開
	if len(name) == 0 {
		return
	}

	for i := 0; i < len(name); i++ {
		bData := []byte(name[i])

		//計算 offset 透過 Hash K1
		offset := siphash.Hash(0xdeadbabe, 0, bData) % M
		//計算 skip 透過 Hash K2
		skip := (siphash.Hash(0xdeadbeef, 0, bData) % (M - 1)) + 1

		iRow := make([]uint64, M)
		var j uint64
		for j = 0; j < m.m; j++ {
			//排列組合的表格
			iRow[j] = (offset + uint64(j)*skip) % M
		}

		permutation = append(permutation, iRow)
	}
}

必須M是一個素數(如果不給素數,它的排列就必須有重覆值),M=7這個典型的式可能[3, 2, 5, 6, 0, 4, 1]會產生[0, 5, 6, 4, 2, 3, 1]的排列形式是為之後使用的。

產生查表(查閱表)

論文中的 Populate Maglev Hashing 查找表的 Golang 程式。

這邊有兩個表格:

  • entry: 代表表格裡面沒有走過。架設查找表大小為7,就得0~6 都走了一次。(索引為-1).而最後的分數就是節點的
  • next: 代表排列表格的下一個位置,如果有三個,那麼有三個表格。這樣next大小也有三個分別排列的記錄,每一個表格排列成第幾個位置。

翻譯資料

unc (m *Maglev) populate() {
	if len(m.nodeList) == 0 {
		return
	}

	var i, j uint64
	next := make([]uint64, m.n)
	entry := make([]int64, m.m)
	for j = 0; j < m.m; j++ {
		entry[j] = -1
	}

	var n uint64

	for { //true
		for i = 0; i < m.n; i++ {
			c := m.permutation[i][next[i]]
			for entry[c] >= 0 {
				next[i] = next[i] + 1
				c = m.permutation[i][next[i]]
			}

			entry[c] = int64(i)
			next[i] = next[i] + 1
			n++

			if n == m.m {
				m.lookup = entry
				return
			}
		}

	}

}

下麵用簡單的翻譯資料,希望能夠讓大家更容易瞭解。

N = 3
M = 5

m.permutation [0] = [4, 3, 2, 1, 0]
m.permutation [1] = [3, 2, 1, 0, 4]
m.permutation [2] = [0, 1, 2, 3, 4]

通過這個實例,建立出查找表的方式如下:

  • 將剛剛建立出的排列形式來
  • i=0,從第一個排列表格的第一個挑出分數 c1=4,那麼entry[4] = 0(代表查找表中entry[4]指向節點0
  • i=1,從第二個排列表格的第一個挑出分數 c2=3,那麼entry[3] = 1
  • i=2,從第三個排列表個的第一個挑出分數 c3=0,那麼entry[0] = 2
  • i跑迴圈, i=0挑出一個(索引=走過第二個c4=3entry[3]往後第一個next[0] +1m.permutation[0][2]=2entry[2]=0
  • 依此類推所有的n == M。此時,也發現entry[]不再存在任何-1

詳細走法如下圖:

Maglev Hashing 跟 Consistent Hashing 的比較

推薦部分研究的那部分,應該屬於我比較看重的。

  • 一致的哈希
    • 準備工作:
      • 將每個節點的分數根據散列鍵查找表
      • 製作出虛擬節點來達到平衡.
    • 如何查詢:
      • 將分數貫穿 Hash Key 到一個查找表索引
      • 如果該索引沒有節點,往下尋找最接近的節點
  • 磁懸浮哈希
    • 準備工作:
      • 需要先建立一個排列表格
      • 請並請先通過排列表格排列一個排序偏好清單。
    • 如何查詢:
      • 索引的索引 Hash Key 到一個查找表
      • 準備工作,該指數持續存在
      • 傳回節點資料

完整的程式碼

這裡有我的完整程式碼,大家可以參考一下:

https://github.com/kkdai/maglev

參考


  如果是此文是轉載文章,本人會附上轉載鏈接,此篇文章的版權歸原創作者所屬,如果侵權請與我聯繫,我會刪除此文。

若沒有標明轉載鏈接,此篇文章屬於本人的原創文章,其版權所屬:
作者:feiquan
出處:http://www.cnblogs.com/feiquan/
版權聲明:本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。
大家寫文都不容易,請尊重勞動成果~ 這裡謝謝大家啦(*/ω\*)

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

-Advertisement-
Play Games
更多相關文章
  • 這幾天是Spring版本日,很多Spring工件都發佈了新版本, Spring Framework 6.0.0 發佈了第 4 個裡程碑版本,此版本包含所有針對 5.3.20 的修複補丁,以及特定於 6.0 分支的 39 項修複和改進。而今天Spring Boot 2.7.0和Spring Secur ...
  • Anaconda 是一個跨平臺的版本,通過命令行來管理安裝包。進行大規模數據處理、預測分析和科學計算。它包括近 200 個工具包,大數據處理需要用到的常見包有 NumPy 、 SciPy 、 pandas 、 IPython 、 Matplotlib 、 Scikit-learn 、statsmod ...
  • #Scanner對象 java.util.Scanner是java5的特征,可以通過Scanner類來獲取用戶的輸入。 基本語法: 通過Scanner類的next()與nextLine()方法獲取輸入的字元串,在讀取前一般需要使用hasNext()與hasNextLine()判斷是否還有輸入的數據。 ...
  • JSP:全拼寫:java Server pages:java 伺服器端頁面 可以理解為一個特殊的頁面:可以定義html代碼也可以定義java的代碼 定義:JSP是簡化Servlet編寫的一種技術,它將Java代碼和HTML語句混合在同一個文件中編寫,只對網頁中的要動態產生的內容採用Java代碼來編寫... ...
  • 卸載redis # 查詢redis進程 ps -ef | grep redis # 關閉進程 kill -9 6379 # 停止redis-cli redis-cli shutdown # 刪除local目錄下與redis相關的文件 rm -rf /usr/local/bin/redis-* 安裝r ...
  • 異常 異常定義 異常是運行過程中出現的錯誤 人為錯誤:填寫錯誤等 隨機錯誤:網路中斷、記憶體耗盡等 一個健壯的程式必須處理各種各樣的錯誤 Java的異常是class Object Throwable Error OutOfMemoryError Exception RuntimeException N ...
  • 一、反射 《java核心技術》 官方套話:能夠分析類能力的程式成為反射。 又通過網上搜索有這句話:反射指程式可以訪問、檢測和修改它本身狀態或行為的一種能力。 反射是用來乾什麼的呢? “明明我自己能直接new一個對象,為什麼它要繞一個圈子,先拿到Class對象,再調用Class對象的方法來創建對象呢, ...
  • #包機制 包就是裝代碼的文件夾。 為了更好地組織類,JAVA提供了包機制,用於區別類名的組織空間。 ##package 包語句的句法格式為: 一般利用公司功能變數名稱倒置作為包名。 ##import 為了使用某個包的成員,需要在JAVA程式中明確導入該包。使用import語句可以完成此功能。 import必 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...