memcached布满式缓存,分布式缓存

转载地址:

读书目录

一、memcached布满式简单介绍

  memcached就算名叫“分布式”缓存服务器,但劳动器端并未“布满式”功用。Memcache集群主机不可能互为通讯传输数据,它的“布满式”是依据客户端的程序逻辑算法进一步贯彻的。

请看上面简图:

亚洲必赢官网 1

依赖上海体育场合大家简述分析布满式memcached的set与get的经过

set过程:

一、首先通过应用程序set(‘key’,’value’)

2、进入程序,使用key通过逻辑算法得出这几个key供给仓库储存的节点地点

三、依照节点地方三番五次相应的memcached服务器,并发送set命令

get过程:

①、首先通过应用程序get(‘key’)

二、接着使用该key通过逻辑算法获取该key的积累节点

三、依照节点连接相应的memcached服务器,并发送get命令

  实现memcached有很二种办法,在那之中最常用的便是千篇一律哈希思想的布满式(就简称为同样哈希遍及式啦)。好的东西自然需求次劣品来映衬它的亮点啦,由此在此间除了讲明一致哈希布满式,还会讲到取模布满式。从而越发分析他们的利害。

  这里的例子都会使用PHP代码完成,当然啦,最重视的是思索与措施嘛!毕竟那两样东西在任何语言中都以相通的。

 

作者:那一叶随风

  • 一、memcached遍布式简要介绍
  • 2、取模算法方式
  • 3、1致哈希算法方式

二、取模算法格局

  何为取模算法格局布满式?就是将key转换为三十二个人的数字,并与memcached服务器的总和进行相除获得余数。而以此余数正是memcached服务器的节点node。有了那个node我们就能够分明memcached服务器,就能够发送命令给memcached实行了。

图示解析:

亚洲必赢官网 2

全部进程上海体育场合所示。

一)、PHP代码达成

GetModMemcache.class.php

 1 <?php
 2 #分布式memcache(取模计算)
 3 class GetModMemcache
 4 {
 5     private $total='';          #存储memcache服务器的总数
 6     private $servers=array();   #存储memcache服务器的具体信息
 7     /**
 8     * @desc 构造函数
 9     *
10     * @param $serversArr array | memcache服务器具体信息
11     */
12     public function __construct($serversArr)
13     {
14         $this->total=count($serversArr);
15         $this->servers=$serversArr;
16     }
17 
18     /**
19     * @desc 计算$key的存储位置(即哪个服务器)
20     * 
21     * @param string | key字符串
22     *
23     * @return int  返回第几个服务器
24     */
25     protected function position($key)
26     {
27         #使用crc32(),将字符串转化为32为的数字
28         return sprintf('%u',crc32($key))%$this->total;      #取余
29     }
30 
31     /**
32     * @desc 获取memcached对象
33     *
34     * @param $position int | key的位置信息
35     *
36     * @return object 返回实例化memcached对象
37     */
38     protected function getMemcached($position)
39     {
40         $host=$this->servers[$position]['host'];    #服务器池中某台服务器host
41         $port=$this->servers[$position]['port'];    #服务器池中某台服务器port
42         $m= new memcached();
43         $m->addserver($host, $port);
44         return $m; 
45     }
46 
47     /**
48     * @desc 设置key-value值
49     *
50     * @param string | key字符串
51     * @param mixed  | 值可以是任何有效的非资源型php类型
52     *
53     * @return 返回结果
54     */
55     public function setKey($key, $value)
56     {
57         $num=$this->position($key);
58         echo $num;      #调试用
59         $m=$this->getMemcached($num);   #获取memcached对象
60         return $m->set($key, $value);
61     }
62 
63     public function getKey($key)
64     {
65         $num=$this->position($key);
66         $m=$this->getMemcached($num);
67         return $m->get($key);
68     }
69 
70 
71 }
72 
73 
74 $arr=array(
75     array('host'=>'192.168.95.11', 'port'=>'11210'),
76     array('host'=>'192.168.95.11', 'port'=>'11211'),
77     array('host'=>'192.168.95.11', 'port'=>'11212'),
78     );
79 $mod=new GetModMemcache($arr);
80 
81 /*
82 #存储数据
83 $a=$mod->setKey('key3', 'key33333');
84 echo "<pre>";
85 print_r($a);
86 echo "</pre>";die;
87 */
88 /*
89 #获取数据
90 $b=$mod->getKey('key1');
91 echo "<pre>";
92 print_r($b);
93 echo "</pre>";die;
94 */
95 ?>

 

2)、举办相应测试

  一、一连插入多个数据

  #set(‘key1’,’value11111’);  #node=1

  #set(‘key2’,’value22222’);  #node=1

  #set(‘key3’,’value33333’;)  #node=0

  2、分别telnet连接192.168.95.11:(11210、11211、11212)

  11210含有key3数据

  11211含有key1、key2数据

  11212不含数据

  叁、使用程序get数据

  结果都能够将数据收取来

