一个简单的consistent hashing的样例,非常easy理解。

首先有一个设备类,定义了机器名和ip:

  1. public class Cache
  2. {
  3. public String name;
  4. public String ipAddress;
  5. }

然后是基本的实现:

  1. public class Shard<T> {
  2. //hash 算法并非保证绝对的平衡,假设 cache 较少的话,对象并不能被均匀的映射到 cache 上,
  3. //所以添加虚拟节点
  4. private TreeMap<Long, T> nodes;
  5. private List<T> shards; //节点碎片
  6. private final int NODE_NUM = 10; // 每一个机器节点关联的虚拟节点个数
  7.  
  8. public Shard(List<T> shards) {
  9. this.shards = shards;
  10. init();
  11. }
  12.  
  13. private void init() {
  14. nodes = new TreeMap<Long, T>();
  15. for (int i = 0; i < shards.size(); i++)
  16. { // 遍历真实节点
  17. final T shardInfo = shards.get(i);
  18.  
  19. for (int n = 0; n < NODE_NUM; n++)
  20. {
  21. // 真实节点关联虚拟节点,真实节点是VALUE;
  22. nodes.put((long) Hash("SHARD-" + i + "-NODE-" + n), shardInfo);
  23. }
  24. System.out.println(shardInfo);
  25. }
  26. }
  27.  
  28. public T getShardInfo(String key) {
  29. SortedMap<Long, T> tail = nodes.tailMap((long) Hash(key));
  30. if (tail.size() == 0) {
  31. return nodes.get(nodes.firstKey());
  32. }
  33. //找到近期的虚拟节点
  34. return tail.get(tail.firstKey());
  35. }
  36.  
  37. /**
  38. * 改进的32位FNV算法,高离散
  39. *
  40. * @param string
  41. * 字符串
  42. * @return int值
  43. */
  44. public static int Hash(String str)
  45. {
  46. final int p = 16777619;
  47. int hash = (int) 2166136261L;
  48. for (byte b : str.getBytes())
  49. hash = (hash ^ b) * p;
  50. hash += hash << 13;
  51. hash ^= hash >> 7;
  52. hash += hash << 3;
  53. hash ^= hash >> 17;
  54. hash += hash << 5;
  55. return hash;
  56. }
  57.  
  58. }

到这里就完了,是不是非常easy,以下来測试下:

  1. public class Test
  2. {
  3.  
  4. /**
  5. * @param args
  6. */
  7. public static void main(String[] args)
  8. {
  9. List<Cache> myCaches=new ArrayList<Cache>();
  10. Cache cache1=new Cache();
  11. cache1.name="COMPUTER1";
  12. Cache cache2=new Cache();
  13. cache2.name="COMPUTER2";
  14. myCaches.add(cache1);
  15. myCaches.add(cache2);
  16.  
  17. Shard<Cache> myShard=new Shard<Cache>(myCaches);
  18.  
  19. Cache currentCache=myShard.getShardInfo("info1");
  20. System.out.println(currentCache.name);
  21.  
  22. // for(int i=0;i<20;i++)
  23. // {
  24. // String object=getRandomString(20);//产生20位长度的随机字符串
  25. // Cache currentCache=myShard.getShardInfo(object);
  26. // System.out.println(currentCache.name);
  27. // }
  28.  
  29. }
  30.  
  31. public static String getRandomString(int length) { //length表示生成字符串的长度
  32. String base = "abcdefghijklmnopqrstuvwxyz0123456789";
  33. Random random = new Random();
  34. StringBuffer sb = new StringBuffer();
  35. for (int i = 0; i < length; i++) {
  36. int number = random.nextInt(base.length());
  37. sb.append(base.charAt(number));
  38. }
  39. return sb.toString();
  40. }
  41.  
  42. }

我们有两台设备,computer1和computer2,第一次初始化要构建一个2的32次方的环,并往上面放设备。这个环由改进的FNV算法实现。位置也由hash算法确定。

