一致性哈希算法 應用

互聯網創業中大部分人都是草根創業,這個時候沒有強勁的服務器,也沒有錢去買很昂貴的海量數據庫。在這樣嚴峻的條件下,一批又一批的創業者從創業中獲得成 功,這個和當前的開源技術、海量數據架構有著必不可分的關系。比如我們使用mysql、nginx等開源軟件,通過架構和低成本服務器也可以搭建千萬級用 戶訪問量的系統。新浪微博、淘寶網、騰訊等大型互聯網公司都使用了很多開源免費系統搭建了他們的平臺。所以,用什么沒關系,只要能夠在合理的情況下采用合 理的解決方案。

那怎么搭建一個好的系統架構呢?這個話題太大,這里主要說一下數據分流的方式。比如我們的數據庫服務器只能存儲200個數據,突然要搞一個活動預估達到600個數據。
可以采用兩種方式:橫向擴展或者縱向擴展。
縱向擴展是升級服務器的硬件資源。但是隨著機器的性能配置越高,價格越高,這個代價對于一般的小公司是承擔不起的。
橫向擴展是采用多個廉價的機器提供服務。這樣一個機器只能處理200個數據、3個機器就可以處理600個數據了,如果以后業務量增加還可以快速配置增加。在大多數情況都選擇橫向擴展的方式。如下圖:
圖1

圖2

現在有個問題了,這600個數據如何路由到對應的機器。需要考慮如果均衡分配,假設我們600個數據都是統一的自增id數據,從1~600,分成3 堆可以采用 id mod 3的方式。其實在真實環境可能不是這種id是字符串。需要把字符串轉變為hashcode再進行取模。

目前看起來是不是解決我們的問題了,所有數據都很好的分發并且沒有達到系統的負載。但如果我們的數據需要存儲、需要讀取就沒有這么容易了。業務增多 怎么辦,大家按照上面的橫向擴展知道需要增加一臺服務器。但是就是因為增加這一臺服務器帶來了一些問題。看下面這個例子,一共9個數,需要放到2臺機器 (1、2)上。各個機器存放為:1號機器存放1、3、5、7、9 ,2號機器存放 2、4、6、8。如果擴展一臺機器3如何,數據就要發生大遷移,1號機器存放1、4、7, 2號機器存放2、5、8, 3號機器存放3、6、9。如圖:

圖3
從圖中可以看出 1號機器的3、5、9遷移出去了、2好機器的4、6遷移出去了,按照新的秩序再重新分配了一遍。數據量小的話重新分配一遍代價并不大,但如果我們擁有上 億、上T級的數據這個操作成本是相當的高,少則幾個小時多則數天。并且遷移的時候原數據庫機器負載比較高,那大家就有疑問了,是不是這種水平擴展的架構方 式不太合理?

—————————–華麗分割線—————————————

一致性hash就是在這種應用背景提出來的,現在被廣泛應用于分布式緩存,比如memcached。下面簡單介紹下一致性hash的基本原理。最早 的版本 http://dl.acm.org/citation.cfm?id=258660。國內網上有很多文章都寫的比較好。如: http://blog.csdn.net/x15594/article/details/6270242

下面簡單舉個例子來說明一致性hash。

準備:1、2、3 三臺機器
還有待分配的9個數 1、2、3、4、5、6、7、8、9
一致性hash算法架構

步驟
一、構造出來 2的32次方 個虛擬節點出來,因為計算機里面是01的世界,進行劃分時采用2的次方數據容易分配均衡。另 2的32次方是42億,我們就算有超大量的服務器也不可能超過42億臺吧,擴展和均衡性都保證了。
一致性hash
二、將三臺機器分別取IP進行hashcode計算(這里也可以取hostname,只要能夠唯一區別各個機器就可以了),然后映射到2的32次方上去。 比如1號機器算出來的hashcode并且mod (2^32)為 123(這個是虛構的),2號機器算出來的值為 2300420,3號機器算出來為 90203920。這樣三臺機器就映射到了這個虛擬的42億環形結構的節點上了。
圖5
三、將數據(1-9)也用同樣的方法算出hashcode并對42億取模將其配置到環形節點上。假設這幾個節點算出來的值為 1:10,2:23564,3:57,4:6984,5:5689632,6:86546845,7:122,8:3300689,9:135468。可 以看出 1、3、7小于123, 2、4、9 小于 2300420 大于 123, 5、6、8 大于 2300420 小于90203920。從數據映射到的位置開始順時針查找,將數據保存到找到的第一個Cache節點上。如果超過2^32仍然找不到Cache節點,就會 保存到第一個Cache節點上。也就是1、3、7將分配到1號機器,2、4、9將分配到2號機器,5、6、8將分配到3號機器。
圖6
這個時候大家可能會問,我到現在沒有看見一致性hash帶來任何好處,比傳統的取模還增加了復雜度。現在馬上來做一些關鍵性的處理,比如我們增加一臺機 器。按照原來我們需要把所有的數據重新分配到四臺機器。一致性hash怎么做呢?現在4號機器加進來,他的hash值算出來取模后是12302012。 5、8 大于2300420 小于12302012 ,6 大于 12302012 小于90203920 。這樣調整的只是把5、8從3號機器刪除,4號機器中加入 5、6。
圖7
同理,刪除機器怎么做呢,假設2號機器掛掉,受影響的也只是2號機器上的數據被遷移到離它節點,上圖為4號機器。
圖8
大家應該明白一致性hash的基本原理了吧。不過這種算法還是有缺陷,比如在機器節點比較少、數據量大的時候,數據的分布可能不是很均衡,就會導致其中一 臺服務器的數據比其他機器多很多。為了解決這個問題,需要引入虛擬服務器節點的機制。如我們一共有只有三臺機器,1、2、3。但是實際又不可能有這么多機 器怎么解決呢?把 這些機器各自虛擬化出來3臺機器,也就是 1a 1b 1c 2a 2b 2c 3a 3b 3c,這樣就變成了9臺機器。實際 1a 1b 1c 還是對應1。但是實際分布到環形節點就變成了9臺機器。數據分布也就能夠更分散一點。如圖:
圖91

