談談一致性哈希演算法

来源: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
  • 前言 在我們開發過程中基本上不可或缺的用到一些敏感機密數據,比如SQL伺服器的連接串或者是OAuth2的Secret等,這些敏感數據在代碼中是不太安全的,我們不應該在源代碼中存儲密碼和其他的敏感數據,一種推薦的方式是通過Asp.Net Core的機密管理器。 機密管理器 在 ASP.NET Core ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 順序棧的介面程式 目錄順序棧的介面程式頭文件創建順序棧入棧出棧利用棧將10進位轉16進位數驗證 頭文件 #include <stdio.h> #include <stdbool.h> #include <stdlib.h> 創建順序棧 // 指的是順序棧中的元素的數據類型,用戶可以根據需要進行修改 ...
  • 前言 整理這個官方翻譯的系列,原因是網上大部分的 tomcat 版本比較舊,此版本為 v11 最新的版本。 開源項目 從零手寫實現 tomcat minicat 別稱【嗅虎】心有猛虎,輕嗅薔薇。 系列文章 web server apache tomcat11-01-官方文檔入門介紹 web serv ...
  • C總結與剖析:關鍵字篇 -- <<C語言深度解剖>> 目錄C總結與剖析:關鍵字篇 -- <<C語言深度解剖>>程式的本質:二進位文件變數1.變數:記憶體上的某個位置開闢的空間2.變數的初始化3.為什麼要有變數4.局部變數與全局變數5.變數的大小由類型決定6.任何一個變數,記憶體賦值都是從低地址開始往高地 ...
  • 如果讓你來做一個有狀態流式應用的故障恢復,你會如何來做呢? 單機和多機會遇到什麼不同的問題? Flink Checkpoint 是做什麼用的?原理是什麼? ...
  • C++ 多級繼承 多級繼承是一種面向對象編程(OOP)特性,允許一個類從多個基類繼承屬性和方法。它使代碼更易於組織和維護,並促進代碼重用。 多級繼承的語法 在 C++ 中,使用 : 符號來指定繼承關係。多級繼承的語法如下: class DerivedClass : public BaseClass1 ...
  • 前言 什麼是SpringCloud? Spring Cloud 是一系列框架的有序集合,它利用 Spring Boot 的開發便利性簡化了分散式系統的開發,比如服務註冊、服務發現、網關、路由、鏈路追蹤等。Spring Cloud 並不是重覆造輪子,而是將市面上開發得比較好的模塊集成進去,進行封裝,從 ...
  • class_template 類模板和函數模板的定義和使用類似,我們已經進行了介紹。有時,有兩個或多個類,其功能是相同的,僅僅是數據類型不同。類模板用於實現類所需數據的類型參數化 template<class NameType, class AgeType> class Person { publi ...
  • 目錄system v IPC簡介共用記憶體需要用到的函數介面shmget函數--獲取對象IDshmat函數--獲得映射空間shmctl函數--釋放資源共用記憶體實現思路註意 system v IPC簡介 消息隊列、共用記憶體和信號量統稱為system v IPC(進程間通信機制),V是羅馬數字5,是UNI ...