但我们仅仅有两台设备,非常明显在环上会分布不均匀(这个就不解释了,网上非常多资料)。于是我们每台设备添加10个虚拟设备。

最后分布例如以下:

  1. -1561290727=Hash.Cache@10f11b8,
  2. -1083588870=Hash.Cache@10f11b8,
  3. -697149481=Hash.Cache@10f11b8,
  4. -253517545=Hash.Cache@10f11b8,
  5. 397383558=Hash.Cache@10f11b8,
  6. 1078505027=Hash.Cache@10f11b8,
  7. 1810977445=Hash.Cache@10f11b8,
  8. 1844081498=Hash.Cache@10f11b8,
  9. 2004894833=Hash.Cache@10f11b8,
  10. 2051863688=Hash.Cache@10f11b8

-2147483648到2147483647之间是不是比較均匀,这是java的,假设是c#的就是0~2的32次方。我们hash计算出KEY值为2049553054,然后顺时针找到近期的位置,即为

  1. 2051863688=Hash.Cache@10f11b8

结果我们定位到了COMPUTER1

最好我们要看看平衡性怎样:取消上面凝视的代码,循环20次,得到结果例如以下:

COMPUTER1

COMPUTER2

COMPUTER1

COMPUTER2

COMPUTER1

COMPUTER2

COMPUTER1

COMPUTER1

COMPUTER1

COMPUTER2

COMPUTER2

COMPUTER2

COMPUTER1

COMPUTER2

COMPUTER1

COMPUTER1

COMPUTER1

COMPUTER2

COMPUTER1

COMPUTER2

大家能够自己取试试,

FNV哈希算法是一种高离散性的哈希算法,特别适用于哈希很相似的字符串,比如:URL,IP,主机名,文件名称等。

下面服务使用了FNV:

1、calc

2、DNS

3、mdbm key/value查询函数

4、数据库索引hash

5、主流web查询/索引引擎

6、高性能email服务

7、基于消息ID查询函数

8、auti-spam反垃圾邮件过滤器

9、NFS实现(比方freebsd 4.3, linux NFS v4)

10、Cohesia MASS project

11、Ada 95的spellchecker

12、开源x86汇编器:flatassembler   user-defined symbol hashtree

13、PowerBASIC

14、PS2、XBOX上的文本资源

15、非加密图形文件指纹

16、FRET

17、Symbian DASM

18、VC++ 2005的hash_map实现

19、memcache中的libketama

20、 PHP 5.x

21、twitter中用于改进cache碎片

22、BSD IDE project

23、deliantra game server

24、 Leprechaun

25、IPv6流标签

