jredis是redis的java客户端,通过sharde实现负载路由,一直很好奇jredis的sharde如何实现,翻开jredis源码研究了一番,所谓sharde其实就是一致性hash算法。其实,通过其源码可以看出一致性hash算法实现还是比较简单的。主要实现类是redis.clients.util.Sharded<R, S>,关键的地方添加了注释:

public class Sharded<R, S extends ShardInfo<R>> { //S类封装了redis节点的信息 ,如name、权重public static final int DEFAULT_WEIGHT = 1;//默认权重为1private TreeMap<Long, S> nodes;//存放虚拟节点private final Hashing algo;//hash算法......public Sharded(List<S> shards, Hashing algo, Pattern tagPattern) {this.algo = algo;this.tagPattern = tagPattern;initialize(shards);}private void initialize(List<S> shards) {nodes = new TreeMap<Long, S>();//基于红黑树实现排序map, 是根据key排序的 ,注意这里key放的是long类型,最多放2^32个for (int i = 0; i != shards.size(); ++i) {final S shardInfo = shards.get(i);if (shardInfo.getName() == null)for (int n = 0; n < 160 * shardInfo.getWeight(); n++) {//一个真实redis节点关联多个虚拟节点  , 通过计算虚拟节点hash值,可很好平衡把它分散到2^32个整数上nodes.put(this.algo.hash("SHARD-" + i + "-NODE-" + n), shardInfo);}elsefor (int n = 0; n < 160 * shardInfo.getWeight(); n++) {//一个真实redis节点关联多个虚拟节点  , 通过计算虚拟节点hash值,可很好平衡把它分散到2^32个整数上nodes.put(this.algo.hash(shardInfo.getName() + "*" + shardInfo.getWeight() + n), shardInfo);}resources.put(shardInfo, shardInfo.createResource());}}/*** 计算key的hash值查找实际实际节点S* @param key* @return*/public S getShardInfo(byte[] key) {SortedMap<Long, S> tail = nodes.tailMap(algo.hash(key));//取出比较key的hash大的if (tail.isEmpty()) {//取出虚拟节点为空,直接取第一个return nodes.get(nodes.firstKey());}return tail.get(tail.firstKey());//取出虚拟节点第一个}......
}

整个算法可总结为:首先生成一个长度为2^32个整数环,通过计算虚拟节点hash值映射到整数环上,间接也把实际节点也放到这个环上(因为虚拟节点会关联上一个实际节点)。然后根据需要缓存数据的key的hash值在整数环上查找,环顺时针找到距离这个key的hash值最近虚拟节点,这样就完成了根据key到实际节点之间的路由了。

一致性hash核心是思想是增加虚拟节点这一层来解决实际节点变动而不破坏整体的一致性。这种增加层的概念来解决问题对于我们来说一点都不陌生,如软件开发中分层设计,操作系统层解决了应用层和硬件的协调工作,java虚拟机解决了跨平台。

还有一个问题值得关注是一个实际节点虚拟多少个节点才是合适呢?认真看过上述代码同学会注意160这个值,这个实际上是经验值,太多会影响性能,太少又会影响不均衡。通过调整weight值,可实现实际节点权重,这个很好理解,虚拟出节点越多,落到这个节点概率越高。

参考资料

http://blog.csdn.net/sparkliang/article/details/5279393

http://my.oschina.net/u/90679/blog/188750

转载于:https://my.oschina.net/u/866190/blog/192286

