`

memcached分布测试报告(一致性哈希情况下的散列函数选择)

    博客分类:
  • java
阅读更多

一、背景资料

    memcached本身是集中式的缓存系统,要搞多节点分布,只能通过客户端实现。memcached的分布算法一般有两种选择:
1、根 据hash(key)的结果,模连接数的余数决定存储到哪个节点,也就是hash(key)% sessions.size(),这个算法简单快速,表现良好。然而这个算法有个缺点,就是在memcached节点增加或者删除的时候,原有的缓存数据 将大规模失效,命中率大受影响,如果节点数多,缓存数据多,重建缓存的代价太高,因此有了第二个算法。
2、Consistent Hashing,一致性哈希算法,他的查找节点过程如下:
    首先求出memcached服务器(节点)的哈希值,并将其配置到0~232的圆(continuum)上。然后用同样的方法求出存储数据的键的哈希值,并映射到圆上。然后从数据映射到的位置开始顺时针查找,将数据保存到找到的第一个服务器上。如果超过232仍然找不到服务器,就会保存到第一台memcached服务器上。



    一致性哈希算法来源于P2P网络的路由算法,更多的信息可以读这里

 二、测试报告

   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源码中的哈希函数。

 CRC32_HASH  KETAMA_HASH  FNV1_32_HASH  NATIVE_HASH  MYSQL_HASH
命中率
 78.5%  83.3%  78.2%  99.89%  86.9%
 节点1  319  366  546  3596  271
 节点2  399  350  191  1  233
 节点3  413  362  491  0  665
 节点4  393  364  214  1  42
 节点5  464  403  427  1  421
 节点6  472  306  299  0  285
 节点7  283  347  123  0  635
 节点8  382  387  257  2  408
 节点9  238  341  297  0  55
 节点10  239  375  756  0  586
 范围  200~500   300~400
 150~750  0~3600  50~650



结果分析:

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

 

   测试所用文件见附件

分享到:
评论
4 楼 Stero 2010-01-20  
badqiu 写道
String.hashCode()在应用一致性hash时还有分布不均匀的问题,所以是使用FNV1是比较好的选择
而计算MD5再hash则效率太低!


Memcached的客户端一般运行在前端服务器上,例如Web服务器,一般不存储状态数据,因此可以简单通过简单的负载均衡线性的增加计算能力。而服务器端数据量扩大时,在资源占用和计算效率上都会受影响。因此我认为应在调用者采取尽可能好的算法来提高服务器端的利用率。
3 楼 badqiu 2009-11-10  
String.hashCode()在应用一致性hash时还有分布不均匀的问题,所以是使用FNV1是比较好的选择
而计算MD5再hash则效率太低!
2 楼 ideafrog 2009-04-24  
我只对文中的图比较感兴趣。是用什么画的?主要是那个渐变色的处理
1 楼 hqman 2009-04-24  
最近我也在学 tokyo系列产品,也碰到java 客户端的问题

相关推荐

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

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

    带虚拟节点的一致性哈希

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

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

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

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

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

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

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

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

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

    一致性哈希算法(ketama hashing)

    一致性哈希算法(Consistent Hashing)是一种在分布式系统中实现负载均衡的算法,尤其在分布式缓存如Memcached和Redis等场景下广泛使用。它解决了传统哈希算法在节点增减时导致的大量数据迁移问题,提高了系统的可用...

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

    一致性哈希算法(Consistent Hashing)是一种常用于分布式系统中的数据分片策略,它有效地解决了数据在多台服务器间均匀分布的问题,同时减少了因节点加入或离开时的数据迁移成本。 首先,一致性哈希的基本原理是将...

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

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

    一致性hashjava实现

    2. **哈希函数选择**:一致性哈希算法通常需要一个高效的哈希函数,将键(key)映射到一个大的整数空间,然后这个整数被视为一个点,分布在哈希环上。在这个Java实现中,可能采用了如MD5或SHA-1这样的强哈希函数,...

    C# memcached客户端源码 测试例子

    测试例子通常会覆盖这些基本操作,以及更复杂的功能,比如批量操作、一致性哈希策略、错误处理等。这些测试用例可以帮助开发者理解如何在实际项目中正确使用客户端库,确保代码的稳定性和性能。 在`memcacheddotnet...

    一致性Hash简单实现

    - **分布式缓存**:如Memcached、Redis集群中,一致性哈希用于确定数据应该存储在哪个节点上。 - **负载均衡**:在负载均衡器中,一致性哈希可以用来分配请求到不同的服务器,避免在动态调整服务器数量时大量请求...

    Memcached集群搭建

    在Memcached中,没有内置的集群管理机制,但可以通过一致性哈希算法实现数据分布。一致性哈希允许我们根据键的哈希值将数据分配到不同的节点上,即使有节点加入或离开,也只需要重新映射少量数据。 #### 1. 使用...

    memcached:memcached +一致哈希

    1. **哈希函数选择**:首先,选择一个哈希函数,将数据和服务器地址映射到一个大的整数空间上。 2. **虚拟节点**:每个实际服务器在哈希环上表现为多个虚拟节点,这样可以更均匀地分配数据,减少热点现象。 3. **...

    一致性哈希算法以及其PHP实现详细解析

    在实际应用中,一致性哈希算法不仅可以用于负载均衡,还可以应用于分布式数据库的分片、分布式缓存系统如Memcached或Redis的集群部署,以及P2P网络中的数据分布等场景。通过精心设计和优化,一致性哈希能够有效地...

    memcached-笔记资料

    1. "一致性哈希对缓存命中率的影响实验报告.doc":这份文档可能详细介绍了如何使用一致性哈希算法来分配和检索数据在Memcached中的存储,以及该算法如何影响缓存的命中率。一致性哈希是解决分布式缓存中数据分布不均...

    Memcached windows 下安装与测试

    **Memcached Windows 下安装与测试详解** Memcached是一款高性能、分布式的内存对象缓存系统,广泛应用于Web应用中,用于减轻数据库的负载。它通过在内存中存储数据和对象来加速动态Web应用的运行速度。在Windows...

    memcached:在Node.js之上构建的功能齐全的Memcached客户端。 考虑到扩展性,因此它将支持Memcached集群和一致的哈希

    一致性哈希是一种提供哈希表功能的方案,该方式使得添加或删除服务器节点不会显着更改密钥到服务器节点的映射。 用于一致性哈希的算法与libketama相同。 例如,有多种处理错误的方法,例如,当服务器不可用时,您...

Global site tag (gtag.js) - Google Analytics