设为首页 加入收藏

TOP

memcache 分布式缓存(二)
2017-10-10 10:21:04 】 浏览:3617
Tags:memcache 分布式
经缓存的数据大多数都不能够被命中,即数据无用。

 

3、一致哈希算法方式

何为一致哈希算法方式分布式呢?

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

  其次,将每个存储节点赋予一个名字,并通过crc32函数将其转换为32位的数字,此数字就是该memcached服务器的存储节点

  接着,将key也通过crc32函数转换为32位的数字,它的所在位置按顺时针方向走第一个遇到的存储节点所对应的memcached服务器就是该key的最终存储服务器。

1)、图像解析

技术分享

  假设node1节点服务器挂了,根据按顺时针最近原则,那么原本存储在node1节点的数据此时也可存储在node3节点中。

  假设有扩容的需要,增加的两台memcached服务器,又将会怎么样呢?请看下图分析

技术分享

结果显示只有少量数据会受到影响,相对于整体数据来说这些影响还是在可接受的范围内。

  从上面的图示我们可以很容易发现存在这么个缺点,即是使用crc32函数我们不能控制memcached存储节点的具体位置,并且节点的总数量相对于2的32次方是显得多么的渺小。假若恰好即使这几个存储节点都距离的非常近呢,那么必将有一个memcached服务器承受绝大多数的数据缓存。

请看下图分析:

技术分享

解决办法:

  将一个真实存储节点映射为多个虚拟存储节点,即真实节点+后缀再通过crc32处理(例如:node1_1、node1_2、node1_3、…..、node1_n)

看下图节点分布:

  三个真实节点在圆环上就变成了三十个存储节点,这样就可以避免存储节点相距太近而导致数据缓存分布不均匀的问题了,而且存储机制没有任何变化。

技术分享

2)、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->getMemca
首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇WAMP环境配置-Apache服务器的安装 下一篇WAMP环境配置-Apache服务器的安装

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目