【题目描述】

在 Consistent Hashing I 中我们介绍了一个比较简单的一致性哈希算法,这个简单的版本有两个缺陷:

  1. 增加一台机器之后,数据全部从其中一台机器过来,这一台机器的读负载过大,对正常的服务会造成影响。
  2. 当增加到3台机器的时候,每台服务器的负载量不均衡,为1:1:2。

为了解决这个问题,引入了 micro-shards 的概念,一个更好的算法是这样:

  1. 将 360° 的区间分得更细。从 0~359 变为一个 0 ~ n-1 的区间,将这个区间首尾相接,连成一个圆。
  2. 当加入一台新的机器的时候,随机选择在圆周中撒 k 个点,代表这台机器的 k 个 micro-shards。
  3. 每个数据在圆周上也对应一个点,这个点通过一个 hash function 来计算。
  4. 一个数据该属于哪台机器负责管理,是按照该数据对应的圆周上的点在圆上顺时针碰到的第一个 micro-shard 点所属的机器来决定。

n 和 k在真实的 NoSQL 数据库中一般是 2^64 和 1000。

请实现这种引入了 micro-shard 的 consistent hashing 的方法。主要实现如下的三个函数:

  1. create(int n, int k)
  2. addMachine(int machine_id) // add a new machine, return a list of shard ids.
  3. getMachineIdByHashCode(int hashcode) // return machine id

在线评测地址: 

https://www.lintcode.com/problem/consistent-hashing-ii/?utm_source=sc-bky-zq

【样例】

样例 1:

输入:
create(, )
addMachine()
getMachineIdByHashCode()
addMachine()
getMachineIdByHashCode()
getMachineIdByHashCode()
输出:
[,,] [,,]

样例 2:

输入:
create(, )
addMachine()
getMachineIdByHashCode()
addMachine()
getMachineIdByHashCode()
getMachineIdByHashCode()
getMachineIdByHashCode()
getMachineIdByHashCode()
getMachineIdByHashCode()
getMachineIdByHashCode()
输出:
[,,,,] [,,,,]

【题解】

public class Solution {

    public int n, k;
public Set<Integer> ids = null;
public Map<Integer, List<Integer>> machines = null; // @param n a positive integer
// @param k a positive integer
// @return a Solution object
public static Solution create(int n, int k) {
// Write your code here
Solution solution = new Solution();
solution.n = n;
solution.k = k;
solution.ids = new TreeSet<Integer>();
solution.machines = new HashMap<Integer, List<Integer>>();
return solution;
} // @param machine_id an integer
// @return a list of shard ids
public List<Integer> addMachine(int machine_id) {
// Write your code here
Random ra = new Random();
List<Integer> random_nums = new ArrayList<Integer>();
for (int i = 0; i < k; ++i) {
int index = ra.nextInt(n);
while (ids.contains(index))
index = ra.nextInt(n);
ids.add(index);
random_nums.add(index);
} Collections.sort(random_nums);
machines.put(machine_id, random_nums);
return random_nums;
} // @param hashcode an integer
// @return a machine id
public int getMachineIdByHashCode(int hashcode) {
// Write your code here
int distance = n + 1;
int machine_id = 0;
for (Map.Entry<Integer, List<Integer>> entry : machines.entrySet()) {
int key = entry.getKey();
List<Integer> random_nums = entry.getValue();
for (Integer num : random_nums) {
int d = num - hashcode;
if (d < 0)
d += n;
if (d < distance) {
distance = d;
machine_id = key;
}
}
}
return machine_id;
}
}

【更多解法可参考】

https://www.jiuzhang.com/solution/longest-palindromic-substring/?utm_source=sc-bky-zq

[leetcode/lintcode 题解] 一致性哈希 II · Consistent Hashing II的更多相关文章

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

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

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

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

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

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

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

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

  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) ...

随机推荐

  1. Linux下9种优秀的代码比对工具推荐

    大家好,我是良许. 在我们编写代码的时候,我们经常需要知道两个文件之间,或者同一个文件不同版本之间有什么差异性.在 Windows 下有个很强大的工具叫作 BeyondCompare ,那在 Linu ...

  2. 解决start.spring.io无法访问的情况

    将start.spring.io替换成下列网址 http://start.jetbrains.org.cn/ 或者----> 连接手机热点 因为绝大多数无法访问都是因为网络问题

  3. 自定义Springboot全局异常类

    一.简要说明 如何实现网上文章基本是随便一搜就可以很快找到, 这里不再赘述. 二.Spring-web和Spring-webmvc 通过idea查看到两个注解位于 spring-web-5.2.2.R ...

  4. Python之浅谈函数

    目录 文件的高级应用 文件修改的两种方式 第一种 第二种 函数的定义 函数的参数 函数的返回值 文件的高级应用 r+即可读又可写,并且是在后面追加 w+清空文件的功能是w提供的 a+a有追加的功能,a ...

  5. 深入理解letter-spacing,word-spacing的对比区别

    letter-spacing lletter-spacing 属性增加或减少字符间的空白(字符间距). 该属性定义了在文本字符框之间插入多少空间.由于字符字形通常比其字符框要窄,指定长度值时,会调整字 ...

  6. HTML5 Canvas绘图基本使用方法, H5使用Canvas绘图

    Canvas 是H5的一部分,允许脚本语言动态渲染图像.Canvas 定义一个区域,可以由html属性定义该区域的宽高,javascript代码可以访问该区域,通过一整套完整的绘图功能(API),在网 ...

  7. LeetCode题解【题2】:两数相加

    原题链接:https://leetcode-cn.com/problems/add-two-numbers/ 查看请另起链接打开. 解题思路执行用时 :2 ms, 在所有 Java 提交中击败了99. ...

  8. day32 异常处理、网络编程

    目录 一.异常处理 1 什么是异常 2 为什么要处理异常 3 如何处理异常 3.1 语法错误 3.2 逻辑错误 3.3 两种处理逻辑异常的方式 3.3.1 可预知型错误 3.3.2 不可预知型错误 4 ...

  9. java 面向对象(二十三):关键字:abstract以及模板方法的设计模式

    abstract abstract: 抽象的1.可以用来修饰:类.方法2.具体的:abstract修饰类:抽象类 * > 此类不能实例化 * > 抽象类中一定有构造器,便于子类实例化时调用 ...

  10. 纯 CSS 实现滑动轮播图效果

    只使用css实现轮播图简单的操作 <!DOCTYPE html> <html lang="en"> <head> <meta charse ...