一致性哈希算法(consistent hashing)样例+測试。的更多相关文章

  1. 一致性哈希算法(consistent hashing)(转)

    原文链接:每天进步一点点——五分钟理解一致性哈希算法(consistent hashing)  一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT)实现算法,设计目标是为了解决因特网 ...

  2. 一致性哈希算法(Consistent Hashing Algorithm)

    一致性哈希算法(Consistent Hashing Algorithm) 浅谈一致性Hash原理及应用   在讲一致性Hash之前我们先来讨论一个问题. 问题:现在有亿级用户,每日产生千万级订单,如 ...

  3. 转 白话解析:一致性哈希算法 consistent hashing

    摘要: 本文首先以一个经典的分布式缓存的应用场景为铺垫,在了解了这个应用场景之后,生动而又不失风趣地介绍了一致性哈希算法,同时也明确给出了一致性哈希算法的优点.存在的问题及其解决办法. 声明与致谢: ...

  4. (转)每天进步一点点——五分钟理解一致性哈希算法(consistent hashing)

    背景:在redis集群中,有关于一致性哈希的使用. 一致性哈希:桶大小0~(2^32)-1 哈希指标:平衡性.单调性.分散性.负载性 为了提高平衡性,引入“虚拟节点” 每天进步一点点——五分钟理解一致 ...

  5. 白话解析:一致性哈希算法 consistent hashing【转】

    学习一致性哈希算法原理的时候看到博主朱双印的一片文章,看完就懂,大佬! 白话解析:一致性哈希算法 consistent hashing

  6. _00013 一致性哈希算法 Consistent Hashing 新的讨论,并出现相应的解决

    笔者博文:妳那伊抹微笑 博客地址:http://blog.csdn.net/u012185296 个性签名:世界上最遥远的距离不是天涯,也不是海角,而是我站在妳的面前.妳却感觉不到我的存在 技术方向: ...

  7. 一致性哈希算法(consistent hashing)PHP实现

    一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT)实现算法,设计目标是为了解决因特网中的热点(Hot spot)问题,初衷和CARP十分类似.一致性哈希修正了CARP使用的简单哈希 ...

  8. 五分钟理解一致性哈希算法(consistent hashing)

    转载请说明出处:http://blog.csdn.net/cywosp/article/details/23397179 一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT)实现算法 ...

  9. 每天进步一点点——五分钟理解一致性哈希算法(consistent hashing)

    转载请说明出处:http://blog.csdn.net/cywosp/article/details/23397179     一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT) ...

  10. 一致性哈希算法(consistent hashing)【转】

    一致性哈希算法 来自:http://blog.csdn.net/cywosp/article/details/23397179       一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希 ...

随机推荐

  1. HDU 4720Naive and Silly Muggles热身赛2 1005题(分锐角钝角三角形讨论)

    Naive and Silly Muggles Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/ ...

  2. android 逆向project smail 语法学习

    众所周知,android 是开源的.如今市场上反编译别人的劳动果实的人也不少.所以我们也是有必要学习下smail语言,(就是androidproject反编译后出的语法语音),看看改怎么给我们的代码 ...

  3. 安装DBMS_SHARED_POOL包

    在安装10g gc的时候,会遇到The DBMS_SHARED_POOL package is not executed on the Existing Database这样的一个错误,意思是提示你D ...

  4. 用c#开发微信(10) JSSDK 基本用法 分享接口“发送到朋友”

    微信JS-SDK是微信公众平台面向网页开发者提供的基于微信内的网页开发工具包.通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照.选图.语音.位置等手机系统的能力,同时可以直接使用微信分享. ...

  5. 读取中兴3G告警log告警文件到集合

    1.文件格式 ALARM_ID=102305_404205 EVENT_TIME=-- :: NOTIFICATION_TYPE= MANAGED_OBJECT_INSTANCE=NodeId=,Bs ...

  6. 查询mysql哪些表正在被锁状态

    1.查进程,主要是查找被锁表的那个进程的ID SHOW PROCESSLIST; 2.kill掉锁表的进程ID KILL   10866;//后面的数字即时进程的ID

  7. 第12届北师大校赛热身赛第二场 B起床的烦恼

    题目链接:http://www.bnuoj.com/bnuoj/contest_show.php? cid=3570#problem/43572 题目大意: Nono从一開始数数,他每数一个数时会计算 ...

  8. 基于TCP/IP协议的C++网络编程(API函数版)

    源代码:http://download.csdn.net/detail/nuptboyzhb/4169959 基于TCP/IP协议的网络编程 定义变量——获得WINSOCK版本——加载WINSOCK库 ...

  9. 九度OnlineJudge之1014:排名

    题目描述:     今天的上机考试虽然有实时的Ranklist,但上面的排名只是根据完成的题数排序,没有考虑每题的分值,所以并不是最后的排名.给定录取分数线,请你写程序找出最后通过分数线的考生,并将他 ...

  10. webdynpro 组件重用 传值问题

    组件zwd1,需要调用组件zwd2的时候,zwd2组件控制器中需要定义一个方法,定义所要传输的参数,并且该方法需要定义为interface方法. 组件zwd1可以通过代码向导调用组件zwd2,的该方法 ...