3)、优缺点

  优点:

  一、轻松实用易通晓

  二、数据遍及均匀

  缺点:

  1、宕了1台memcached服务器时不能够半自动调度群组去管理数据,使有些数量无法选取缓存,平素不断从数据库中获取数据。

  贰、当供给扩大容积的时候,增扩充台memcached服务器,那么原来已经缓存的数码大繁多都不可见被击中,即数据无用。

 

一、memcached布满式简要介绍

  memcached就算称之为“布满式”缓存服务器,但劳务器端并从未“遍及式”功效。Memcache集群主机不能相互通讯传输数据,它的“遍及式”是基于客户端的程序逻辑算法进一步贯彻的。

请看上边简图:

亚洲必赢官网 3

凭借上航海用体育地方我们简述分析分布式memcached的set与get的长河

set过程:

一、首先通过应用程序set(‘key’,’value’)

二、进入程序,使用key通过逻辑算法得出这么些key需求仓库储存的节点地点

3、依照节点地点再而三相应的memcached服务器,并发送set命令

get过程:

1、首先通过应用程序get(‘key’)

2、接着使用该key通过逻辑算法获取该key的存款和储蓄节点

3、依照节点连接相应的memcached服务器,并发送get命令

  实现memcached有很各个艺术,个中最常用的正是壹致哈希观念的遍及式(就简称为同1哈希布满式啦)。好的事物自然要求次劣质商品来烘托它的长处啦,因而在此地除了教学一致哈希遍及式,还会讲到取模遍及式。从而特别分析他们的利害。

  这里的例子都会使用PHP代码完成,当然啦,最重要的是观念与措施嘛!毕竟那两样东西在任何语言中都是相通的。

memcached布满式缓存,分布式缓存。 

回到顶部

3、1致哈希算法情势

何为一致哈希算法格局布满式呢?

  想象一下,将三十个人的装有数字从小到大按顺时针布满在四个圆环上;

  其次,将各类存款和储蓄节点赋予三个名字,并通过crc3二函数将其改造为三九个人的数字,此数字便是该memcached服务器的积累节点

  接着,将key也因此crc3贰函数调换为三1二个人的数字,它的所在地方按顺时针方向走先是个遭遇的仓库储存节点所对应的memcached服务器便是该key的尾声存款和储蓄服务器。

壹)、图像分析

亚洲必赢官网 4

  假使node一节点服务器挂了,遵照按顺时针近日口径,那么原来存款和储蓄在node壹节点的数量此时也可存款和储蓄在node三节点中。

  假如有扩大体积的供给,扩大的两台memcached服务器,又将会怎样呢?请看下图分析

亚洲必赢官网 5

结果显示唯有为数不佳些个码会遇到震慑,绝对于完整数量来讲这么些潜移默化仍旧在可承受的界定内。

  从地点的图示大家能够很轻巧发觉存在这么个毛病,正是使用crc3二函数大家不可能调控memcached存款和储蓄节点的具体地方,并且节点的总量量相对于贰的三十二次方是显得多么的渺小。倘使恰好即便那多少个存款和储蓄节点都距离的不行近呢,那么自然有一个memcached服务器承受绝大繁多的数据缓存。

请看下图分析:

亚洲必赢官网 6

化解办法:

  将三个真正存储节点映射为多少个虚拟存款和储蓄节点,即真实节点+后缀再通过crc3二管理(比方:node1_1、node1_2、node1_3、…..、node1_n)

看下图节点分布:

  四个真正节点在圆环上就成为了三十二个存款和储蓄节点,那样就足防止止存款和储蓄节点相距太近而形成数据缓存遍布不均匀的标题了,而且蕴藏机制未有此外变化。

亚洲必赢官网 7

贰)、PHP代码完毕

