应用场景

这里我先描述一个极其简单的业务场景:用4台Cache服务器缓存所有Object。

那么我将如何把一个Object映射至对应的Cache服务器呢?最简单的方法设置缓存规则:object.hashCode() % 4。

Cache 0:

object.hashCode() % 4 == 0

Cache 1:

object.hashCode() % 4 == 1

Cache 2:

object.hashCode() % 4 == 2

Cache 3:

object.hashCode() % 4 == 2

看起来一切正常,考虑下面两种情况:

一:由于Cache3硬件损坏,所有Cache3上的缓存都失效了,需要把Cache3移除。

二:由于负载已经无法承担业务增涨,决定添加一台Cache服务器。

一致性哈希算法简介

一致性哈希算法是在哈希算法基础上,提出的在动态变化的Cache环境中,哈希算法应该满足的4个适应条件。

平衡性(Balance)

平衡性是指Hash的结果能够尽可能分布均匀,充分利用所有缓存空间。

单调性(Monotonicity)

单调性是指如果已经有一些内容通过哈希分派到了相应的缓冲中,又有新的缓冲加入到系统中。哈希的结果应能够保证原有已分配的内容可以被映射到新的缓冲中去,而不会被映射到旧的缓冲集合中的其他缓冲区。

分散性(Spread)

分散性定义了分布式环境中,不同终端通过Hash过程将内容映射至缓存上时,因可见缓存不同,Hash结果不一致,相同的内容被映射至不同的缓冲区。

负载(Load)

负载是对分散性要求的另一个纬度。既然不同的终端可以将相同的内容映射到不同的缓冲区中,那么对于一个特定的缓冲区而言,也可能被不同的用户映射为不同的内容。

使用一致性哈希算法解决上述问题

一致性哈希算法采用一种新的方式来解决问题,不再仅仅依赖object.hashCode()本身,而且将Cache的配置也进行哈希运算。具体步骤如下:

  1. 首先求出每个Cache的哈希值,并将其配置到一个0~2^32的圆环区间上。
  2. 使用同样的方法求出需要存储对象的哈希值,也将其配置到这个圆环上。
  3. 从数据映射到的位置开始顺时针查找,将数据保存到找到的第一个Cache节点上。如果超过2^32仍然找不到Cache节点,就会保存到第一个Cache节点上。

新增Cache服务器

  假设在这个环形哈希空间中,Cache5被映射在Cache3和Cache4之间,那么受影响的将仅是沿Cache5逆时针遍历直到下一个Cache(Cache3)之间的对象(它们本来映射到Cache4上)。

移除Cache服务器

  假设在这个环形哈希空间中,Cache3被移除,那么受影响的将仅是沿Cache3逆时针遍历直到下一个Cache(Cache2)之间的对象(它们本来映射到Cache3上)。

虚拟Cache服务器

考虑到哈希算法并不是保证绝对的平衡,尤其Cache较少的话,对象并不能被均匀的映射到 Cache上。为了解决这种情况,Consistent Hashing引入了“虚拟节点”的概念: “虚拟节点”是实际节点在环形空间的复制品,一个实际节点对应了若干个“虚拟节点”,这个对应个数也成为“复制个数”,“虚拟节点”在哈希空间中以哈希值排列。

仍以4台Cache服务器为例,在下图中看到,引入虚拟节点,并设置“复制个数”为2后,共有8个“虚拟节点”分部在环形区域上,缓解了映射不均的情况。

  引入了“虚拟节点”后,映射关系就从【对象--->Cache服务器】转换成了【对象--->虚拟节点---> Cache服务器】。查询对象所在Cache服务器的映射关系如下图所示。

总结

在我们的web开发应用中的分布式缓存系统里哈希算法承担着系统架构上的关键点。

使用分布更合理的算法可以使得多个服务节点间的负载相对均衡,可以最大程度的避免资源的浪费以及服务器过载。

使用一致性哈希算法,可以最大程度的降低服务硬件环境变化带来的数据迁移代价和风险。

使用更合理的配置策略和算法可以使分布式缓存系统更加高效稳定的为我们整体的应用服务。

参考资料地址

http://weblogs.java.net/blog/2007/11/27/consistent-hashing

http://blog.csdn.net/mayongzhan/archive/2009/06/25/4298834.aspx

http://www.codeproject.com/KB/recipes/lib-conhash.aspx

http://blog.csdn.net/sparkliang/archive/2010/02/02/5279393.aspx

http://portal.acm.org/citation.cfm?id=258660

http://en.wikipedia.org/wiki/Consistent_hashing

http://www.spiteful.com/2008/03/17/programmers-toolbox-part-3-consistent-hashing/

http://weblogs.java.net/blog/2007/11/27/consistent-hashing

http://tech.idv2.com/2008/07/24/memcached-004/

http://blog.csdn.net/mayongzhan/archive/2009/06/25/4298834.aspx

文章出处:http://blog.csdn.net/x15594/article/details/6270242

最新文章

  1. MongoDB Java Driver操作指南
  2. Event Handler
  3. js自执行函数的几种不同写法的比较
  4. LabVIEW串口通信
  5. C++ 使用Htmlcxx解析Html内容(VS编译库文件)
  6. Xcode文档下载与安装路径
  7. IMP-00013 目前只有 DBA 其他导入能力 DBA 导出的文件
  8. 【Time系列三】简单的计时器(秒表)
  9. Restful based service 的跨域调用
  10. MYSQL 数据库高频查询语句整理
  11. 不使用数据结构反转栈 递归 CVTE实习 CVTE是一家什么公司
  12. (一)linux定时任务的设置 crontab 基础实践
  13. Java设计模式之【工厂模式】(简单工厂模式,工厂方法模式,抽象工厂模式)
  14. CentOS7部署Django,nginx,uwsgi,redis
  15. markdown改变字体颜色和大小
  16. 如何在一台计算机上配置多个jdk【转】
  17. .NET CORE 设置cookie以及获取cookie
  18. SQL注入的优化和绕过
  19. tomcat apr
  20. day042 前端CSS选择器

热门文章

  1. 关于 Unity 项目中的 Mono 堆内存泄露
  2. 二分+并查集【bzoj3007】[SDOI2012]拯救小云公主
  3. 【BZOJ 2119】 2119: 股市的预测 (后缀数组+分块+RMQ)
  4. jni java C/C++ 相互调用
  5. 「BZOJ 2534」 L - gap字符串
  6. luoguP4284 [SHOI2014]概率充电器 概率期望树形DP
  7. px,dp,sp以及像素密度
  8. day78_淘淘商城项目_11_单点登录系统实现 + 用户名回显 + ajax请求跨域问题详解_匠心笔记
  9. Java虚拟机类加载机制--概述
  10. SqlServer收缩数据库语句