一直性Hash算法在很多场景下都有应用,尤其是在分布式缓存系统中,经常用其来进行缓存的访问的负载均衡,比如:redis等<k,v>非关系数据库作为缓存系统。我们首先来看一下采用取模方式进行缓存的问题。

一致性Hash算法的使用场景

假设我们的将10台redis部署为我们的缓存系统,存储<k,v>数据,存储方式是:hash(k)%10,用来将数据分散到各个redis存储系统中。这样做,最大的问题就在于:如果此缓存系统扩展(比如:增加或减少redis服务器的数量),节点故障宕机等将会带来很高的代价。比如:我们业务量增大了,需要扩展我们的缓存系统,再增加一台redis作为缓存服务器,那么后来的数据<k,v>的散列方式变为了:hash(k)%11。我们可以看到,如果我们要查找扩展之前的数据,利用hash(k)%11,则会找不到对应的存储服务器。所以这个时候大量的数据失效了(访问不到了)。
这时候,我们就要进行数据的重现散列,如果是将redis作为存储系统,则需要进行数据迁移,然后进行恢复,但是这个时候就意味着每次增减服务器的时候,集群就需要大量的通信,进行数据迁移,这个开销是非常大的。如果只是缓存,那么缓存就都失效了。这会形成缓存击穿,导致数据库压力巨大,可能会导致应用的崩溃。

一致性Hash算法的原理

因为对于hash(k)的范围在int范围,所以我们将0~2^32作为一个环。其步骤为:
1,求出每个服务器的hash(服务器ip)值,将其配置到一个 0~2^n 的圆环上(n通常取32)。
2,用同样的方法求出待存储对象的主键 hash值,也将其配置到这个圆环上,然后从数据映射到的位置开始顺时针查找,将数据分布到找到的第一个服务器节点上。
其分布如图:

这是一致性hash算法的基本原理,接下来我们看一下,此算法是如何解决 我们上边 说的 缓存系统的扩展或者节点宕机导致的缓存失效的问题。比如:再加入一个redis节点:

如上图,当我们加入redis node5之后,影响的范围只有黄色标出的那部分,不会造成全局的变动。

除了上边的优点,其实还有一个优点:对于热点数据,如果发现node1访问量明显很大,负载高于其他节点,这就说明node1存储的数据是热点数据。这时候,为了减少node1的负载,我们可以在热点数据位置再加入一个node,用来分担热点数据的压力。
雪崩效应

接下来我们来看一下,当有节点宕机时会有什么问题。如下图:

如上图,当B节点宕机后,原本存储在B节点的k1,k2将会迁移到节点C上,这可能会导致很大的问题。如果B上存储的是热点数据,将数据迁移到C节点上,然后C需要承受B+C的数据,也承受不住,也挂了。。。。然后继续CD都挂了。这就造成了雪崩效应。
上面会造成雪崩效应的原因分析:
如果不存在热点数据的时候,每台机器的承受的压力是M/2(假设每台机器的最高负载能力为M),原本是不会有问题的,但是,这个时候A服务器由于有热点数据挂了,然后A的数据迁移至B,导致B所需要承受的压力变为M(还不考虑热点数据访问的压力),所以这个失败B是必挂的,然后C至少需要承受1.5M的压力。。。。然后大家一起挂。。。
所以我们通过上面可以看到,之所以会大家一起挂,原因在于如果一台机器挂了,那么它的压力全部被分配到一台机器上,导致雪崩。

怎么解决雪崩问题呢,这时候需要引入虚拟节点来进行解决。
虚拟节点

虚拟节点,我们可以针对每个实际的节点,虚拟出多个虚拟节点,用来映射到圈上的位置,进行存储对应的数据。如下图:

如上图:A节点对应A1,A2,BCD节点同理。这时候,如果A节点挂了,A节点的数据迁移情况是:A1数据会迁移到C2,A2数据迁移到D1。这就相当于A的数据被C和D分担了,这就避免了雪崩效应的发送,而且虚拟节点我们可以自定义设置,使其适用于我们的应用。

