博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
聊聊jump consistent hash
阅读量:6325 次
发布时间:2019-06-22

本文共 5276 字,大约阅读时间需要 17 分钟。

本文主要简介一下jump Consistent hash。

jump consistent hash

jump consistent hash是一致性哈希的一种实现,论文见

经典的一致性哈希算法来自
jump consistent hash与之的主要区别是节点可以扩容,但是不会移除节点。

算法代码

int32_t JumpConsistentHash(uint64_t key, int32_t num_buckets) {    int64_t b = -1, j = 0;    while (j < num_buckets) {        b = j;        key = key * 2862933555777941757ULL + 1;        j = (b + 1) * (double(1LL << 31) / double((key >> 33) + 1));    }    return b;}

java实现

guava里头有个现成的实现

guava-22.0-sources.jar!/com/google/common/hash/Hashing.java

/**   * Assigns to {@code hashCode} a "bucket" in the range {@code [0, buckets)}, in a uniform manner   * that minimizes the need for remapping as {@code buckets} grows. That is, {@code   * consistentHash(h, n)} equals:   *   * 
    *
  • {@code n - 1}, with approximate probability {@code 1/n} *
  • {@code consistentHash(h, n - 1)}, otherwise (probability {@code 1 - 1/n}) *
* *

This method is suitable for the common use case of dividing work among buckets that meet the * following conditions: * *

    *
  • You want to assign the same fraction of inputs to each bucket. *
  • When you reduce the number of buckets, you can accept that the most recently added buckets * will be removed first. More concretely, if you are dividing traffic among tasks, you can * decrease the number of tasks from 15 and 10, killing off the final 5 tasks, and {@code * consistentHash} will handle it. If, however, you are dividing traffic among servers {@code * alpha}, {@code bravo}, and {@code charlie} and you occasionally need to take each of the * servers offline, {@code consistentHash} will be a poor fit: It provides no way for you to * specify which of the three buckets is disappearing. Thus, if your buckets change from {@code * [alpha, bravo, charlie]} to {@code [bravo, charlie]}, it will assign all the old {@code alpha} * traffic to {@code bravo} and all the old {@code bravo} traffic to {@code charlie}, rather than * letting {@code bravo} keep its traffic. *
* * *

See the Wikipedia article on * consistent hashing for more information. */ public static int consistentHash(HashCode hashCode, int buckets) { return consistentHash(hashCode.padToLong(), buckets); } /** * Assigns to {@code input} a "bucket" in the range {@code [0, buckets)}, in a uniform manner that * minimizes the need for remapping as {@code buckets} grows. That is, {@code consistentHash(h, * n)} equals: * *

    *
  • {@code n - 1}, with approximate probability {@code 1/n} *
  • {@code consistentHash(h, n - 1)}, otherwise (probability {@code 1 - 1/n}) *
* *

This method is suitable for the common use case of dividing work among buckets that meet the * following conditions: * *

    *
  • You want to assign the same fraction of inputs to each bucket. *
  • When you reduce the number of buckets, you can accept that the most recently added buckets * will be removed first. More concretely, if you are dividing traffic among tasks, you can * decrease the number of tasks from 15 and 10, killing off the final 5 tasks, and {@code * consistentHash} will handle it. If, however, you are dividing traffic among servers {@code * alpha}, {@code bravo}, and {@code charlie} and you occasionally need to take each of the * servers offline, {@code consistentHash} will be a poor fit: It provides no way for you to * specify which of the three buckets is disappearing. Thus, if your buckets change from {@code * [alpha, bravo, charlie]} to {@code [bravo, charlie]}, it will assign all the old {@code alpha} * traffic to {@code bravo} and all the old {@code bravo} traffic to {@code charlie}, rather than * letting {@code bravo} keep its traffic. *
* * *

See the Wikipedia article on * consistent hashing for more information. */ public static int consistentHash(long input, int buckets) { checkArgument(buckets > 0, "buckets must be positive: %s", buckets); LinearCongruentialGenerator generator = new LinearCongruentialGenerator(input); int candidate = 0; int next; // Jump from bucket to bucket until we go out of range while (true) { next = (int) ((candidate + 1) / generator.nextDouble()); if (next >= 0 && next < buckets) { candidate = next; } else { return candidate; } } }/** * Linear CongruentialGenerator to use for consistent hashing. See * http://en.wikipedia.org/wiki/Linear_congruential_generator */ private static final class LinearCongruentialGenerator { private long state; public LinearCongruentialGenerator(long seed) { this.state = seed; } public double nextDouble() { state = 2862933555777941757L * state + 1; return ((double) ((int) (state >>> 33) + 1)) / (0x1.0p31); } }

使用实例

@Test    public void testJumpHash(){        List
nodes = Arrays.asList("ins1","ins2","ins3","ins4"); List
keys = Arrays.asList("key1","key2","key3","key4"); keys.stream().forEach(e -> { int bucket = Hashing.consistentHash(Hashing.md5().hashString(e, Charsets.UTF_8), nodes.size()); String node = nodes.get(bucket); System.out.println(e + " >> " + node); }); }

doc

转载地址:http://xmvaa.baihongyu.com/

你可能感兴趣的文章
1-接口测试基础知识
查看>>
C++怎样通过嵌入汇编写一个函数
查看>>
MaoCaiJun.Database 数据库代码辅助工具
查看>>
css样式的继承性、层叠性 、优先级
查看>>
VS2010+64+OSG3.2.1之五Plugins dae编译
查看>>
关于函数的引用和值拷贝
查看>>
洛谷 P1048 采药【裸01背包】
查看>>
<%%> <%! %> <%=%> <%-- --%> jsp中jstl一些运用
查看>>
UIView设置成圆角
查看>>
Android Studio集成SVN报错:can't use subversion command line client : svn
查看>>
基本排序算法的实现
查看>>
怎样用U盘装Win7
查看>>
PHP木马的判断和查找清除
查看>>
在MyBatis中查询数据、涉及多参数的数据访问操作、插入数据时获取数据自增长的id、关联表查询操作、动态SQL、关于配置MyBatis映射没有代码提示的解决方案...
查看>>
Java程序员需要了解的几个开源协议(转)
查看>>
python(进程&线程&协程)
查看>>
Java 常用IO流操作详解
查看>>
[LeetCode] Remove Duplicates from Sorted Array II 解题报告
查看>>
首师大附中科创教育平台 我的刷题记录(3)
查看>>
面试技术总结
查看>>