寫了這么多一致性hash,這個和分布式搜索有什么半點關系?我們現在使用solr4搭建了分布式搜索,測試了基于solrcloud的分布式平臺 提交20條數據居然需要幾十秒,所以就廢棄了solrcloud。采用自己hack solr平臺,不用zookeeper做分布式一致性管理平臺,自己管理數據的分發機制。既然需要自己管理數據的分發,就需要考慮到索引的創建,索引的更 新。這樣我們的一致性hash也就用上了。整體架構如下圖:

圖10
建立和更新需要維持機器的位置,能夠根據數據的key找到對應的數據分發并更新。這里需要考慮的是如何高效、可靠的把數據建立、更新到索引里。
備份服務器防止建立服務器掛掉,可以根據備份服務器快速恢復。
讀服務器主要做讀寫分離使用,防止寫索引影響查詢數據。
集群管理服務器管理整個集群內的服務器狀態、告警。

整個集群隨著業務增多還可以按照數據的類型劃分,比如用戶、微博等。每個類型按照上圖架構搭建,就可以滿足一般性能的分布式搜索。對于solr和分布式搜索的話題后續再聊。

擴展閱讀:
java的hashmap隨著數據量的增加也會出現map調整的問題,必要的時候就初始化足夠大的size以防止容量不足對已有數據進行重新hash計算。

疫苗:Java HashMap的死循環 http://coolshell.cn/articles/9606.html
一致性哈希算法的優化—-關于如何保正在環中增加新節點時,命中率不受影響 (原拍拍同事scott)http://scottina.iteye.com/blog/650380

語言實現:
http://weblogs.java.net/blog/2007/11/27/consistent-hashing java 版本的例子
http://blog.csdn.net/mayongzhan/archive/2009/06/25/4298834.aspx PHP 版的例子
http://www.codeproject.com/KB/recipes/lib-conhash.aspx C語言版本例子

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

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

相關文章

(9)How to take a picture of a black hole

https://www.ted.com/talks/katie_bouman_what_does_a_black_hole_look_like/transcript 00:13In the movie "Interstellar[??nt?r?stel?(r)]星際的," we get an up-close look at a supermassive black hole. Set against a backdrop of bright gas, the black…

單個節點的緩存容量達到上限 Hash算法一致性

場景 單個節點的緩存容量達到上限,無法繼續單點增加內存,如何解決? 單個節點支撐的QPS達到上限,如何解決? 初步方案 增加N個緩存節點,為了保證緩存數據的均勻,一般情況會采用對key值hash&…

java學習筆記11 (構造方法 this深探)

在開發中,經常需要在創建對象的同事明確對象對的屬性值,比如一個person對象創建的時候就應該有name和age 等屬性,那么如何做到在創建對象的同時給對象的屬性值初始化值呢? 這里介紹構造方法 1 構造方法沒有返回值類型,…

密碼中不能包含全角字符的正則表達式

String regex "^((?![^\\x00-\\xff]).)*$"; String str "aA"; System.out.println(str.matches(regex));

編程算法 - 將排序數組按絕對值大小排序 代碼(java)

一個含有多個元素的數組&#xff0c;有多種排序方式。它可以升序排列&#xff0c;可以降序排列&#xff0c;也可以像我們以前章節說過的&#xff0c;以波浪形方式排序&#xff0c;現在我們要看到的一種是絕對值排序。對于數組A,絕對值排序滿足以下條件&#xff1a;|A[i]| < …

QT Linux打包發布

Linux&#xff1a; 1、用Release編譯&#xff1b; 2、把可執行文件(如paike)放入新建目錄中; 3、當前目錄下編寫腳本copyDependency.sh&#xff0c;把動態鏈接庫導入當前目錄&#xff1b; #!/bin/shexe"paike" #發布的程序名稱destination"/home/paike"…

CRM公海自動回收規則

