Memcache分布式方案

分布式和集群区别
  • 分布式:分布式处理是将不同地点的,或具有不同功能的,或拥有不同数据的多台计算机通过通信网络连接起来,在控制系统的统一管理控制下,协调地完成大规模信息处理任务的计算机系统。简单地说,分布式处理就是多台相连的计算机各自承担同一工作任务的不同部分,在人的控制下,同时运行,共同完成同一件任务。

  • 集群:是一组相互独立的、通过高速网络互联的计算机,它们构成了一个组,并以单一系统的模式加以管理。一个客户与集群相互作用时,集群像是一个独立的服务器。简单的说,集群就是几台计算机同时部署同一个任务。

有时候一台memcached服务器不能满足我们的要求,需要布置多台服务器,但是有个问题,怎么确定一个数据应该保存到哪台服务器上边呢?

  memcached 尽管是“分布式”缓存服务器,但服务器端并没有分布式功能,memcached 不会互相通信以共享信息,那么,怎样进行分布式呢?这完全取决于客户端的实现。有两种方案,一种是普通Hash分布,另一种是一致性Hash分布。

一、普通Hash分布

  普通Hash函数相对简单,Hash函数如下:

function mHash($key){
   $md5 = substr(md5($key), 0, 8);
   $seed = 31;
   $hash = 0;
  
   for($i=0; $i<8; $i++){
       $hash = $hash*seed + ord($md5[$i]);
       $i++;
   }
   return $hash & 0x7FFFFFFF;
}

  首先通过md5把key处理成一个32位的字符串,取其前8个字符。在经过Hash算法处理成一个整数并返回,然后映射到其中的一台Memcached服务器。

  假如配置两台Memcache服务器,可以使用下面代码映射:

<?php
$servers = [
       ['host'=>'192.168.1.12', 'port'=>11211],
       ['host'=>'192.168.1.21', 'port'=>11211],
];
$key = 'setKeys';
$value = 'setValues';

$sc = $servers[mHash[$key] % 2];

$memcached = new Memcached($sc);
$memcache->set($key, $value);

  通过Hash函数把key转化成整数后,利用这个整数与Memcached服务器数量取模,这样得到的是其中一台服务器的配置,利用这个配置连接Memcache服务器,这样就完成了分布式布置。

二、一致性Hash分布

  在普通服务器数量不改变的时候,普通Hash分布可以很好的运作。当服务器数量发生改变时,问题就出来了,假如增加一台服务器后,同一个key经过hash之后,与服务器取模后的结果跟没增加之前不一样,这样就导致了之前保存的数据丢失,为了把丢失的数据减到最少,可以采用一致性Hash分布算法解决。
  一致性Hash算法分为6步,如下:

  1. 将一个32位整数(即0 – 2^32-1)想象成一个环,将0作为圆环的头, 2^32-1作为圆环的尾,假想把它连起来组成一个环,如图1所示:
  2. 通过Hash函数把key处理成整数。
    例如把4个key通过Hash函数处理成整数:
$key1 = mHash('key1');
$key2 = mHash('key2');
$key3 = mHash('key3');
$key4 = mHash('key4');

把key处理成整数后,就可以在环中找到一个位置与之对应,如图2所示:

《Memcache分布式方案》 01.png

  1. 把Memcached群映射到环上,使用Hash函数处理服务器IP地址。
    加入有三台memcached服务器ip为192.168.1.1, 192.168.1.4, 192.168.1.5。
$server1 = mHash('192.168.1.1');
$server2 = mHash('192.168.1.4');
$server3 = mHash('192.168.1.5');

把服务器映射到环上,经过上面几个步骤,我们把数据Key和服务器都映射到同一个环上,如图3所示:

《Memcache分布式方案》 2.png

  1. 把key映射到服务器上,沿着圆环顺时针方向的key出发,直到遇到第一个服务器位置,把key对应的数据保存在这个服务器上,key1,key4保存到server3上,key3保存到server2上,key2保存到server1上。

  2. 添加服务器
    假如现在需要添加一台服务器server4,用之前的方法得出server4的位置在key1和key4之间,这时受影响的是server4逆时针到server1之间的数据,把这些数据映射到server4上,这里仅需要变动Key1,映射到server4上即可,如图4:

  3. 移除服务器
    假如现在有一台服务器server2故障了,依照上述方法,顺时针映射,受影响的是server2逆时针到server3之间的数据,也就是key3,这里需要把key3顺时针映射到下一个服务器,也就是server1上。

后续我会用PHP实现一致性Hash分布算法。

    原文作者:幽思片羽
    原文地址: https://www.jianshu.com/p/89ba8bf70a74
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