ConsistentHashMemcache.class.php

  1 <?php
  2 #分布式memcache 一致性哈希算法(采用环状数据结构)
  3 class ConsistentHashMemcache
  4 {
  5     private $virtualNode='';      #用于存储虚拟节点个数
  6     private $realNode=array();    #用于存储真实节点
  7     private $servers=array();      #用于存储memcache服务器信息
  8     #private $totalNode=array();   #节点总数
  9     /**
 10     * @desc 构造函数
 11     *
 12     * @param $servers array    | memcache服务器的信息
 13     * @param $virtualNode int | 虚拟节点个数,默认64个
 14     */
 15     public function __construct($servers, $virtualNode=64)
 16     {
 17         $this->servers=$servers;
 18         $this->realNode=array_keys($servers);
 19         $this->virtualNode=$virtualNode;
 20     }
 21 
 22     /**
 23     * @return int 返回32位的数字
 24     */
 25     private function hash($str)
 26     {
 27         return sprintf('%u',crc32($str));   #将字符串转换为32位的数字
 28     }
 29 
 30     /**
 31     * @desc 处理节点
 32     *
 33     * @param $realNode     array | 真实节点 
 34     * @param $virturalNode int   | 虚拟节点个数
 35     *
 36     * @return array 返回所有节点信息
 37     */
 38     private function dealNode($realNode, $virtualNode)
 39     {
 40         $totalNode=array();
 41         foreach ($realNode as $v) 
 42         {
 43             for($i=0; $i<$virtualNode; $i++)
 44             {
 45                 $hashNode=$this->hash($v.'-'.$i);
 46                 $totalNode[$hashNode]=$v;
 47             }
 48         }
 49         ksort($totalNode);     #按照索引进行排序,升序
 50         return $totalNode;
 51     }
 52 
 53     /**
 54     * @desc 获取key的真实存储节点
 55     * 
 56     * @param $key string | key字符串
 57     *
 58     * @return string 返回真实节点
 59     */
 60     private function getNode($key)
 61     {
 62         $totalNode=$this->dealNode($this->realNode, $this->virtualNode);    #获取所有虚拟节点
 63         /* #查看虚拟节点总数
 64         echo "<pre>";
 65         print_r($totalNode);
 66         echo "</pre>";die;
 67         */
 68         $hashNode=$this->hash($key);            #key的哈希节点
 69         foreach ($totalNode as $k => $v)        #循环总结点环查找
 70         {
 71             if($k >= $hashNode)                 #查找第一个大于key哈希节点的值
 72             {
 73                 return $v;                      #返回真实节点
 74             }
 75         }
 76         return reset($totalNode);               #假若总节点环的值都比key哈希节点小,则返回第一个总哈希环的value值
 77     }
 78 
 79     /**
 80     * @desc 返回memcached对象
 81     *
 82     * @param $key string | key值
 83     *
 84     * @return object
 85     */
 86     private function getMemcached($key)
 87     {
 88         $node=$this->getNode($key);             #获取真实节点
 89         echo  $key.'真实节点:'.$node.'<br/>'; #测试使用,查看key的真实节点
 90         $host=$this->servers[$node]['host'];    #服务器池中某台服务器host
 91         $port=$this->servers[$node]['port'];    #服务器池中某台服务器port
 92         $m= new memcached();                    #实例化
 93         $m->addserver($host, $port);            #添加memcache服务器
 94         return $m;                              #返回memcached对象
 95     }
 96 
 97     /**
 98     * @desc 设置key-value值
 99     */
100     public function setKey($key, $value)
101     {
102         $m=$this->getMemcached($key);
103         return $m->set($key, $value);
104     }
105 
106     /**
107     * @desc 获取key中的value
108     */
109     public function getKey($key)
110     {
111         $m=$this->getMemcached($key);
112         return $m->get($key);
113     }
114 
115 
116 }
117 
118 ?>

3)、测试

1、查看全部虚拟节点

一共64*三=①315个虚拟节点(虚拟节点设置照旧属于偏少的,一般都会安装在拾0~200)

亚洲必赢官网 8

亚洲必赢官网 9

2、set测试

 1 include './ConsistentHashMemcache.class.php';
 2 header("content-type: text/html;charset=utf8;");
 3 $arr=array(
 4     'node1'=>array('host'=>'192.168.95.11', 'port'=>'11210'),
 5     'node2'=>array('host'=>'192.168.95.11', 'port'=>'11211'),
 6     'node3'=>array('host'=>'192.168.95.11', 'port'=>'11212'),
 7     );
 8 
 9 $c=new ConsistentHashMemcache($arr);
10 
11 #测试set
12 $c->setKey('aaa', '11111');
13 $c->setKey('bbb', '22222');
14 $c->setKey('ccc', '33333');

 

亚洲必赢官网 10

分别telnet连接192.168.95.11:(11210、11211、11212)

在节点node第11中学get(‘aaa’)、get(‘bbb’)能取到值

在节点node三中get(‘ccc’)能取到值

3、get测试

 1 include './ConsistentHashMemcache.class.php';
 2 header("content-type: text/html;charset=utf8;");
 3 $arr=array(
 4     'node1'=>array('host'=>'192.168.95.11', 'port'=>'11210'),
 5     'node2'=>array('host'=>'192.168.95.11', 'port'=>'11211'),
 6     'node3'=>array('host'=>'192.168.95.11', 'port'=>'11212'),
 7     );
 8 
 9 $c=new ConsistentHashMemcache($arr);
10 #测试get
11 echo $c->getKey('aaa').'<br/>';
12 echo $c->getKey('bbb').'<br/>';
13 echo $c->getKey('ccc').'<br/>';

亚洲必赢官网 11

4、优缺点

  相对于取模格局遍及式,一致性哈希方式布满式的代码复杂性要高级中学一年级些,但那也在尚可的限量内,不构成任何拦截难题。相反它的亮点就十分醒目,通过编造节点的法子贯彻,能够使不可控的积攒节点能够尽恐怕的均匀遍及在圆环上,从而到达数据均匀缓存在种种主机里。其次扩展与删除虚拟节点对于在此之前缓存的完全部据影响非常小。

 

(以上是上下一心的1对思想与总括,若有欠缺大概失实的地方请各位建议)

作者:那一叶随风

扬言:以上只表示自己在干活学习中某一时半刻间内总计的视角或结论。转发时请在篇章页面明显地方给出原来的书文链接

 

2、取模算法格局

  何为取模算法情势遍及式?正是将key转变为33人的数字,并与memcached服务器的总量举办相除获得余数。而那些余数正是memcached服务器的节点node。有了那些node大家就足以分明memcached服务器,就能够发送命令给memcached试行了。

