生活随笔
收集整理的這篇文章主要介紹了
一致性哈希算法与Java实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
來源:http://blog.csdn.net/wuhuan_wp/article/details/7010071
?一致性哈希算法是分布式系統中常用的算法。比如,一個分布式的存儲系統,要將數據存儲到具體的節點上,如果采用普通的hash方法,將數據映射到具體的節點上,如key%N,key是數據的key,N是機器節點數,如果有一個機器加入或退出這個集群,則所有的數據映射都無效了,如果是持久化存儲則要做數據遷移,如果是分布式緩存,則其他緩存就失效了。
? ? 因此,引入了一致性哈希算法:
把數據用hash函數(如MD5),映射到一個很大的空間里,如圖所示。數據的存儲時,先得到一個hash值,對應到這個環中的每個位置,如k1對應到了圖中所示的位置,然后沿順時針找到一個機器節點B,將k1存儲到B這個節點中。
如果B節點宕機了,則B上的數據就會落到C節點上,如下圖所示:
這樣,只會影響C節點,對其他的節點A,D的數據不會造成影響。然而,這又會造成一個“雪崩”的情況,即C節點由于承擔了B節點的數據,所以C節點的負載會變高,C節點很容易也宕機,這樣依次下去,這樣造成整個集群都掛了。
?????? 為此,引入了“虛擬節點”的概念:即把想象在這個環上有很多“虛擬節點”,數據的存儲是沿著環的順時針方向找一個虛擬節點,每個虛擬節點都會關聯到一個真實節點,如下圖所使用:
圖中的A1、A2、B1、B2、C1、C2、D1、D2都是虛擬節點,機器A負載存儲A1、A2的數據,機器B負載存儲B1、B2的數據,機器C負載存儲C1、C2的數據。由于這些虛擬節點數量很多,均勻分布,因此不會造成“雪崩”現象。
Java實現:
[java]?view plaincopy
public?class?Shard<S>?{??? ?? ????private?TreeMap<Long,?S>?nodes;??? ????private?List<S>?shards;??? ????private?final?int?NODE_NUM?=?100;??? ?? ????public?Shard(List<S>?shards)?{?? ????????super();?? ????????this.shards?=?shards;?? ????????init();?? ????}?? ?? ????private?void?init()?{??? ????????nodes?=?new?TreeMap<Long,?S>();?? ????????for?(int?i?=?0;?i?!=?shards.size();?++i)?{??? ????????????final?S?shardInfo?=?shards.get(i);?? ?? ????????????for?(int?n?=?0;?n?<?NODE_NUM;?n++)?? ?????????????????? ????????????????nodes.put(hash("SHARD-"?+?i?+?"-NODE-"?+?n),?shardInfo);?? ?? ????????}?? ????}?? ?? ????public?S?getShardInfo(String?key)?{?? ????????SortedMap<Long,?S>?tail?=?nodes.tailMap(hash(key));??? ????????if?(tail.size()?==?0)?{?? ????????????return?nodes.get(nodes.firstKey());?? ????????}?? ????????return?tail.get(tail.firstKey());??? ????}?? ?? ????? ? ? ? ? ?? ????private?Long?hash(String?key)?{?? ?????????? ????????ByteBuffer?buf?=?ByteBuffer.wrap(key.getBytes());?? ????????int?seed?=?0x1234ABCD;?? ?????????? ????????ByteOrder?byteOrder?=?buf.order();?? ????????buf.order(ByteOrder.LITTLE_ENDIAN);?? ?? ????????long?m?=?0xc6a4a7935bd1e995L;?? ????????int?r?=?47;?? ?? ????????long?h?=?seed?^?(buf.remaining()?*?m);?? ?? ????????long?k;?? ????????while?(buf.remaining()?>=?8)?{?? ????????????k?=?buf.getLong();?? ?? ????????????k?*=?m;?? ????????????k?^=?k?>>>?r;?? ????????????k?*=?m;?? ?? ????????????h?^=?k;?? ????????????h?*=?m;?? ????????}?? ?? ????????if?(buf.remaining()?>?0)?{?? ????????????ByteBuffer?finish?=?ByteBuffer.allocate(8).order(?? ????????????????????ByteOrder.LITTLE_ENDIAN);?? ?????????????? ?????????????? ????????????finish.put(buf).rewind();?? ????????????h?^=?finish.getLong();?? ????????????h?*=?m;?? ????????}?? ?? ????????h?^=?h?>>>?r;?? ????????h?*=?m;?? ????????h?^=?h?>>>?r;?? ?? ????????buf.order(byteOrder);?? ????????return?h;?? ????}?? ?? }??
總結
以上是生活随笔為你收集整理的一致性哈希算法与Java实现的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。