从jredis中学习一致性hash算法相关推荐

  1. 良好的分布式cahce系统中,一致性hash算法需要满足什么?

    良好的分布式cahce系统中,一致性hash算法需要满足什么?你知道吗?让我们来一起学习下吧. 良好的分布式cahce系统中,一致性hash算法应该满足哪些方面 平衡性(Balance).单调性(Mo ...

  2. hash oracle 分表_一致性Hash算法在数据库分表中的实践

    最近有一个项目,其中某个功能单表数据在可预估的未来达到了亿级,初步估算在90亿左右.与同事详细讨论后,决定采用一致性Hash算法来完成数据库的自动扩容和数据迁移.整个程序细节由我同事完成,我只是将其理 ...

  3. 5分钟带你理解一致性Hash算法

    转载自 5分钟带你理解一致性Hash算法 一致性Hash算法背景 一致性哈希算法在1997年由麻省理工学院的Karger等人在解决分布式Cache中提出的,设计目标是为了解决因特网中的热点(Hot s ...

  4. 一致性hash算法虚拟节点_一致性 Hash 算法

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

  5. 一致性Hash算法(hash环)

    一致性Hash(DHT)性质 考虑到分布式系统每个节点都有可能失效,并且新的节点很可能动态的增加进来,如何保证当系统的节点数目发生变化时仍然能够对外提供良好的服务,这是值得考虑的,尤其实在设计分布式缓 ...

  6. 一致性 Hash 算法学习(分布式或均衡算法)

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

  7. 一致性hash算法学习

    一致性hash算法是一种很好的数据缓存设计方案,它满足平衡性.分散性.单调性.负载均衡. 1.平衡性(Balance):平衡性是指哈希的结果能够尽可能分布到所有的缓冲中去,这样可以使得所有的缓冲空间都 ...

  8. 分布式系统:一致性hash算法 在分布式系统中的应用

    前段时间在了解分布式,发现firefoxbug在博客中写的这篇<一致性hash在分布式系统中的应用>对这个问题说明得比较清晰易懂,本文主要是自己的理解和实践. 在后端一般会遇到这样的场景: ...

  9. 「分布式专题」分布式系统中一致性hash算法

    近年来B2C.O2O等商业概念的提出和移动端的发展,使得分布式系统流行了起来.分布式系统相对于单系统,解决了流量大.系统高可用和高容错等问题.功能强大也意味着实现起来需要更多技术的支持.例如系统访问层 ...

最新文章

  1. oracle 的替代变量和
  2. (转载)Xcode中other linker flags的作用
  3. 怎么使用7zip进行分批压缩_装机必备软件之压缩软件篇——7zip
  4. 计算机网络:TCP滑动窗口的流量控制和拥塞控制
  5. mysql多图怎么同时上传,小程序如何同时上传多张图片?
  6. Debian 里设置 IP 地址、网关、DNS
  7. C语言Main函数到底有几种,你真的懂吗?
  8. Java即时类| hashCode()方法与示例
  9. php前缀路由器的,php – 使用前缀和Zend_Controller_Router_Route
  10. c语言while跳不出来,这个while循环终止了却跳不出来为什么
  11. vue-cli起服务chrome不能打断点——每周汇总(第一周)
  12. mysql 中文 3个字节_mysql 字节问题,中文和数字
  13. 经典技术文章翻译(3):IIS7协议侦听器(Introducing IIS 7 IIS Protocol Listeners)
  14. Atitit.减少http请求数方案
  15. 如何把Web Service 说清楚
  16. 测量学-导线测量-测回法
  17. word添加脚注后正文跑到下一页
  18. HTML+CSS制作课程表
  19. speedoffice表格如何冻结窗格?
  20. 云时代,租电脑还是初创型企业最好的选择吗?

热门文章

  1. 游戏图标有哪些素材模板推荐
  2. android代码实现数据恢复,android EnMicroMsg.db安卓微信数据库获得密码的源码
  3. 05线性代数 问题笔记
  4. 希尔排序和归并排序以及快速排序
  5. 开发笔记--Vue中不同组件的传值的几种方法
  6. Web应用技术-week4
  7. python使用pymongo读写mongodb
  8. img标签和p标签是行内元素还是块级元素?以及p标签中可以放img标签吗?
  9. 如何高效快速的项目开发
  10. vuex是什么 以及他的优缺点