有没有好奇过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. 互联网大厂Java面试题集—Spring boot常见面试题(二)

    Spring Boot的核心功能与使用优点? 核心功能: 1)Spring Boot项目为独立运行的spring项目,java -jar xx.jar即可运行. 2)内嵌servlet容器(可以选择内 ...

  2. 大白话OSI七层协议

    目录 一.物理层 二.数据链路层 2.1 以太网协议 2.2 Mac地址 2.3 广播地址 三.网络层 3.1 IP协议详解 3.1.1 IP地址的两部分 3.2 子网掩码详解 3.3 IP数据包详解 ...

  3. day26

    绑定方法 分为对象绑定方法和类的绑定方法 绑定方法的特殊之处 绑定给谁就是谁来调用 类的绑定方法 绑定给类,类来调用,会把类自身传过来 不需要通过对象 ,只需要通过类就能获取到一些东西的时候,用类的绑 ...

  4. VLAN实验3(Hybrid接口的应用)

    本实验基于<HCNA网络技术实验指南> 本实验使用eNSP软件 原理概述: Hybrid接口既可以连接普通终端的接入链路又可以连接交换机间的干道链路,它允 许多个VLAN的帧通过,并可以在 ...

  5. NSURLConnection发送GET请求

    // ViewController.m // 04-掌握-NSURLConnection发送GET请求 // // Created by xiaomage on 16/2/22. // Copyrig ...

  6. 数据库Oracle多表链接

    多表查询: 当查询的数据并不是来源一个表时,需要使用多表链接操作完成查询.根据不同表中的数据之间的关系查询相关联的数据. 多表链接方式: 内连接:(等值连接,非等值连接,自连接,SQL99有交叉连接( ...

  7. 移动开发在路上-- IOS移动开发系列 多线程二

    最近太忙没太多的时间,忙碌的码农生活空下来一点时间,都会挤出来看一些技术或者咨询的文章,废话不多说,直奔主题. 接着上一次的继续说. 定时器在多线程的使用 NSRunLoop 是线程相关的基础框架的一 ...

  8. [TimLinux] Python 函数

    1. 函数(function)与方法(method)的区别 方法:在类结构体中通过def语句声明的代码块称为方法,比如类方法(classmethod),实例方法,静态方法(staticmethod)等 ...

  9. Python入门(一个有趣的画图例子实战)你肯定不会

    前言本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理.作者:qiu_fang  画一条可爱的python(蟒蛇): import t ...

  10. 虚拟链路(virtual-link)

    第四部分,虚拟链路配置.我们都知道,在ospf多区域中,所有与主干区域(ospf0)相连接的其他区域可以相互学系路由信息,但是,如果是非主干区域和非主干区域相连,就不能相互学习路由信息,这时候,我们可 ...