图示解析:

亚洲必赢官网 12

方方面面经过上海体育地方所示。

1)、PHP代码实现

GetModMemcache.class.php

 1 <?php
 2 #分布式memcache(取模计算)
 3 class GetModMemcache
 4 {
 5     private $total=‘‘;          #存储memcache服务器的总数
 6     private $servers=array();   #存储memcache服务器的具体信息
 7     /**
 8     * @desc 构造函数
 9     *
10     * @param $serversArr array | memcache服务器具体信息
11     */
12     public function __construct($serversArr)
13     {
14         $this->total=count($serversArr);
15         $this->servers=$serversArr;
16     }
17 
18     /**
19     * @desc 计算$key的存储位置(即哪个服务器)
20     * 
21     * @param string | key字符串
22     *
23     * @return int  返回第几个服务器
24     */
25     protected function position($key)
26     {
27         #使用crc32(),将字符串转化为32为的数字
28         return sprintf(‘%u‘,crc32($key))%$this->total;      #取余
29     }
30 
31     /**
32     * @desc 获取memcached对象
33     *
34     * @param $position int | key的位置信息
35     *
36     * @return object 返回实例化memcached对象
37     */
38     protected function getMemcached($position)
39     {
40         $host=$this->servers[$position][‘host‘];    #服务器池中某台服务器host
41         $port=$this->servers[$position][‘port‘];    #服务器池中某台服务器port
42         $m= new memcached();
43         $m->addserver($host, $port);
44         return $m; 
45     }
46 
47     /**
48     * @desc 设置key-value值
49     *
50     * @param string | key字符串
51     * @param mixed  | 值可以是任何有效的非资源型php类型
52     *
53     * @return 返回结果
54     */
55     public function setKey($key, $value)
56     {
57         $num=$this->position($key);
58         echo $num;      #调试用
59         $m=$this->getMemcached($num);   #获取memcached对象
60         return $m->set($key, $value);
61     }
62 
63     public function getKey($key)
64     {
65         $num=$this->position($key);
66         $m=$this->getMemcached($num);
67         return $m->get($key);
68     }
69 
70 
71 }
72 
73 
74 $arr=array(
75     array(‘host‘=>‘192.168.95.11‘, ‘port‘=>‘11210‘),
76     array(‘host‘=>‘192.168.95.11‘, ‘port‘=>‘11211‘),
77     array(‘host‘=>‘192.168.95.11‘, ‘port‘=>‘11212‘),
78     );
79 $mod=new GetModMemcache($arr);
80 
81 /*
82 #存储数据
83 $a=$mod->setKey(‘key3‘, ‘key33333‘);
84 echo "<pre>";
85 print_r($a);
86 echo "</pre>";die;
87 */
88 /*
89 #获取数据
90 $b=$mod->getKey(‘key1‘);
91 echo "<pre>";
92 print_r($b);
93 echo "</pre>";die;
94 */
95 ?>

 

二)、进行对应测试

  一、接二连三插入八个数据

  #set(‘key1’,’value11111’);  #node=1

  #set(‘key2’,’value22222’);  #node=1

  #set(‘key3’,’value33333’;)  #node=0

  2、分别telnet连接192.168.95.11:(11210、11211、11212)

  11210含有key3数据

  11211含有key1、key2数据

  11212不含数据

  三、使用程序get数据

  结果都可以将数据抽取来

3)、优缺点

  优点:

  一、简单实用易精晓

  2、数据遍布均匀

  缺点:

  1、宕了壹台memcached服务器时不能够自动调度群组去处理数据,使有个别数额不能够选用缓存,一贯频频从数据库中获取数据。

  2、当必要扩大容积的时候,增添多台memcached服务器,那么原来已经缓存的多少大大多都不可见被打中,即数据无用。

 

壹、memcached分布式简单介绍

  memcached就算称之为“布满式”缓存服务器,但劳动器端并未“布满式”作用。Memcache集群主机不可能互相通信传输数据,它的“布满式”是基于客户端的程序逻辑算法进一步完结的。

请看上边简图:

亚洲必赢官网 13

基于上航海用图书馆大家简述分析分布式memcached的set与get的进度

set过程:

一、首先通过应用程序set(‘key’,’value’)

2、进入程序,使用key通过逻辑算法得出这一个key必要仓库储存的节点位置

三、依据节点地点再而三相应的memcached服务器,并发送set命令

get过程:

一、首先通过应用程序get(‘key’)

二、接着使用该key通过逻辑算法获取该key的积累节点

三、依据节点连接相应的memcached服务器,并发送get命令

  完结memcached有很三种方法,个中最常用的就是一样哈希理念的遍布式(就简称为一样哈希分布式啦)。好的事物自然须求次劣质商品来搭配它的帮助和益处啦,由此在这里除了教学1致哈希分布式,还会讲到取模分布式。从而特别分析他们的利害。

  这里的例证都会选择PHP代码落成,当然啦,最注重的是思想与格局嘛!毕竟那两样东西在别的语言中都以相通的。

