`
kangkang203
  • 浏览: 13901 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

从 Memcached 分布式应用看一致性哈希散列函数的选择

阅读更多

Hash设计的原则是尽量使元素均匀分布,从而最大处利用内存。

一致性哈希算法来源于 P2P 网络的路由算法,目前主流的 P2P 软件就是利用我们所熟知的 DHT (Distributed Hash Table,分布式哈希表) 来定位整个分布式网络的信息,另外此算法在目前火热的云计算领域也将占有极其重要的位置。可以说散列函数在当代计算机和网络系统中所起的重要作用大家应该 都有目共睹了,特别是在目前这个分布式应用爆炸的时代,这个方面的知识只会越来越引起人们的重视,本文重在从 Memcached 这个流行的分布式应用的场景中来对一致性哈希散列的几个主流算法做一些比较和分析。

 

[背景信息]

 

对于 Memcached 来说,本身是集中式的缓存系统,要搞多节点分布,只能通过客户端实现。Memcached 的分布算法一般有两种选择:

 

1、根据 hash(key) 的结果,模连接数的余数决定存储到哪个节点,也就是 hash(key) % sessions.size(),这个算法简单快速,表现良好。然而这个算法有个缺点,就是在memcached节点增加或者删除的时候,原有的缓存数据 将大规模失效,命中率大受影响,如果节点数多,缓存数据多,重建缓存的代价太高,因此有了第二个算法。

 

2、Consistent Hashing,一致性哈希算法,他的查找节点过程如下:首先求出 Memcached 服务器(节点)的哈希值,并将其配置到 0~232 的圆(continuum)上。然后用同样的方法求出存储数据的键的哈希值,并映射到圆上。然后从数据映射到的位置开始顺时针查找,将数据保存到找到的第 一个服务器上。如果超过 232 仍然找不到服务器,就会保存到第一台 Memcached 服务器上。

 

下图就是一致性哈希算法算法的示意图,比如我们现在有 4 台服务器,我们把他们的 hash 值当作 node 节点按照某种平均分布算法被分配到这个环上面,我们按顺时针方向 把 Key 的哈希值与 node 节点的 hash 值比较,总是把 Key 节点保存到找到的第一个 hash 值大于 Key 节点的那个 node 节点服务器上:

 

现在假如我们有一台新的服务器加入进来(减少一个服务器同理),那么按照此前的算法,受影响的 Key 值只有下图黄色那部分的数据,从某种意义上甚至这样可以说,加入的服务器 node 节点越多,受影响的数据就越少 ,从而使这个动态的分布式系统中的数据稳定性达到最大,而这就是一致性哈希算法的精髓所在了:

 

Spymemcached 和 Xmemcached 都实现了一致性算法,这里要测试下在使用一致性哈希的情况下,增加节点,看不同散列函数下命中率和数据分布的变化情况,这个测试结果对于 Spymemcached 和 Xmemcached 是一样的,测试场景:

 

从一篇英文小说(《黄金罗盘》前三章)进行单词统计,并将最后的统计结果存储到 Memcached,以单词为 Key,以次数为 Value。单词个数为 3061,Memcached 原来节点数为10,运行在局域网内同一台服务器上的不同端口,在存储统计结果后,增加两个 Memcached 节点(也就是从 10个节点增加到12个节点),统计此时的缓存命中率并查看数据的分布情况。

 

结果如下表格,命中率一行表示增加节点后的命中率情况(增加前为100%),后续的行表示各个节点存储的单词数,CRC32_HASH 表示采用 CRC32 散列函数,KETAMA_HASH 是基于 md5 的散列函数也是默认情况下一致性哈希的推荐算法,FNV1_32_HASH 就是 FNV 32 位散列函数,NATIVE_HASH 就是 java.lang.String.hashCode() 方法返回的 long 取 32 位的结果,MYSQL_HASH 是 Xmemcached 添加的传说来自于 mysql 源码中的哈希函数。

 

 

[结果分析]

 

1、命中率最高看起来是NATIVE_HASH,然而NATIVE_HASH情况下数据集中存储在第一个节点,显然没有实际使用价值。为什么会集中 存储在第一个节点呢?这是由于在查找存储的节点的过程中,会比较hash(key)和hash(节点IP地址),而在采用了NATIVE_HASH的情况 下,所有连接的hash值会呈现一个递增状况(因为String.hashCode是乘法散列函数),如:

192.168.0.100:12000 736402923
192.168.0.100:12001 736402924
192.168.0.100:12002 736402925
192.168.0.100:12003 736402926

如果这些值很大的会,那么单词的hashCode()会通常小于这些值的第一个,那么查找就经常只找到第一个节点并存储数据,当然,这里有测试的局 限性,因为memcached都跑在一个台机器上只是端口不同造成了hash(节点IP地址)的连续递增,将分布不均匀的问题放大了。

 

2、从结果上看,KETAMA_HASH 维持了一个最佳平衡,在增加两个节点后还能访问到83.3%的单词,并且数据分布在各个节点上的数目也相对平均,难怪作为默认散列算法。

 

3、最后,单纯比较下散列函数的计算效率:

CRC32_HASH:3266
KETAMA_HASH:7500
FNV1_32_HASH:375
NATIVE_HASH:187
MYSQL_HASH:500

简单看以上算法的效率排序如下:

NATIVE_HASH > FNV1_32_HASH > MYSQL_HASH > CRC32_HASH > KETAMA_HASH

 

综上所述,大家可以比较清楚的看出哪种 hash 算法适合你所在的场景,对于分布式应用,本人比较推荐在 CRC32_HASH、FNV1_32_HASH、KETAMA_HASH 这三种算法中选择,至于你是注重算法效率还是命中率,这就需要根据具体的场景来选择了。另外,对于 PHP 客户端可以通过 Memcache 扩展如下配置(在 php.ini 中)来选择:

memcache.hash_function={crc32(default),fnv}

memcache.hash_strategy={consistent(default),standard}

然后通过 Memcache::addServer 函数即可添加服务器节点了,相当方便哦~

分享到:
评论

相关推荐

    memcached分布式缓存数据库部署.doc

    memcached的分布式特性使其能够在多台服务器上分布缓存,通过一致性哈希算法实现数据的均匀分布,当集群中的某个节点出现问题时,可以通过其他节点继续提供服务,保证系统的高可用性。此外,memcached支持多种数据...

    memcached分布式工具

    1. **负载均衡**:确保数据均匀分布到各个节点,避免某些节点过载,可以使用一致性哈希算法来分配键值对。 2. **故障恢复**:当某个节点出现故障时,需要有机制自动将数据重新分配到其他健康节点,保证服务连续性。...

    Memcached 分布式缓存实现原理简介

    总结来说,Memcached的分布式缓存实现主要依赖于客户端的哈希算法,包括余数计算分散法和一致性哈希。这些策略确保了数据在多台服务器间的有效分布,减少了数据库的压力,提高了系统的响应速度和可扩展性。在实际...

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

    在分布式缓存系统如Memcached或Redis中,一致性哈希算法被广泛使用。当用户请求数据时,根据数据的键进行哈希运算,然后在哈希环上找到最近的服务器节点来存储或检索数据。这种方式确保了数据与服务器之间的绑定关系...

    .net memcached 分布式缓存应用类库

    1. **分布式**: Memcached将数据分散存储在多台服务器上,通过一致性哈希算法实现数据的分布式存储,确保数据的正确分布和负载均衡。 2. **内存存储**: 由于Memcached主要利用内存进行数据存储,因此其读取速度极快...

    Memcached分布式缓存入门

    2. **分布式策略**:通过一致性哈希或其他算法实现数据在多台Memcached服务器间的均匀分布。 3. **性能监控**:定期检查Memcached的命中率、内存使用情况等指标,及时调整策略。 **六、Memcached与数据库的协同...

    20120102 net下memcached 分布式缓存系统应用

    7. **故障转移与分布式一致性**:如何处理节点故障,以及Memcached的分布式一致性哈希算法。 8. **性能优化**:缓存命中率提升技巧,避免缓存击穿、雪崩等问题的方法。 9. **源码分析**:如果包含源码,可能涉及具体...

    基于C# 实现的一致性哈希算法

    C#实现一致性哈希的关键在于选择合适的哈希函数和节点分布策略。KetamaHash-code这个名字可能指的是使用了Ketama一致性哈希的实现。Ketama是Memcached的一个扩展,它引入了虚拟节点的概念,通过为每个实际节点生成多...

    Memcached分布式缓存简介

    客户端使用特定的分布式算法(例如一致性哈希)来决定数据应存储在哪个服务器上。这种设计允许Memcached在多台服务器上分散大量数据,减轻单一服务器的压力,并且能实现缓存的扩展性。 Memcached的设计特征包括: 1...

    _net memcached 分布式缓存应用类库

    4. **分布式缓存原理**:理解分布式缓存的工作方式,如键值存储、数据分片、一致性哈希、过期策略等。 5. **SQL数据库交互**:掌握如何将Memcached与SQL数据库结合使用,优化读写操作,实现读写分离和负载均衡。 6. ...

    Memcached分布式缓存

    - **支持ConsistentHashing的函数库**:如Ketama等库提供了实现一致性哈希功能的支持。 #### 五、Memcached的应用和兼容程序 **5.1 mixi案例研究** - **服务器配置和数量**:mixi使用大量的memcached服务器集群来...

    带虚拟节点的一致性哈希

    一致性哈希(Consistent Hashing)是一种分布式哈希算法,主要应用于分布式缓存、负载均衡等领域,例如Memcached和Redis等系统。它解决了在分布式环境中数据分片与节点动态增减时,尽量减少数据迁移的问题。带虚拟...

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

    此外,一致性哈希算法在分布式缓存如Memcached、Redis中也得到了广泛应用。它不仅简化了数据分布的逻辑,还允许动态扩展和收缩集群规模,无需大规模的数据迁移。 在文件名为“distribute-mysql”的压缩包中,可能...

    Memcached 分布式缓存实现原理 – 码农网1

    客户端根据一致性哈希策略选择合适的服务器进行操作。如果某个服务器故障,客户端会自动将请求路由到其他服务器,保证服务的可用性。 然而,这种分布式策略也有一些局限性。例如,它无法实现数据的跨服务器复制,...

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

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

    memcached 分布式内存

    - **一致性哈希**: 为解决服务器添加或删除时导致的数据重新分布问题,可以采用一致性哈希算法。 - **分片策略**: 通过数据分片,将大型数据集分散到多个缓存实例,平衡各个节点的负载。 综上所述,Memcached 是...

    一致性哈希算法应用及优化(最简洁明了的教程)

    一致性哈希算法应用及优化是IT领域中分布式系统设计的核心技术之一,特别是在处理大规模数据分布与缓存系统中,其重要性不言而喻。本文将深入探讨一致性哈希算法的基本概念、工作原理以及在实际场景中的应用和优化...

    24一致性哈希:如何高效地均衡负载?1

    一致性哈希算法是一种在分布式系统中解决负载均衡和数据分布问题的有效方法。在传统的哈希算法中,当添加或移除服务器节点时,大部分数据需要重新映射,导致大规模的数据迁移。而一致性哈希算法通过特定的设计,能够...

    一致性哈希算法(ketama hashing)

    一致性哈希算法(Consistent Hashing)是一种在分布式系统中实现负载均衡的算法...在理解和应用一致性哈希时,需要考虑如何合理设置虚拟节点数量、选择合适的哈希函数以及优化数据分布策略,以适应不同应用场景的需求。

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

    一致性哈希算法(Consistent Hashing)是一种在分布式系统中平衡数据分布的策略,尤其适用于缓存服务如Memcached或Redis。它的核心思想是通过哈希函数将对象映射到一个固定大小的环形空间中,然后将服务器也映射到这个...

Global site tag (gtag.js) - Google Analytics