`
m635674608
  • 浏览: 5027685 次
  • 性别: 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简单实现

    一致性哈希(Consistent Hashing)是一种分布式哈希表(DHT)的算法,它主要应用于分布式缓存、负载均衡等场景,旨在解决在动态扩展或收缩系统规模时,尽量减少数据迁移的问题。在这个简单的实现中,我们将探讨如何...

    一致性Hash算法的原理及实现

    为了进一步提高数据的分布均匀性以及提高系统的容错能力,一致性Hash算法还可以引入虚拟节点的概念。虚拟节点是指同一个物理节点可以映射到环上的多个位置,从而使得数据更加均匀地分布在不同的服务器上。虚拟节点的...

    C/C++ 一致性hash算法

    一致性哈希算法是一种分布式哈希(Distributed Hash Table, DHT)技术,它在处理大量数据分布到多个节点上时,能保持较好的均衡性和可扩展性。在C/C++编程中,一致性哈希通常用于构建分布式系统,如负载均衡、缓存...

    一致性哈希算法源码 Ketama一致性hash算法源码

    一致性哈希算法是一种分布式哈希(Distributed Hash Table, DHT)技术,旨在解决在分布式环境中数据分布不均匀的问题。Ketama算法是基于一致性哈希的一种优化实现,由Last.fm公司的Simon Willison提出,其目标是在...

    memcache分布式一致性hash

    一致性哈希还常使用虚拟节点策略来改善负载均衡。每个物理节点在环上可以有多个虚拟节点,这使得即使节点数量少也能实现更均匀的数据分布,降低了因节点增减导致的数据迁移范围。 总之,一致性哈希算法解决了分布式...

    一致性hashjava实现

    1. **虚拟节点**:在Ketama一致性哈希中,每个实际的物理节点被映射到多个虚拟节点,这些虚拟节点在哈希环上均匀分布。这样即使节点数量变化,也能保持较好的数据分布,降低了“热点”现象。 2. **哈希函数选择**:...

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

    为了解决这个问题,可以采用跳数法(Jump Consistent Hash)或者更高级的一致性哈希变体,如Ketama或libketama。哈希冲突则可以通过开放寻址、链地址法等方法来解决。 此外,一致性哈希算法在分布式缓存如Memcached...

    Ketama一致性Hash算法(含Java代码) 1

    总的来说,Ketama一致性哈希算法通过引入虚拟节点的概念,有效解决了传统一致性哈希中的热点问题,使得在动态调整服务器数量时,数据分布的变动更加平滑,提高了分布式系统的稳定性和效率。在Java环境中,可以通过...

    libconhash一致性hash

    一致性哈希(Consistent Hashing)是一种在分布式系统中解决数据分片问题的算法,它使得在节点加入或离开时,只需要少量的数据迁移就能保持系统的稳定性。在这个上下文中,`libconhash`是一个专门实现一致性哈希的...

    一致性哈希与Chord1

    【一致性哈希与Chord1】是一篇关于分布式哈希算法的文章,主要讨论了一致性哈希和普通哈希的区别,以及如何通过引入虚拟节点来优化一致性哈希的分布问题。 1. **普通哈希算法**: - Java中的`HashMap`类是一个典型...

    一致性hash算法(c++)

    在一致性哈希中,传统哈希函数将数据映射到固定数量的桶(例如0到2^32-1)上,但这种方法在增加或减少节点时,会导致大量键的重新映射。一致性哈希通过引入虚拟节点和特殊的哈希函数来解决这个问题。虚拟节点是实际...

    算法之一致性hash(csdn)————程序.pdf

    总结来说,一致性哈希算法通过创建一个虚拟的哈希环,实现了在服务器动态增减时只影响部分数据的策略,提高了系统的可扩展性。通过引入虚拟节点,进一步解决了数据分布不均衡的问题,提升了系统的整体效率和稳定性。...

    一致性Hash算法1

    一致性哈希算法通过引入虚拟节点和环形哈希空间的概念,有效地解决了这个问题。 1. **虚拟节点**:在一致性哈希中,每个实际的物理节点可以被映射为多个虚拟节点。虚拟节点是物理节点在哈希空间中的多个副本,这样...

    一致性hash算法1

    一致性哈希算法通过引入虚拟节点和环形哈希空间的概念,有效地解决了这个问题。 1. **环形哈希空间** 一致性哈希不再将哈希值映射到一个线性的范围,而是将其映射到一个环形空间,这个空间是闭合的,从0开始,到...

    搞懂分布式技术11:分布式session解决方案与一致性hash.docx

    ### 分布式Session解决方案与一致性Hash详解 #### 一、问题背景及提出 在现代互联网应用中,随着用户量的增长和服务需求的增加,单一服务器往往难以满足高性能、高可用性的需求,因此分布式系统逐渐成为主流架构之...

    ConsistentHash(Ketama)

    一致性哈希(Consistent Hashing)是一种分布式哈希(Distributed Hash Table,DHT)算法,主要用于解决在分布式系统中的数据存储和检索问题。在云计算、缓存系统(如Redis、Memcached)以及负载均衡等领域广泛应用...

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

    一致性哈希引入了一个虚拟的环形空间,这个环的大小是2^32,从0开始逆时针分布。每个对象和服务器都会被哈希到这个环上,形成一个点。对象会映射到距离其哈希值最近的服务器节点,这样即使有节点增减,只需要影响到...

    对一致性Hash算法,Java代码实现的深入研究1

    在传统的哈希算法中,增加或删除一个服务器可能导致大量键的重新映射,而一致性Hash算法通过构建一个虚拟的哈希环来解决这个问题。 算法步骤如下: 1. 首先,创建一个大小为2^32的虚拟圆环,这是因为在计算机中,32...

Global site tag (gtag.js) - Google Analytics