回去顶部

③、一致哈希算法格局

何为一致哈希算法情势遍布式呢?

  想象一下,将三十四人的有着数字从小到大按顺时针分布在二个圆环上;

  其次,将每一种存款和储蓄节点赋予三个名字,并透过crc3二函数将其转移为三十二人的数字,此数字便是该memcached服务器的仓库储存节点

  接着,将key也经过crc3二函数转换为三10位的数字,它的所在地方按顺时针方向走先是个境遇的贮存节点所对应的memcached服务器正是该key的末尾存款和储蓄服务器。

1)、图像分析

亚洲必赢官网 14

  假使node一节点服务器挂了,依据按顺时针近期口径,那么原来存款和储蓄在node一节点的多少此时也可存储在node三节点中。

  假使有扩大体量的内需,扩大的两台memcached服务器,又将会怎么啊?请看下图分析

亚洲必赢官网 15

结果显示只有为数不许多额会见临震慑,相对于全部数据以来那几个影响依旧在可承受的限制内。

  从下面的图示大家得以很轻巧发掘存在那样个缺陷,就是使用crc32函数大家不能够垄断(monopoly)memcached存款和储蓄节点的具体地点,并且节点的总量据相对于2的34次方是突显多么的不起眼。倘若恰好即便那多少个存款和储蓄节点都距离的分外近呢,那么早晚有3个memcached服务器承受绝大许多的数码缓存。

请看下图分析:

亚洲必赢官网 16

化解办法:

  将三个真正存款和储蓄节点映射为七个虚拟存款和储蓄节点,即真实节点+后缀再经过crc3二管理(举个例子:node1_1、node1_2、node1_3、…..、node1_n)

看下图节点布满:

  多少个实际节点在圆环上就改成了二十五个存款和储蓄节点,那样就能够制止存款和储蓄节点相距太近而招致数据缓存布满不均匀的标题了,而且蕴藏机制尚未别的变化。

亚洲必赢官网 17

二)、PHP代码达成

ConsistentHashMemcache.class.php

  1 <?php
  2 #分布式memcache 一致性哈希算法(采用环状数据结构)
  3 class ConsistentHashMemcache
  4 {
  5     private $virtualNode=‘‘;      #用于存储虚拟节点个数
  6     private $realNode=array();    #用于存储真实节点
  7     private $servers=array();      #用于存储memcache服务器信息
  8     #private $totalNode=array();   #节点总数
  9     /**
 10     * @desc 构造函数
 11     *
 12     * @param $servers array    | memcache服务器的信息
 13     * @param $virtualNode int | 虚拟节点个数,默认64个
 14     */
 15     public function __construct($servers, $virtualNode=64)
 16     {
 17         $this->servers=$servers;
 18         $this->realNode=array_keys($servers);
 19         $this->virtualNode=$virtualNode;
 20     }
 21 
 22     /**
 23     * @return int 返回32位的数字
 24     */
 25     private function hash($str)
 26     {
 27         return sprintf(‘%u‘,crc32($str));   #将字符串转换为32位的数字
 28     }
 29 
 30     /**
 31     * @desc 处理节点
 32     *
 33     * @param $realNode     array | 真实节点 
 34     * @param $virturalNode int   | 虚拟节点个数
 35     *
 36     * @return array 返回所有节点信息
 37     */
 38     private function dealNode($realNode, $virtualNode)
 39     {
 40         $totalNode=array();
 41         foreach ($realNode as $v) 
 42         {
 43             for($i=0; $i<$virtualNode; $i++)
 44             {
 45                 $hashNode=$this->hash($v.‘-‘.$i);
 46                 $totalNode[$hashNode]=$v;
 47             }
 48         }
 49         ksort($totalNode);     #按照索引进行排序,升序
 50         return $totalNode;
 51     }
 52 
 53     /**
 54     * @desc 获取key的真实存储节点
 55     * 
 56     * @param $key string | key字符串
 57     *
 58     * @return string 返回真实节点
 59     */
 60     private function getNode($key)
 61     {
 62         $totalNode=$this->dealNode($this->realNode, $this->virtualNode);    #获取所有虚拟节点
 63         /* #查看虚拟节点总数
 64         echo "<pre>";
 65         print_r($totalNode);
 66         echo "</pre>";die;
 67         */
 68         $hashNode=$this->hash($key);            #key的哈希节点
 69         foreach ($totalNode as $k => $v)        #循环总结点环查找
 70         {
 71             if($k >= $hashNode)                 #查找第一个大于key哈希节点的值
 72             {
 73                 return $v;                      #返回真实节点
 74             }
 75         }
 76         return reset($totalNode);               #假若总节点环的值都比key哈希节点小,则返回第一个总哈希环的value值
 77     }
 78 
 79     /**
 80     * @desc 返回memcached对象
 81     *
 82     * @param $key string | key值
 83     *
 84     * @return object
 85     */
 86     private function getMemcached($key)
 87     {
 88         $node=$this->getNode($key);             #获取真实节点
 89         echo  $key.‘真实节点:‘.$node.‘<br/>‘; #测试使用,查看key的真实节点
 90         $host=$this->servers[$node][‘host‘];    #服务器池中某台服务器host
 91         $port=$this->servers[$node][‘port‘];    #服务器池中某台服务器port
 92         $m= new memcached();                    #实例化
 93         $m->addserver($host, $port);            #添加memcache服务器
 94         return $m;                              #返回memcached对象
 95     }
 96 
 97     /**
 98     * @desc 设置key-value值
 99     */
100     public function setKey($key, $value)
101     {
102         $m=$this->getMemcached($key);
103         return $m->set($key, $value);
104     }
105 
106     /**
107     * @desc 获取key中的value
108     */
109     public function getKey($key)
110     {
111         $m=$this->getMemcached($key);
112         return $m->get($key);
113     }
114 
115 
116 }
117 
118 ?>

