`
m635674608
  • 浏览: 4932189 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

一致性hash 虚拟桶

 
阅读更多

关于数据分片讨论最多的是一致性hash,然而它并不是分布式设计中的银弹百试百灵。 在数据稳定性要求比较高的场景下它的缺点是不能容忍的。
比如在Redis分布式缓存设计中,使用一致性Hash进行key分片存储,通过虚拟节点最大化降低添加或删除节点带来的影响。这里强调降低二字,即是它还是有影响的,在一般情况下我们还可以接受。
但是某些场景下要求动态扩容无影响就无法满足了。

上次(探索c#之一致性Hash详解)提到过Hash取模的分片算法,是把数据mod后直接映射到真实节点上面,这造成节点个数和数据的紧密关联、后期缺乏灵活扩展。
而一致性Hash分片算法多增加一层虚拟映射层,数据与虚拟节点映射、虚拟节点与真实节点再映射。

虚拟桶(virtual buckets)

虚拟桶是取模和一致性hash二者的折中办法。

  • 采用固定节点数量,来避免取模的不灵活性。
  • 采用可配置映射节点,来避免一致性hash的部分影响。

其运行机制如下:

key对虚拟桶层

虚拟桶层采用预设固定数量,比如楼主在项目中预设N=1024。意味之后这个分布式集群最大扩容到1024个节点,带来的好处就是mod后的值是不变的(非常重要),这保证了第一层映射挖宝去不受实际节点变化的影响。 关于最大数量,可根据实现需要预先定义好即可,比如Redis官方的糟最大65000个节点,豌豆荚的codis默认也是1024个节点。 当然如果数据量超过1024节点存储时,可以再起另外个集群应对。

虚拟桶对实际节点

举个例子,项目刚开始使用时配置节点映射:
Redis Server1对应桶的编号为0到500。
Redis Server2对应桶的编号为500到1024。

缓存数据量增长后需要增加新节点,在加之前需要重新分配节点对应虚拟桶的编号。 比如增加server3并配置对应桶的编号400到600,这时对于key映射虚拟桶层完全无影响。  实际上mod 400到600的真实数据还在另外两台节点上,请求过来后还会发生无法命中的影响。 
这就要求在增加新节点前,需要在后台把另外二台的400到600编号数据拷贝到新节点上面,完成后再添加配置到映射上面。 因为新来请求会命中到新节点,所以另外2台的400到600编号数据就无用了,需要进行删除。这种做法就能最大限度(100%)的保证动态扩容后,对缓存系统无影响。

实现

算法实现这块比较简单,数据迁移、配置等这块需要单独的系统来做。

复制代码
private Dictionary<int, RedisGroup> RedisGroups;
private const ulong Slot = 1024;

 public RedisGroup GetGroup(string key)
        {
            var longVal = Md5Hash(key);
            var index = (int) (longVal%Slot);
            return RedisGroups[index];
        }

        public ulong Md5Hash(string key)
        {
            using (var hash = System.Security.Cryptography.MD5.Create())
            {
                byte[] data = hash.ComputeHash(Encoding.UTF8.GetBytes(key));
                var a = BitConverter.ToUInt64(data, 0);
                var b = BitConverter.ToUInt64(data, 8);
                ulong hashCode = a ^ b;
                return hashCode;
            }
        }
复制代码

总结

采取虚拟桶这种预分片的算法,可以避免一致性hash扩容时引起的缓存不命中。文中使用1024个实例作为最大节点数量,实际中是完全足够用的。如果以后可能超过这个数量,可以部署另外一套1024节点的集群,最后形成一个超大规模的redis集群。

关于Redis的整套解决方案可以参考使用豌豆荚的codis。

 

http://www.cnblogs.com/mushroom/p/4542772.html

分享到:
评论

相关推荐

    一致性Hash简单实现

    简单模拟实现一致性Hash,透过虚拟节点映射至实际结点,解决一致性Hash的单调性和平衡性问题。

    解决分布式数据插入数据库~一致性hash算法

    随着虚拟节点的增加,数据量分配就比较平均了,但是并不是虚拟节点数量越多就越好,因为要考虑这些虚拟节点带来的性能开销以及算法的复杂性;

    一致性Hash算法1

    引入“虚拟节点”后,映射关系就从{对象-&gt;节点}转换到了{对象-&gt;虚拟节点}。查询物体所在 cache时的映射关系如图 7 所示。图 7 查询对象所在 cach

    一致性哈希算法及其在分布式系统中的应用

    本文将会从实际应用场景出发,介绍一致性哈希算法(Consistent Hashing)及 其在分布式系统中的应用。首先本文会描述一个在日常开发中经常会遇到的问题 场景,借此介绍一致性哈希算法以及这个算法如何解决此问题;接...

    一致性哈希与Chord1

    引入虚拟节点,可以有效地防止物理节点(机器)映射到哈希环中出现不均匀的情况。比如上图中的机器 A、B、C 都映射在环的右半边上。一般,虚拟节点会比物理节点多很多

    memcache一致性hash的php实现方法

    本文实例讲述了memcache一致性hash的php实现方法。分享给大家供大家参考。具体如下: 最近在看一些分布式方面的文章,所以就用php实现一致性hash来练练手,以前一般用的是最原始的hash取模做 分布式,当生产过程中...

    一致性Hash(Consistent Hashing)原理剖析1

    响的虚拟节点包括c31,c22,c11(顺时针查找到第个节点),这3个虚拟节点分别对应机器c3,c2,c1。即新加的台机器,同时影响到原有的3台机器。理想情况下

    PHP一致性hash分布式算法封装类定义与用法示例

    * 一致性hash分布式算法 * @param $key * @return int * 实现步骤 * 1.先将0~ 是32位最大带符号整数(0x7FFFFFFF) 想象成一个闭环 * 2.将服务器列表通过hash算法分布在 圆环之中 * 3.将key值也分布在圆环之...

    一致性哈希算法(ketama hashing)

    对已有的负载平衡的改进算法,通过一致性哈希算法,负载平衡更加的有效。

    海量数据去重的Hash与BloomFilter,bitmap1

    背景分布式一致性 hash 算法将哈希空间组织成一个虚拟的圆环,圆环的大小是,最终会得到一个 [0,] 之间的一个无符号整型,这个整数代表服务器的编号;多个服务

    dubbo负载均衡策略、使用注解.docx

    • 随机,按权重设置随机概率。 • 在一个截面上碰撞的...• 一致性 Hash,相同参数的请求总是发到同一提供者。 • 当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。

    consistent-hash:一致的哈希追踪器项目符号

    环一致散列跳转一致哈希集合一致哈希磁悬浮一致性哈希 (第3.4节)粗略设计注意事项从与Karger等人成一直线的圆圈开始N个节点可以复制R次以改善分片分布。 复制的节点称为虚拟节点。 分片复制节点的散列在cicle上成...

    基于虚拟散列安全访问路径VHSAP的云计算路由平台防御DDoS攻击方法

    揭示了SOS在节点被攻击时退出机制存在的安全漏洞,根据云计算路由策略改进了一致性散列算法 Chord,提出了适用于云计算路由平台3层架构的虚拟散列安全访问路径VHSAP(virtualization hash security access path),...

    Redis集群

    一致性hash算法:对2的32次方取模,将哈希值空间组织成虚拟的圆环 比如通过各个节点的主机编号进行hash,这样就能确定每台服务器在hash环上的位置 数据存储 将数据key使用相同的函数进行hash计算出hash值,如果一个...

    基于springBoot自研微服务框架+源代码+文档说明

    一致性hash算法,支持可配置虚拟节点数 #### 支持可插拔的注册中心 orion-register-zk-starter cp orion-register-etcd-starter cp orion-register-nacos-starter ap ...

    Doss:去分布式对象存储

    根据标准的一致性哈希算法实现了hashRing,并加入数据服务器存储空间大小不同等权重来平衡各节点的虚拟多维数据集复制因子,对象读取请求均根据对象名进行哈希运算映射到虚拟多维数据集上,再由虚拟多维数据集映射到...

    百度地图毕业设计源码-WheelPlan:重新发明轮子来训练我们的代码技能

    百度地图毕业设计源码 造轮子计划 背景与目的 游戏行业是一个需求非常复杂多样的行业,身处于这样的行业中,有它独有的乐趣。 而如何提升自我,提高自己在...一致性hash算法(虚拟节点与主动动态增删节点,异常删除节点

    2019年 Redis从入门到高可用 分布式实战教程

    9-5 一致性哈希分区.mp4 9-4 节点取余分区.mp4 9-3 数据分布概论.mp4 9-2 呼唤集群.mp4 9-16 原生命令和redis-trib.rb对比.mp4 9-14 ruby环境准备-操作.mp4 9-13 ruby环境准备-说明.mp4 9-12 原生安装-4.分配...

    oracle学习文档 笔记 全面 深刻 详细 通俗易懂 doc word格式 清晰 连接字符串

     事务控制语言(Transactional Control Language,TCL),用于维护数据的一致性,包括COMMIT(提交事务)、ROLLBACK(回滚事务)和SAVEPOINT(设置保存点)3条语句 二、 Oracle的数据类型 类型 参数 描述 字符类型...

    超级有影响力霸气的Java面试题大全文档

    Hashtable和HashMap采用的hash/rehash算法都大概一样,所以性能不会有很大的差异。 15、final, finally, finalize的区别。  final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。 ...

Global site tag (gtag.js) - Google Analytics