企微云CRM操作指南 – 道一云|企微https://wbg.do1.com.cn/xueyuan/2568.html 銷售云 - 美洽 - 連接客戶&#xff0c;親密無間https://meiqia.com/sales-cloud 轉載于:https://www.cnblogs.com/rgqancy/p/10695466.html

三分鐘看懂一致性哈希算法

一致性哈希算法&#xff0c;作為分布式計算的數據分配參考&#xff0c;比傳統的取模&#xff0c;劃段都好很多。 在電信計費中&#xff0c;可以作為多臺消息接口機和在線計費主機的分配算法&#xff0c;根據session_id來分配&#xff0c;這樣當計費主機動態伸縮的時候&#xf…

數據結構09圖

第七章 圖 Graph 7.1 圖的定義和術語 頂點 Vertex V 是頂點的有窮非空集合&#xff0c;頂點數 |V| n VR 兩個頂點之間關系的集合&#xff0c;邊數 |VR| e 有向圖 Digraph <v, w> Arc v Tail / Inital node w Head / Terminal node 無向圖 Undigraph <v, w> 必…

JVM調優-GC參數

一、Throughput收集器(吞吐量) -XX:UseParallelGC -XX:UseParallelOldGC *參數調整&#xff1a;通過調整堆大小&#xff0c;減少GC停頓時間&#xff0c;增大吞吐量 增強堆大小可以減少Full GC頻率&#xff0c;但卻會增加停頓時間 1.手動調整 -Xmn -Xms -XX:NewRatioN 手動指…

aspnetcore源碼學習(一)

---恢復內容開始--- 筆者從事netcore相關項目開發已經大半年了&#xff0c;從netcore 1.0到現在3.0大概經過了3年左右的時間&#xff0c;記得netcore剛出來的時候國內相關的學習資料缺乏&#xff0c;限制于外語不大熟練的限制國外的相關書籍看起來相當吃力&#xff0c;于是在當…

評估一個垃圾收集(GC)

在實踐中我們發現對于大多數的應用領域&#xff0c;評估一個垃圾收集(GC)算法如何根據如下兩個標準&#xff1a; 吞吐量越高算法越好暫停時間越短算法越好 首先讓我們來明確垃圾收集(GC)中的兩個術語:吞吐量(throughput)和暫停時間(pause times)。 JVM在專門的線程(GC threads…

python數據分析常用包之Scipy

Scipy轉載于:https://www.cnblogs.com/jacky912/p/10697853.html

docker容器狀態跟蹤及疑惑

一、 1 def status_test():2 container client.containers.create("comp")3 print ("create: ", container.status)4 container.start()5 print ("start: ", container.status)6 container.pause()7 print ("paus…

CAP和BASE理論

幾個名詞解釋&#xff1a; 網絡分區&#xff1a;俗稱“腦裂”。當網絡發生異常情況&#xff0c;導致分布式系統中部分節點之間的網絡延時不斷變大&#xff0c;最終導致組成分布式系統的所有節點中&#xff0c;只有部分節點之間能夠進行正常通信&#xff0c;而另一些節點則不能…

Mysql案例5:取得平均薪資最高的部門的部門名稱

一、要求&#xff1a;查詢平均薪水最高部門的部門編號 二、背景&#xff1a;當前數據庫有employee表和department表&#xff0c;數據分別如下&#xff1a; employee表&#xff1a; department表&#xff1a; 三、難點&#xff1a; 1、需要考慮最高平均薪資可能在多個部門同時出…

Spring 處理過程分析

一、處理過程分析 1、首先&#xff0c;Tomcat每次啟動時都會加載并解析/WEB-INF/web.xml文件&#xff0c;所以可以先從web.xml找突破口&#xff0c;主要代碼如下&#xff1a;<servlet ><servlet-name >spring-mvc</servlet-name><!-- servlet類 --><…

python全棧開發中級班全程筆記(第二模塊、第四章)(常用模塊導入)

python全棧開發筆記第二模塊 第四章 &#xff1a;常用模塊&#xff08;第二部分&#xff09; 一、os 模塊的 詳解 1、os.getcwd() &#xff1a;得到當前工作目錄&#xff0c;即當前python解釋器所在目錄路徑 import os j os.getcwd() # 返回當前pyt…

基于 Spring Cloud 完整的微服務架構實戰

本項目是一個基于 Spring Boot、Spring Cloud、Spring Oauth2 和 Spring Cloud Netflix 等框架構建的微服務項目。 作者&#xff1a;Sheldon地址&#xff1a;https://github.com/zhangxd1989 技術棧 Spring boot - 微服務的入門級微框架&#xff0c;用來簡化 Spring 應用的初…

mysql Invalid use of group function的解決辦法

錯誤語句&#xff1a;SELECT s.SID, s.Sname, AVG(a.score)FROM student sLEFT JOIN sc a ON s.SID a.SID WHERE AVG(a.score) > 60GROUP BY s.SID正確語句&#xff1a; SELECTs.SID,s.Sname,AVG(a.score)FROMstudent sLEFT JOIN sc a ON s.SID a.SID GROUP BYs.SID HAVIN…