3)、测试

一、查看全体虚拟节点

一共64*叁=一3十三个虚拟节点(虚拟节点设置照旧属于偏少的,一般都会安装在拾0~200)

亚洲必赢官网 18

亚洲必赢官网 19

2、set测试

 1 include ‘./ConsistentHashMemcache.class.php‘;
 2 header("content-type: text/html;charset=utf8;");
 3 $arr=array(
 4     ‘node1‘=>array(‘host‘=>‘192.168.95.11‘, ‘port‘=>‘11210‘),
 5     ‘node2‘=>array(‘host‘=>‘192.168.95.11‘, ‘port‘=>‘11211‘),
 6     ‘node3‘=>array(‘host‘=>‘192.168.95.11‘, ‘port‘=>‘11212‘),
 7     );
 8 
 9 $c=new ConsistentHashMemcache($arr);
10 
11 #测试set
12 $c->setKey(‘aaa‘, ‘11111‘);
13 $c->setKey(‘bbb‘, ‘22222‘);
14 $c->setKey(‘ccc‘, ‘33333‘);

 

亚洲必赢官网 20

分别telnet连接192.168.95.11:(11210、11211、11212)

在节点node第11中学get(‘aaa’)、get(‘bbb’)能取到值

在节点node三中get(‘ccc’)能取到值

3、get测试

 1 include ‘./ConsistentHashMemcache.class.php‘;
 2 header("content-type: text/html;charset=utf8;");
 3 $arr=array(
 4     ‘node1‘=>array(‘host‘=>‘192.168.95.11‘, ‘port‘=>‘11210‘),
 5     ‘node2‘=>array(‘host‘=>‘192.168.95.11‘, ‘port‘=>‘11211‘),
 6     ‘node3‘=>array(‘host‘=>‘192.168.95.11‘, ‘port‘=>‘11212‘),
 7     );
 8 
 9 $c=new ConsistentHashMemcache($arr);
10 #测试get
11 echo $c->getKey(‘aaa‘).‘<br/>‘;
12 echo $c->getKey(‘bbb‘).‘<br/>‘;
13 echo $c->getKey(‘ccc‘).‘<br/>‘;

亚洲必赢官网 21

4、优缺点

  相对于取模格局遍及式,一致性哈希格局遍布式的代码复杂性要高级中学一年级些,但那也在还行的范围内,不构成任何阻拦难点。相反它的优点就充裕显眼,通过编造节点的不二等秘书技贯彻,能够使不可控的积攒节点能够尽量的均匀遍及在圆环上,从而落成多少均匀缓存在种种主机里。其次扩展与删除虚拟节点对于在此以前缓存的总体数量影响一点都非常的小。

 

亚洲必赢官网 ,二、取模算法形式

  何为取模算法格局分布式?正是将key调换为三十几人的数字,并与memcached服务器的总额举行相除获得余数。而以此余数便是memcached服务器的节点node。有了那么些node大家就足以明显memcached服务器,就能够发送命令给memcached实施了。

图示解析:

亚洲必赢官网 22

全套经过上图所示。

1)、PHP代码达成

GetModMemcache.class.php

亚洲必赢官网 23

 1 <?php 2 #分布式memcache 3 class GetModMemcache 4 { 5     private $total='';          #存储memcache服务器的总数 6     private $servers=array();   #存储memcache服务器的具体信息 7     /** 8     * @desc 构造函数 9     *10     * @param $serversArr array | memcache服务器具体信息11     */12     public function __construct($serversArr)13     {14         $this->total=count($serversArr);15         $this->servers=$serversArr;16     }17 18     /**19     * @desc 计算$key的存储位置20     * 21     * @param string | key字符串22     *23     * @return int  返回第几个服务器24     */25     protected function position($key)26     {27         #使用crc32(),将字符串转化为32为的数字28         return sprintf('%u',crc32($key))%$this->total;      #取余29     }30 31     /**32     * @desc 获取memcached对象33     *34     * @param $position int | key的位置信息35     *36     * @return object 返回实例化memcached对象37     */38     protected function getMemcached($position)39     {40         $host=$this->servers[$position]['host'];    #服务器池中某台服务器host41         $port=$this->servers[$position]['port'];    #服务器池中某台服务器port42         $m= new memcached();43         $m->addserver($host, $port);44         return $m; 45     }46 47     /**48     * @desc 设置key-value值49     *50     * @param string | key字符串51     * @param mixed  | 值可以是任何有效的非资源型php类型52     *53     * @return 返回结果54     */55     public function setKey($key, $value)56     {57         $num=$this->position($key);58         echo $num;      #调试用59         $m=$this->getMemcached($num);   #获取memcached对象60         return $m->set($key, $value);61     }62 63     public function getKey($key)64     {65         $num=$this->position($key);66         $m=$this->getMemcached($num);67         return $m->get($key);68     }69 70 71 }72 73 74 $arr=array(75     array('host'=>'192.168.95.11', 'port'=>'11210'),76     array('host'=>'192.168.95.11', 'port'=>'11211'),77     array('host'=>'192.168.95.11', 'port'=>'11212'),78     );79 $mod=new GetModMemcache($arr);80 81 /*82 #存储数据83 $a=$mod->setKey('key3', 'key33333');84 echo "<pre>";85 print_r;86 echo "</pre>";die;87 */88 /*89 #获取数据90 $b=$mod->getKey;91 echo "<pre>";92 print_r;93 echo "</pre>";die;94 */95 ?>

