有没有好奇过redis、memcache等是怎么实现集群负载均衡的呢?

其实他们都是通过一致性hash算法实现节点调度的。

讲一致性hash算法前,先简述一下求余hash算法:

hash(object)%N

  1. 一个缓存服务器宕机了,这样所有映射到这台服务器的对象都会失效,我们需要把属于该服务器中的缓存移除,这时候缓存服务器是 N-1 台,映射公式变成了 hash(object)%(N-1) ;
  2. 由于QPS升高,我们需要添加多一台服务器,这时候服务器是 N+1 台,映射公式变成了 hash(object)%(N+1) 。

1 和 2 的改变都会出现所有服务器需要进行数据迁移。

一致性HASH算法

一致性HASH算法的出现有效的解决了上面普通求余算法在节点变动后面临全部缓存失效的问题:

  type Consistent struct {

  numOfVirtualNode int

  hashSortedNodes []uint32

  circle map[uint32]string

  nodes map[string]bool

}

简单地说,一致性哈希将整个哈希值空间组织成一个虚拟的圆环,如假设某空间哈希函数H的值空间是0-2^32-1(即哈希值是一个32位无符号整形),整个哈希空间如下:

下一步将各个服务器使用哈希算法计算出每台机器的位置,具体可以使用服务器的IP地址或者主机名作为关键字,并且是按照顺时针排列:

  //这里我选择crc32,具体情况具体安排

  func hashKey(host string) uint32 {

  scratch := []byte(host)

  return crc32.ChecksumIEEE(scratch)

}

这里我们假设三台节点memcache经计算后位置如下:

  //add the node

  c.Add("Memcache_server01")

  c.Add("Memcache_server02")

  c.Add("Memcache_server03")

  func (c *Consistent) Add(node string) error {

  if _, ok := c.nodes[node]; ok {

  return errors.New("host already existed")

}

  c.nodes[node] = true

  // add virtual node

  for i := 0; i < c.numOfVirtualNode; i++ {

  virtualKey := getVirtualKey(i, node)

  c.circle[virtualKey] = node

  c.hashSortedNodes = append(c.hashSortedNodes, virtualKey)

 }

  sort.Slice(c.hashSortedNodes, func(i, j int) bool {

  return c.hashSortedNodes[i] < c.hashSortedNodes[j]

  })

  return nil

}

接下来使用相同算法计算出数据的哈希值,并由此确定数据在此哈希环上的位置

假如我们有数据A、B、C和D,经过哈希计算后位置如下:

根据一致性哈希算法,数据A就被绑定到了server01上,D被绑定到了server02上,B、C在server03上,是按照顺时针找最近服务节点方法

这样得到的哈希环调度方法,有很高的容错性和可扩展性:

假设server03宕机

可以看到此时A、C、B不会受到影响,只是将B、C节点被重定位到Server 1。一般的,在一致性哈希算法中,如果一台服务器不可用,则受影响的数据仅仅是此服务器到其环空间中前一台服务器(即顺着逆时针方向行走遇到的第一台服务器)之间数据,其它不会受到影响。

考虑另外一种情况,如果我们在系统中增加一台服务器Memcached Server 04:

此时A、D、C不受影响,只有B需要重定位到新的Server 4。一般的,在一致性哈希算法中,如果增加一台服务器,则受影响的数据仅仅是新服务器到其环空间中前一台服务器(即顺着逆时针方向行走遇到的第一台服务器)之间数据,其它不会受到影响。