一致性哈希算法----nginx负载均衡器配置之一的更多相关文章

  1. Nginx 第三方模块的安装以及一致性哈希算法的使用

    Nginx 第三方模块的安装以及一致性哈希算法的使用 第三方模块安装方法总结: 以ngx_http_php_memcache_standard_balancer-master为例 1:解压 到 pat ...

  2. nginx系列12:一致性哈希算法

    前面一节的hash算法存在一个问题,当上游的应用服务器因某一台down掉导致服务器数量发生变化时,会导致大量的请求路由策略失效,一致性哈希算法可以缓解这个问题. 一致性哈希算法 1,hash算法存在的 ...

  3. 一致性哈希算法(Consistent Hashing) .

    应用场景 这里我先描述一个极其简单的业务场景:用4台Cache服务器缓存所有Object. 那么我将如何把一个Object映射至对应的Cache服务器呢?最简单的方法设置缓存规则:object.has ...

  4. Go -- 一致性哈希算法

    一致性哈希算法在1997年由麻省理工学院的Karger等人在解决分布式Cache中提出的,设计目标是为了解决因特网中的热点(Hot spot)问题,初衷和CARP十分类似.一致性哈希修正了CARP使用 ...

  5. 一致性哈希算法与Java实现

    原文:http://blog.csdn.net/wuhuan_wp/article/details/7010071 一致性哈希算法是分布式系统中常用的算法.比如,一个分布式的存储系统,要将数据存储到具 ...

  6. 五分钟理解一致性哈希算法(consistent hashing)

    转载请说明出处:http://blog.csdn.net/cywosp/article/details/23397179 一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT)实现算法 ...

  7. 每天进步一点点——五分钟理解一致性哈希算法(consistent hashing)

    转载请说明出处:http://blog.csdn.net/cywosp/article/details/23397179     一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT) ...

  8. 一致性哈希算法以及其PHP实现

    在做服务器负载均衡时候可供选择的负载均衡的算法有很多,包括:  轮循算法(Round Robin).哈希算法(HASH).最少连接算法(Least Connection).响应速度算法(Respons ...

  9. Java_一致性哈希算法与Java实现

    摘自:http://blog.csdn.net/wuhuan_wp/article/details/7010071 一致性哈希算法是分布式系统中常用的算法.比如,一个分布式的存储系统,要将数据存储到具 ...

随机推荐

  1. SpringBoot 集成Mybatis 连接Mysql数据库

    记录SpringBoot 集成Mybatis 连接数据库 防止后面忘记 1.添加Mybatis和Mysql依赖 <dependency> <groupId>org.mybati ...

  2. java代码之美(5)---guava之Multiset

    guava之Multiset 一.概述 Guava提供了一个新集合类型Multiset,它可以多次添加相等的元素,且和元素顺序无关.Multiset继承于JDK的Cllection接口,而不是Set接 ...

  3. .NET之消息推送(SignalR即时通讯实现)

    前言 ASP .NET SignalR 是一个ASP .NET 下的类库,可以在ASP .NET 的Web项目中实现实时通信.什么是实时通信的Web呢?就是让客户端(Web页面)和服务器端可以互相通知 ...

  4. rabbitmq.config配置参数详解

    rabbitmq.config详细配置参数 详细使用方法请点击:http://www.cnblogs.com/wyt007/p/9073316.html Key Documentation tcp_l ...

  5. leetcode — remove-duplicates-from-sorted-array-ii

    /** * Source : https://oj.leetcode.com/problems/remove-duplicates-from-sorted-array-ii/ * * * Follow ...

  6. Android单个控件占父控件宽度一半且水平居中

    前些天,在工作中遇到了一个需求:一个“加载上一页”的按钮宽度为父控件宽度一半,且水平居中于父控件中. 在此给出两种思路: 1.直接在Activity代码中获取到当前父控件的宽度,并将此按钮宽度值设置成 ...

  7. Disconf源码分析之启动过程分析下(2)

    接上文,下面是第二次扫描的XML配置. <bean id="disconfMgrBean2" class="com.baidu.disconf.client.Dis ...

  8. iOS 加锁的方式

    iOS多线程编程中,经常碰到多个线程访问共同的一个资源,在线程相互交互的情况下,需要一些同步措施,来保证线程之间交互的时候是安全的.下面我们一起看一下学一下iOS的几种常用的加锁方式,希望对大家有所帮 ...

  9. [Redis] redis的设计与实现-对象系统

    1.redis并没有直接使用前面的数据结构实现键值对数据库,而是基于数据结构创建了一个对象系统,字符串对象/列表对象/哈希对象/集合对象/有序集合对象都用到了至少一种前面的数据结构2.针对不同的使用场 ...

  10. C# 创建EXCEL图表并保存为图片

    数据表格能够清晰的呈现数据信息,但是我们对于一些繁杂多变的数据想要很直观的看到数据变化走势或者数据的占比时,数据图表会更具代表性,并且在呈现数据信息上也更形象,也能获取更多纯数字信息所不能直接展现的信 ...