• 一致性Hash算法


    可能会遇到这样的场景

      比如你有 N 个 cache 服务器(后面简称 cache ),那么如何将一个对象 object 映射到 N 个 cache 上呢,你很可能会采用类似下面的通用方法计算 object 的 hash 值,然后均匀的映射到到 N 个 cache :

      hash(object)%N

      如果增加一个cache,映射公式变成了 hash(object)%(N+1)

      如果一个cache宕机了,映射公式变成了 hash(object)%(N-1)

      在这两种情况下,几乎所有的 cache 都失效了。会导致数据库访问的压力陡增,严重情况,还可能导致数据库宕机。

      一致性hash算法正是为了解决此类问题的方法,它可以保证当机器增加或者减少时,对缓存访问命中的概率影响减至很小。

    一致性Hash环

      通常的 hash 算法都是将 value 映射到一个 32 位的 key 值,也即是 0~2^32-1 次方的数值空间;我们可以将这个空间想象成一个首( 0 )尾( 2^32-1 )相接的圆环

      

    将对象映射到hash环上

      

    将cache 映射到hash环上

      可以使用 cache 机器的 IP 地址或者机器名作为 hash 输入

      

    把对象映射到cache

      在这个环形空间中,如果沿着顺时针方向从对象的 key 值出发,直到遇见一个 cache ,那么就将该对象存储在这个 cache 上,因为对象和 cache 的 hash 值是固定的,因此这个 cache 必然是唯一和确定的。

      

    增加cache

      使用简单的求模方法,当新添加机器后会导致大部分缓存失效的情况,使用一致性hash算法后这种情况则会得到大大的改善。

      如下图,只有对象o4被重新分配到了c4,其他对象仍在原有机器上。

      

    减少cache

      只有对象o2被重新分配到机器c3,其他对象仍在原有机器上。

      

    虚拟节点

      哈希的结果能够尽可能分布到所有的cache中去,这样可以使得所有的缓冲空间都得到利用。

      如果 cache 较少的话,对象并不能被均匀的映射到 cache 上。

      可能o1映射到缓存a上,o2,o3,o4映射到缓存c上。

      为了解决这种情况,需要引入虚拟节点的概念。

      “虚拟节点”( virtual node )是实际节点在 hash 空间的复制品( replica ),一个实际节点对应了若干个“虚拟节点”。

      如图,虚拟节点A1,A2都会映射到实际结点A上。

      

      “虚拟节点”的 hash 计算可以采用对应节点的 IP 地址加数字后缀的方式。例如假设 cache A 的 IP 地址为 202.168.14.241 。

      引入“虚拟节点”前,计算 cache A 的 hash 值:

        Hash(“202.168.14.241”);

      引入“虚拟节点”后,计算“虚拟节”点 cache A1 和 cache A2 的 hash 值:

        Hash(“202.168.14.241#1”);  // cache A1

        Hash(“202.168.14.241#2”);  // cache A2

    参考:

      https://blog.csdn.net/sparkliang/article/details/5279393

      https://blog.csdn.net/lihao21/article/details/54193868

  • 相关阅读:
    原型模式
    单例模式-2(注册式单例)
    单例模式-1(懒汉式、饿汉式)
    PBKDF2加密的实现
    vue中获取客户端IP地址
    微信公众平台,监听用户输入及事件
    详解二叉树的遍历-前中后序遍历/层序遍历-递归/迭代
    联想小新pro关机变慢的解决办法
    MySQL自学笔记系列
    MySQL入门-首先搞清楚【数据类型】
  • 原文地址:https://www.cnblogs.com/mengchunchen/p/9658402.html
Copyright © 2020-2023  润新知