`

有关一致性哈希算法的应用场景

阅读更多
Tim Yang去年在博客(http://timyang.net)讨论一个有状态服务的场景下如何使用一致性哈希算法的问题。其中主要涉及到增加或删除节点时引起的系统震荡。其中也讨论了是否使用随机选取节点,并使用memcached保持选择的方案。

我们知道一致性哈希算法可以很好的解决增加或删除节点时引起的系统震荡问题。采用虚拟节点后,平均的将增删节点产生的震荡分配到其他节点上。测试证实了一致性哈希算法有很良好的平均性。

我们做一个简单测试:
有50个node,200个虚节点,100000个session。分别测试增加10%的节点和删除10%的节点对系统有多少影响。结果分析如下,

Normal case : nodes count : 50
Added case : nodes count : 55
Reduced case : nodes count : 45
85512   ---   85431
Same percent in added case : 89.218124%
Same percent in reduced case : 89.13361%
(增加或删除10%的节点后,仍有约89%的session被分配给原有节点)

但测试中暴露了两个问题,有待以后研究。
一个是随着节点数的增加,分配给每个节点的session不再是非常平均。特别是在环开始的几个节点分配的较少
第二是当节点数量很多时,比如2^32大小的寻址空间上,如果节点数量很大,超过1000个虚节点,算法性能就开始有比较明显的下降。这可能是由于实现问题,但是还需要调研。

回到原来的问题上,即什么样的场景适合使用一致性哈希算法。
这里有两类场景,我们先来讨论比较简单的情况。

场景一
假设有一种静态资源,例如视频、网页、大型log文件等,只有第一次请求时才加载到系统中。我们希望以后每次对相关资源的请求都送达到同一个节点。这样可以最大限度的利用整个集群的能力,这也是CDN的基本思路。
这类场景的特点是,
1,在高并发情况下,如何使多个并发请求都被发送到同一节点。
2,session实际是无状态的

在该情况下,使用一致性哈希是很合适的。我在构建高性能Java服务器中谈到了使用一致性哈希算法替代多线程上同步锁,从而极大的提高系统性能。就是在这个场景下实现的。

场景二
一个有状态服务,持有大量有状态session,且session不断的被更新和查询。

这种类型的session是不可能被实时更新到数据库的,因此它们只能在分布式内存中被保持。由于session更新频繁,且要特别考虑到场景是多线程同时受理对同一session的多个请求。因此我们的考虑是,不能完全把session保存在一个分布式memory中,因为频繁的更新对CPU和网络都有比较大的压力session异步备份,还是那句话,这次业务可以失败,但是系统不能因为业务无法更新而停止工作

可以有几种解决方案,

buddy replication+一致性哈希

借鉴Jboss Cache buddy replication的思路。为了减少网络和被备份节点的压力,我们不希望把session复制到整个cluster上。但是又希望可以当单点crash后从内存恢复数据。因此我们只把session备份到几个节点上,例如当一致性哈希找到了工作节点后,该工作节点再使用固定后缀找到buddy node进行复制。
例如,sessionID+"buddy1";sessionID+"buddy2";
每次更新本地session的同时,节点异步的向buddy中的memcached写一个备份。如果本节点crash,session被分配到其他节点处理,它会试图从buddy的memcached中取回状态。

whole cluster replication
如果你的服务要求一个会话都不能丢失,则只能进行全cluster复制。这样可以保证任何一节点活着就能继续进行业务。我们测试过一些开源产品,比如Jboss InfiniSpan,
在节点数量不大,且网络条件很好的情况,仅用UDP进行whole cluster replication效果就很好。如果参考其实可以发现,通过NIO/TCP进行可序列号对象复制,其速度和可靠性在节点数较多的集群中也可以工作的很好。

以上两种场景在实际运营的系统中都可胜任,当然对于不同客户的不同要求,需要采用不同的架构。另外要考虑到团队的能力,比如团队如果一直基于JBoss开发,且用户对session状态的丢失率有严格要求,则采用Jboss Cache是最简单的方法。尽管它显然没有一致性哈希这么酷:)

本文纯属原创,欢迎转载,请注明原网址;
0
3
分享到:
评论
1 楼 elicer 2014-08-16  
引用
每次更新本地session的同时,节点异步的向buddy中的memcached写一个备份。如果本节点crash,session被分配到其他节点处理,它会试图从buddy的memcached中取回状态。

请问一句,你们是怎么检测当前session并不在当前的节点上,需要从memchched中去取。
另外,存储过程是不是以session id 作为key, session object作为value

相关推荐

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

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

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

    典型的应用场景是: 有N台服务器提供缓存服务,需要对服务器进行负载均衡,将请求平均分发到每台服务器上,每台机器负责1/N的服务。 常用的算法是对hash结果取余数 (hash() mod N):对机器编号从0到N-1,按照自定义...

    实时通信集群负载均衡策略研究与应用

    本文首先分析单服务器场景下的实时通信流程,然后研究和分析常见的负载均衡算法,同时为满足同群组客户端需转发到相同服务器的一致性要求,提出一种基于一致性哈希算法和遗传算法的自适应负载均衡算法,并对该算法...

    大厂的Java面试题分享

    如何保证事务的完整性和一致性? 5. SQL语言中的聚合函数有哪些?它们分别是什么作用? 数据结构题: 1. 什么是栈和队列?它们的应用场景是什么? 2. 什么是哈希表?如何实现一个哈希表? 3. 什么是二叉树?如何...

    leetcode跳跃-CS-Notes:备战秋招笔记

    leetcode 跳跃 Ⅰ Ⅱ Ⅲ Ⅳ Ⅴ Ⅵ Ⅶ Ⅷ ...算法 ...算法 ...缓存特征、缓存位置、缓存问题、数据分布、一致性哈希、LRU、CDN 消息处理模型、使用场景、可靠性 :hammer: 工具 一些 Git 的使用和概念。 正则

    Redis面试题50道(含答案)_.pdf

    39、支持一致性哈希的客户端有哪些? 40、Redis 与其他 key-value 存储有什么不同? 41、Redis 的内存占用情况怎么样? 42、都有哪些办法可以降低 Redis 的内存使用情况呢? 43、查看 Redis 使用情况及状态信息用...

    开涛高可用高并发-亿级流量核心技术

    11.6.2 一致性哈希 226 11.6.3 快速恢复 226 12 连接池线程池详解 227 12.1 数据库连接池 227 12.1.1 DBCP连接池配置 228 12.1.2 DBCP配置建议 233 12.1.3 数据库驱动超时实现 234 12.1.4 连接池使用的一些建议 235 ...

    java面试题,180多页,绝对良心制作,欢迎点评,涵盖各种知识点,排版优美,阅读舒心

    【算法】什么是一致性哈希?用来解决什么问题? 144 【性能优化】页面静态化 144 【设计模式】写一个单例(延迟加载,高性能) 144 【容器】Apache Http Server和Tomcat 区别 145 【版本控制】GIT与SVN的区别 146 【高...

    beauty of architecture

    一致哈希—分布式存储的基础算法 索引原理:布尔代数和搜索引擎的索引 MySQL索引背后的数据结构和算法原理 4.1.2 NoSQL 集群环境下关系型数据库扩展性的问题 数据模型与存储模型的矛盾 NoSQL的来源、主要特征和...

    Redis V3.0 中文文档

    列表的通用场景(Common use cases) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 上限列表(Capped) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ....

    Redis 3.0 中文版 - v1.1.pdf

    列表的通用场景(Common use cases) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 上限列表(Capped) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ....

Global site tag (gtag.js) - Google Analytics