談談一致性哈希演算法

来源:https://www.cnblogs.com/jilodream/archive/2023/06/02/17452331.html
-Advertisement-
Play Games

一致性哈希演算法是1997年由麻省理工的幾位學者提出的用於解決分散式緩存中的熱點問題。大家有沒有發現,我們之前介紹的例如快排之類的演算法是更早的六七十年代,此時分散式還沒有發展起來,大家往往還在提高單機性能。但是九十年代開始,逐漸需要用分散式集群來解決大型問題,相應的演算法研究也就應運而生。在說到一致性哈 ...


一致性哈希演算法是1997年由麻省理工的幾位學者提出的用於解決分散式緩存中的熱點問題。大家有沒有發現,我們之前介紹的例如快排之類的演算法是更早的六七十年代,此時分散式還沒有發展起來,
大家往往還在提高單機性能。但是九十年代開始,逐漸需要用分散式集群來解決大型問題,相應的演算法研究也就應運而生。
在說到一致性哈希演算法,我們還是得先從緩存的發展談起:
緩存,我們一般是用來提速的,當規模或者說數據量小時,我們往往用單機來部署一套緩存系統即可,如下圖:

多台客戶端在查詢數據時,只要根據key進入緩存伺服器查詢到自己想要的內容即可。
但是隨著業務的發展,單一的緩存伺服器往往無法支撐住我們的業務需要。比如緩存數據太大,多城多活的網路部署等,
我們就需要多台緩存伺服器來支撐,如下圖:

客戶端需要查詢緩存時,先根據哈希演算法,講key進行計算,得到哈希值。然後通過哈希值對機器數取模(%n)來判定落在哪台機器上。
這個架構很簡單,也很易實現,我們就不多說了。
但是這裡會存在一個緩存伺服器伸縮的問題:什麼意思呢?比如目前是三台,我們由於業務的需要,需要變為四台,或者變為兩台。那麼我們需要調整一遍所有數據所處的伺服器位置,因為他們存在的位置都有可能改變。

分散式緩存本來就是為瞭解決大數據量問題的,此時重新調整,勢必會極度影響可用性。那麼如何解決呢?
來看看一致性哈希演算法的思路:
我們假設存在一個虛擬環,這個環足夠大,上邊存在2^32個節點,三台器機器呢,我們根據id計算出他們在環中所處的位置,如圖所示:

 

當我們計算數據所處的緩存位置,不再是根據n來取模,而是根據2^32來取模,此時會有相當多的數據並沒有落在緩存伺服器所處的節點上。
那怎麼辦呢?我們按照順時針方向計算,將數據落在下一個最*的順時針節點上。
如下圖所示:

這樣當我們新增或者刪除節點時,只會影響有限的節點上的數據,極大的縮小了受影響的節點和數據。我們只需要重新計算受影響的數據即可,但是這樣還會存在新的問題:
1、緩存伺服器計算出的位置不均勻,導致覆蓋的節點數差異明顯;
2、數據並不均衡:數據經過哈希和取模運算後,可能落在集中的一片區域中,造成對應的緩存伺服器的數據特別大。
以上問題我們稱之為數據傾斜。數據傾斜的程度明顯後,可能會導致所解決的問題再次出現(前文中的紅字部分)。
那如何解決這種問題呢?很簡單,加節點,只要節點足夠多,那麼就會越來越趨*於*均,數據傾斜的情況就會越不突出。但是緩存伺服器是有限的,並不是想加多少都可以的。
那怎麼辦呢?

我們可以採用虛擬緩存節點的形式解決問題。什麼是虛擬緩存節點,就是並不實際存在的緩存節點。只是一個虛擬的點。
每個真實的緩存伺服器對應多個虛擬緩存節點,兩者是一對多的關係,如下圖所示:

虛擬節點--圖中連接在環上的就是虛擬緩存節點。
真實緩存節點--Cache
每個Cache對應若幹的虛擬節點。當增減Cache時,我們只要調整對應的虛擬節點所對應的數據即可。

 

如果你覺得寫的不錯,歡迎轉載和點贊。 轉載時請保留作者署名jilodream/王若伊_恩賜解脫(博客鏈接:http://www.cnblogs.com/jilodream/


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

-Advertisement-
Play Games
更多相關文章
  • **原文鏈接:** [為什麼說 Go 語言字元串是不可變的?](https://mp.weixin.qq.com/s/AOb6AjKwyTwLeAUou0AU-Q) 最近有讀者留言說,平時在寫代碼的過程中,是會對字元串進行修改的,但網上都說 Go 語言字元串是不可變的,這是為什麼呢? 這個問題本身並 ...
  • aliases: [] tags : " " summary: [基於TCP/IP和UDP協議的Java Socket網路通信編程] author : [yaenli] notekey: [20230512-143738] # Socket 網路模型 Socket編程是在TCP/IP、UDP協議上的 ...
  • # Rust Web 全棧開發之增加教師管理功能 ## 增加教師管理功能 ### 目標 #### Actix HTTP Server #### Actix App - Routes - GET /teachers - GET / teachers /{teacher_id} - POST /teac ...
  • ## 教程簡介 Google Charts 是一個純粹的基於JavaScript的圖表庫,旨在通過添加互動式圖表功能來增強Web應用程式.它支持各種圖表.在Chrome,Firefox,Safari,Internet Explorer(IE)等標準瀏覽器中使用SVG繪製圖表.在傳統的IE 6中,VM ...
  • ## 教程簡介 Excel是辦公室自動化中非常重要的一款軟體,Excel函數則是Excel中的內置函數。Excel函數共包含11類,分別是資料庫函數、日期與時間函數、工程函數、財務函數、信息函數、邏輯函數、查詢和引用函數、數學和三角函數、統計函數、文本函數以及用戶自定義函數。 熟練且高效的使用Exc ...
  • 前端組件 <hd-flex> <el-dialog v-model="isUploadDialog" width="50%" lock-scroll=false> <el-upload class="upload-demo" drag :action="url" :on-success="succe ...
  • 基於java的酒店管理系統設計與實現,酒店訂票系統,酒店預訂系統,酒店信息管理系統,app訂房系統設計與實現; ...
  • 本章將繼續探索內核中解析PE文件的相關內容,PE文件中FOA與VA,RVA之間的轉換也是很重要的,所謂的FOA是文件中的地址,VA則是記憶體裝入後的虛擬地址,RVA是記憶體基址與當前地址的相對偏移,本章還是需要用到`《驅動開發:內核解析PE結構導出表》`中所封裝的`KernelMapFile()`映射函... ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...