一致性hash算法--负载均衡的更多相关文章

  1. 一致性 Hash 在负载均衡中的应用

    介 一致性Hash是一种特殊的Hash算法,由于其均衡性.持久性的映射特点,被广泛的应用于负载均衡领域,如nginx和memcached都采用了一致性Hash来作为集群负载均衡的方案.本文将介绍一致性 ...

  2. 不会一致性hash算法,劝你简历别写搞过负载均衡

    大家好,我是小富~ 个人公众号:程序员内点事,欢迎学习交流 这两天看到技术群里,有小伙伴在讨论一致性hash算法的问题,正愁没啥写的题目就来了,那就简单介绍下它的原理.下边我们以分布式缓存中经典场景举 ...

  3. c# Hash一致算法负载均衡(KetamaHash)项目升级

    其实就是我最近写的一个项目,采用Hash一致满足负载均衡.Hash一致环带虚拟节点. 在前面的博文中说明了我采用的方法,MurmurHash+红黑树(底层其实是sortedlist).经过多次测试结合 ...

  4. 对一致性Hash算法,Java代码实现的深入研究

    一致性Hash算法 关于一致性Hash算法,在我之前的博文中已经有多次提到了,MemCache超详细解读一文中"一致性Hash算法"部分,对于为什么要使用一致性Hash算法.一致性 ...

  5. 一致性hash算法详解

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

  6. memcache的一致性hash算法使用

    一.概述 1.我们的memcache客户端(这里我看的spymemcache的源码),使用了一致性hash算法ketama进行数据存储节点的选择.与常规的hash算法思路不同,只是对我们要存储数据的k ...

  7. 一致性Hash算法在Memcached中的应用

    前言 大家应该都知道Memcached要想实现分布式只能在客户端来完成,目前比较流行的是通过一致性hash算法来实现.常规的方法是将server的hash值与server的总台数进行求余,即hash% ...

  8. 分布式算法(一致性Hash算法)

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

  9. Java实现一致性Hash算法深入研究

    一致性Hash算法 关于一致性Hash算法,在我之前的博文中已经有多次提到了,MemCache超详细解读一文中”一致性Hash算法”部分,对于为什么要使用一致性Hash算法和一致性Hash算法的算法原 ...

随机推荐

  1. 英语口语考试资料Friendships

    Friendships Remember Friendships can be complicated. When you want to get to know someone, it helps ...

  2. 华为OSPF与ACL综合应用实例讲解

    OSPF与ACL综合应用实例讲解 项目案例要求: 1.企业内网运行OSPF路由协议,区域规划如图所示:2.财务和研发所在的区域不受其他区域链路不稳定性影响:3.R1.R2.R3只允许被IT登录管理:4 ...

  3. 想实现多人协作的“在线Excel”?真没那么简单

    本文由葡萄城技术团队原创并首发 转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. Excel是我们办公中常用的工具 ,它几乎能为我们处理大部分数据,友好的交互 ...

  4. Mysql 执行计划以及常见索引问题总结

    Mysql 执行计划以及常见索引问题总结

  5. luogu P3152 正整数序列

    题目描述 kkk制造了一个序列,这个序列里的数全是由正整数构成的.你别认为她的数列很神奇--其实就是1, 2, -, n而已.当然,n是给定的.kkk的同学lzn认为0是一个好数字(看上去很饱满有木有 ...

  6. java中List、Map、Set、Stack、Queue、Collections等的使用

    java中List.Map.Set.Stack.Queue.Collections等的使用 List 创建方法: List<String> list=new ArrayList<&g ...

  7. 洛谷 P2764(最小路径覆盖=节点数-最大匹配)

    给定有向图G=(V,E).设P 是G 的一个简单路(顶点不相交)的集合.如果V 中每个顶点恰好在P 的一条路上,则称P是G 的一个路径覆盖.P 中路径可以从V 的任何一个顶点开始,长度也是任意的,特别 ...

  8. Docker系列-(2) 镜像制作与发布

    上篇文章引入了Docker的基本原理和操作,本节文章主要介绍如何制作Docker镜像和发布. 镜像文件结构 Docker镜像的本质是一系列文件的集合,这些文件依次叠加,形成了最后的镜像文件,类似于下图 ...

  9. QEMU让你无需开发板即可玩溜RT-Thread~

    1.1 本文的目的和背景 嵌入式软件开发离不开开发板,在没有物理开发板的情况下,可以使用QEMU等类似的虚拟机来模拟开发板.QEMU是一个支持跨平台虚拟化的虚拟机,它可以虚拟很多开发板.为了方便大家在 ...

  10. jvm调优、常用工具

    ps -ef | grep java查出进程id jmap -heap ID 查出jvm配置信息 加入参数:打印Gc日志,分析 GC日志分析工具: GCeasy 降低minor gc 和 full g ...