亚洲必赢官网 24

二)、进行相应测试

  壹、延续插入四个数据

  #set(‘key1’,’value11111’); #node=1

  #set(‘key2’,’value22222’); #node=1

  #set(‘key3’,’value33333’;) #node=0

  2、分别telnet连接192.168.95.11:(11210、11211、11212)

  11210含有key3数据

  11211含有key1、key2数据

  1121二不含数据

  3、使用程序get数据

  结果都能够将数据抽出来

3)、优缺点

  优点:

  一、简单实用易掌握

  二、数据布满均匀

  缺点:

  1、宕了一台memcached服务器时不可能半自动调度群组去管理数量,使一些数额无法应用缓存,平昔持续从数据库中获取数据。

  2、当须要扩大容积的时候,增增添台memcached服务器,那么原来早就缓存的多少大诸多都不可见被击中,即数据无用。

回到顶部

3、一致哈希算法方式

何为1致哈希算法形式遍布式呢?

  想象一下,将3二位的有着数字从小到大按顺时针分布在3个圆环上;

  其次,将各种存款和储蓄节点赋予二个名字,并由此crc32函数将其改动为三十二位的数字,此数字正是该memcached服务器的贮存节点

  接着,将key也透过crc3二函数调换为33位的数字,它的所在地点按顺时针方向走先是个碰着的存款和储蓄节点所对应的memcached服务器便是该key的末段存款和储蓄服务器。

1)、图像分析

亚洲必赢官网 25

  假若node一节点服务器挂了,依据按顺时针方今条件,那么原来存款和储蓄在node一节点的数据此时也可存款和储蓄在node3节点中。

  若是有扩大容积的急需,扩张的两台memcached服务器,又将会怎么啊?请看下图分析

亚洲必赢官网 26

结果显示只有为数不繁多目会受到震慑,相对于全体数据的话这几个潜移默化或许在可接受的界定内。

  从地点的图示大家能够很轻松发掘存在那样个缺陷,便是使用crc3二函数大家不可能操纵memcached存款和储蓄节点的具体地方,并且节点的总量据相对于二的三十遍方是体现多么的不起眼。假诺恰好即便这多少个存款和储蓄节点都距离的十二分近呢,那么势必有2个memcached服务器承受绝大大多的数据缓存。

请看下图分析:

亚洲必赢官网 27

化解办法:

  将2个忠实存款和储蓄节点映射为多个虚拟存款和储蓄节点,即真实节点+后缀再经过crc3二管理(举例:node1_1、node1_2、node1_3、…..、node1_n)

看下图节点布满:

  四个真实节点在圆环上就变成了215个存款和储蓄节点,那样就可以防止存款和储蓄节点相距太近而导致数据缓存分布不均匀的难点了,而且蕴藏机制未有其余变动。

亚洲必赢官网 28

2)、PHP代码实现

ConsistentHashMemcache.class.php

亚洲必赢官网 29

  1 <?php  2 #分布式memcache 一致性哈希算法  3 class ConsistentHashMemcache  4 {  5     private $virtualNode='';      #用于存储虚拟节点个数  6     private $realNode=array();    #用于存储真实节点  7     private $servers=array();      #用于存储memcache服务器信息  8     #private $totalNode=array();   #节点总数  9     /** 10     * @desc 构造函数 11     * 12     * @param $servers array    | memcache服务器的信息 13     * @param $virtualNode int | 虚拟节点个数,默认64个 14     */ 15     public function __construct($servers, $virtualNode=64) 16     { 17         $this->servers=$servers; 18         $this->realNode=array_keys($servers); 19         $this->virtualNode=$virtualNode; 20     } 21  22     /** 23     * @return int 返回32位的数字 24     */ 25     private function hash($str) 26     { 27         return sprintf('%u',crc32($str));   #将字符串转换为32位的数字 28     } 29  30     /** 31     * @desc 处理节点 32     * 33     * @param $realNode     array | 真实节点  34     * @param $virturalNode int   | 虚拟节点个数 35     * 36     * @return array 返回所有节点信息 37     */ 38     private function dealNode($realNode, $virtualNode) 39     { 40         $totalNode=array(); 41         foreach ($realNode as $v)  42         { 43             for($i=0; $i<$virtualNode; $i++) 44             { 45                 $hashNode=$this->hash($v.'-'.$i); 46                 $totalNode[$hashNode]=$v; 47             } 48         } 49         ksort($totalNode);     #按照索引进行排序,升序 50         return $totalNode; 51     } 52  53     /** 54     * @desc 获取key的真实存储节点 55     *  56     * @param $key string | key字符串 57     * 58     * @return string 返回真实节点 59     */ 60     private function getNode($key) 61     { 62         $totalNode=$this->dealNode($this->realNode, $this->virtualNode);    #获取所有虚拟节点 63         /* #查看虚拟节点总数 64         echo "<pre>"; 65         print_r($totalNode); 66         echo "</pre>";die; 67         */ 68         $hashNode=$this->hash($key);            #key的哈希节点 69         foreach ($totalNode as $k => $v)        #循环总结点环查找 70         { 71             if($k >= $hashNode)                 #查找第一个大于key哈希节点的值 72             { 73                 return $v;                      #返回真实节点 74             } 75         } 76         return reset($totalNode);               #假若总节点环的值都比key哈希节点小,则返回第一个总哈希环的value值 77     } 78  79     /** 80     * @desc 返回memcached对象 81     * 82     * @param $key string | key值 83     * 84     * @return object 85     */ 86     private function getMemcached($key) 87     { 88         $node=$this->getNode($key);             #获取真实节点 89         echo  $key.'真实节点:'.$node.'<br/>'; #测试使用,查看key的真实节点 90         $host=$this->servers[$node]['host'];    #服务器池中某台服务器host 91         $port=$this->servers[$node]['port'];    #服务器池中某台服务器port 92         $m= new memcached();                    #实例化 93         $m->addserver($host, $port);            #添加memcache服务器 94         return $m;                              #返回memcached对象 95     } 96  97     /** 98     * @desc 设置key-value值 99     */100     public function setKey($key, $value)101     {102         $m=$this->getMemcached($key);103         return $m->set($key, $value);104     }105 106     /**107     * @desc 获取key中的value108     */109     public function getKey($key)110     {111         $m=$this->getMemcached($key);112         return $m->get($key);113     }114 115 116 }117 118 ?>

亚洲必赢官网 30

3)、测试

一、查看全数虚拟节点

一共64*三=13三个虚拟节点(虚拟节点设置依然属于偏少的,一般都会安装在100~200)

亚洲必赢官网 31

亚洲必赢官网 32

2、set测试

亚洲必赢官网 33

 1 include './ConsistentHashMemcache.class.php'; 2 header("content-type: text/html;charset=utf8;"); 3 $arr=array( 4     'node1'=>array('host'=>'192.168.95.11', 'port'=>'11210'), 5     'node2'=>array('host'=>'192.168.95.11', 'port'=>'11211'), 6     'node3'=>array('host'=>'192.168.95.11', 'port'=>'11212'), 7     ); 8  9 $c=new ConsistentHashMemcache($arr);10 11 #测试set12 $c->setKey('aaa', '11111');13 $c->setKey('bbb', '22222');14 $c->setKey('ccc', '33333');

亚洲必赢官网 34

亚洲必赢官网 35

分别telnet连接192.168.95.11:(11210、11211、11212)

在节点node第11中学get(‘aaa’)、get(‘bbb’)能取到值

在节点node三中get(‘ccc’)能取到值

3、get测试

亚洲必赢官网 36

 1 include './ConsistentHashMemcache.class.php'; 2 header("content-type: text/html;charset=utf8;"); 3 $arr=array( 4     'node1'=>array('host'=>'192.168.95.11', 'port'=>'11210'), 5     'node2'=>array('host'=>'192.168.95.11', 'port'=>'11211'), 6     'node3'=>array('host'=>'192.168.95.11', 'port'=>'11212'), 7     ); 8  9 $c=new ConsistentHashMemcache($arr);10 #测试get11 echo $c->getKey.'<br/>';12 echo $c->getKey.'<br/>';13 echo $c->getKey.'<br/>';

亚洲必赢官网 37

亚洲必赢官网 38

4、优缺点

  相对于取模方式布满式,1致性哈希形式遍布式的代码复杂性要高级中学一年级些,但那也在还不错的限制内,不结合任何拦截难题。相反它的独到之处就那多少个强烈,通过编造节点的办法贯彻,能够使不可控的囤积节点能够尽量的均匀布满在圆环上,从而达到多少均匀缓存在各类主机里。其次增加与删除虚拟节点对于以前缓存的完整数量影响相当小。

(以上是友好的片段眼光与总括,若有欠缺恐怕失实的地点请各位提议)

扬言:以上只象征自个儿在干活学习中某一时间内总计的观点或结论。转发时请在篇章页面明显地点给出原来的作品链接

转发地址:

网站地图xml地图