Memcached 一致性hash分布式算法

  1 <?php
  2
  3     interface HashWay{
  4         public function hash($string);
  5     }
  6
  7     class Md5HashWay implements HashWay{
  8         public function hash($string){
  9             return md5($string,0,8);
 10         }
 11     }
 12
 13     class Crc32HashWay implements HashWay{
 14         public function hash($string){
 15             return crc32($string);
 16         }
 17     }
 18
 19     class HashException extends Exception{
 20
 21     }
 22
 23     class ConsistentHash{
 24         //每一台memcached服务器的虚拟节点个数
 25         private $_replicas = 64;
 26         //表示memcached服务器的数量
 27         private $_targetCount = 0;
 28         //虚拟节点散列用到的hash算法
 29         private $_hasher = null;
 30         //一台memcached服务器对应的虚拟节点
 31         private $_targetToPostion = array();
 32         //虚拟节点对应memcached
 33         private $_postionToTarget = array();
 34         //是否排序
 35         private $_postionToTargetSorted = false;
 36
 37
 38         //构造函数,确定hasher的方法,已经虚拟节点的个数
 39         public function __construct(HashWay $hash = null,$replicas = null){
 40             $this->_hasher = $hash ? $hash : new Crc32HashWay();
 41             if(!empty($replicas))$this->_replicas = intval($replicas);
 42         }
 43
 44         //增加一台服务器的操作
 45         public function addTarget($target){
 46             if(isset($this->targetToPostion[$target])){throw new HashException("$target exists");}
 47
 48             //如果这台服务器没有存在,则给这台服务器去生成虚拟节点
 49             for($i = 0 ; $i < $this->_replicas; $i++){
 50                 $postion = $this->_hasher->hash($target.$i);
 51                 //虚拟节点指向target
 52                 $this->_postionToTarget[$postion] = $target;
 53                 //每一个服务器对应的虚拟节点
 54                 $this->_targetToPostion[$target][] = $postion;
 55             }
 56
 57             $this->_targetCount++;
 58
 59             //每次增加memcached服务器过来,虚拟节点都会混乱,必须排序来解决问题
 60             $this->_postToTargetSorted = false;
 61             return $this;
 62         }
 63
 64         //增加多台memcached服务器
 65         public function addTargets($targets){
 66             if(is_array($targets) && !empty($targets)){
 67                 foreach ($targets as $key => $value) {
 68                     $this->addTarget($value);
 69                 }
 70             }
 71         }
 72
 73         //删除一台服务器的操作
 74         public function removeTarget($target){
 75             if(!isset($this->_targetToPostion[$target])){throw new HashException("$target not exists");}
 76
 77             //现在进行删除服务器的操作
 78             foreach ($this->_targetToPostion[$target] as $key => $value) {
 79                 //根据虚拟节点数组,来删除指向target的数组
 80                 if(isset($this->_postionToTarget[$value])){
 81                     unset($this->_postionToTarget[$value]);
 82                 }
 83             }
 84             unset($this->_targetToPostion[$target]);
 85             $this->_targetCount--;
 86             return $this;
 87         }
 88
 89
 90         //得到全部的memcached服务器
 91         public function getAllTargets(){
 92             return array_keys($this->_targetToPostion);
 93         }
 94
 95         //查找存储的服务器
 96         public function lookUp($resource){
 97             $result = $this->lookUpList($resource);
 98             return $this->_postionToTarget[current($result)];
 99         }
100
101         //lookup函数返回一个环,数组0表示的是顺时针最近的memcached服务器
102         public function lookUpList($resource){
103
104             if($this->_targetCount == 0){
105                 return array();
106             }
107
108             //如果只有一个服务器,则返回
109             if($this->_targetCount == 1){
110                 return array_unique(array_values($this->_postionToTarget));
111             }
112
113
114             //如果没有找到一个服务器
115             //1对虚拟节点进行排序
116             $this->_sortedPostToTargets();
117
118
119             //2对查找的resource进行hash
120             $hashresource = $this->_hasher->hash($resource);
121
122             //3对虚拟节点查找
123             $flag = false;
124             $result = array();
125
126             //4优先查找服务器,取得顺时针最近的服务器
127             foreach ($this->_postionToTarget as $key => $value) {
128                 if(!$flag && $key > $hashresource){
129                     $flag = true;
130                 }
131
132                 if($flag == true && !in_array($key,$result)){
133                     $result[] = $key;
134                 }
135
136                 if(count($result) == $this->_targetCount){
137                     return $result;
138                 }
139             }
140
141             //5如果没有在顺时针取得服务器,那就重新再来一遍
142             foreach ($this->_postionToTarget as $key => $value) {
143                 if(!in_array($key,$result)){
144                     $result[] = $key;
145                 }
146
147                 if(count($result) == $this->_targetCount){
148                     return $result;
149                 }
150             }
151
152             return $result;
153         }
154
155         //对虚拟节点进行排序
156         private function _sortedPostToTargets(){
157             if(!$this->_postionToTargetSorted){
158                 ksort($this->_postionToTarget,SORT_REGULAR);
159                 $this->_postionToTargetSorted = true;
160             }
161         }
162     }
163
164
165     $a = new ConsistentHash;
166     //添加了两台主机
167     $a->addTarget(‘192.168.1.1‘)->addTarget(‘192.168.1.2‘)->addTarget(‘192.168.1.3‘)->addTarget(‘192.168.1.4‘);
168     print_r($a->getAllTargets());
169
170     echo "<br/>";
171     $result = array();
172     for($i = 0; $i < 100 ; $i++){
173         if(!isset($result[$a->lookUp($i)])){
174             $result[$a->lookUp($i)] = 1;
175         }else{
176             $result[$a->lookUp($i)] ++;
177         }
178     }
179
180     print_r($result);
181
182 ?>Array ( [0] => 192.168.1.1 [1] => 192.168.1.2 [2] => 192.168.1.3 [3] => 192.168.1.4 ) Array ( [192.168.1.2] => 13 [192.168.1.1] => 44 [192.168.1.3] => 28 [192.168.1.4] => 15 )

  这边只是简单的代码实现,用于解决分布均衡问题

学习地址:http://blog.csdn.net/cywosp/article/details/23397179

     http://blog.sina.com.cn/s/blog_3fde8252010147j5.html

     好像忘记添加一个链接了,有原代码一致性hash的链接,我就是看懂,然后自己写了下,不喜勿喷。

    

时间: 2024-11-08 02:55:30

Memcached 一致性hash分布式算法的相关文章

php memcached 一致性hash

<?php /**  * 一致性hahs实现类  *   */ class FlexiHash{ /**  * var int  * 虚拟节点  */ private $_replicas = 200; /**  * 使用hash方法  */ private $_hasher = null; /**  * 真实节点计数器  *   */ private $_targetCount = 0; /**  * 位置对应节点,用户lookup中根据位置确定要访问的节点  */ private $_pos

分布式memcached学习(四)&mdash;&mdash; 一致性hash算法原理

    分布式一致性hash算法简介 当你看到"分布式一致性hash算法"这个词时,第一时间可能会问,什么是分布式,什么是一致性,hash又是什么.在分析分布式一致性hash算法原理之前,我们先来了解一下这几个概念. 分布式 分布式(distributed)是指在多台不同的服务器中部署不同的服务模块,通过远程调用协同工作,对外提供服务. 以一个航班订票系统为例,这个航班订票系统有航班预定.网上值机.旅客信息管理.订单管理.运价计算等服务模块.现在要以集中式(集群,cluster)和分布

分布式算法(一致性Hash算法)

一.分布式算法 在做服务器负载均衡时候可供选择的负载均衡的算法有很多,包括: 轮循算法(Round Robin).哈希算法(HASH).最少连接算法(Least Connection).响应速度算法(Response Time).加权法(Weighted )等.其中哈希算法是最为常用的算法. 典型的应用场景是: 有N台服务器提供缓存服务,需要对服务器进行负载均衡,将请求平均分发到每台服务器上,每台机器负责1/N的服务. 常用的算法是对hash结果取余数 (hash() mod N ):对机器编号

分布式缓存技术memcached学习系列(四)—— 一致性hash算法原理

文章主目录 分布式一致性hash算法简介 分布式一致性hash算法使用背景 环形hash空间 映射key到环形hash空间 映射server节点到hash空间 映射key到server节点 添加server节点 删除server节点 虚拟节点的引入 节点变化数据分流的问题 一致性hash算法与取模算法的比较 参考文档 回到顶部 分布式一致性hash算法简介 当你看到“分布式一致性hash算法”这个词时,第一时间可能会问,什么是分布式,什么是一致性,hash又是什么.在分析分布式一致性hash算法

memcached 分布式 一致性hash算法demo

一致性Hash分布算法分4个步骤:步骤1:将一个32位整数[0 ~ (2^32-1)]想象成一个环,0 作为开头,(2^32-1) 作为结尾,当然这只是想象.步骤2:通过Hash函数把KEY处理成整数.这样就可以在环上找到一个位置与之对应.步骤3:把Memcached服务器群映射到环上,使用Hash函数处理服务器对应的IP地址即可.步骤4:把数据映射到Memcached服务器上.查找一个KEY对应的Memcached服务器位置的方法如下:从当前KEY的位置,沿着圆环顺时针方向出发,查找位置离得最

一致性hash算法在memcached中的使用

一.概述 1.我们的memcacheclient(这里我看的spymemcache的源代码).使用了一致性hash算法ketama进行数据存储节点的选择.与常规的hash算法思路不同.仅仅是对我们要存储数据的key进行hash计算,分配到不同节点存储.一致性hash算法是对我们要存储数据的server进行hash计算,进而确认每一个key的存储位置.  2.常规hash算法的应用以及其弊端 最常规的方式莫过于hash取模的方式.比方集群中可用机器适量为N,那么key值为K的的数据请求非常easy

转: memcached Java客户端spymemcached的一致性Hash算法

转自:http://colobu.com/2015/04/13/consistent-hash-algorithm-in-java-memcached-client/ memcached Java客户端spymemcached的一致性Hash算法 最近看到两篇文章,一个是江南白衣的陌生但默默一统江湖的MurmurHash,另外一篇是张洋的一致性哈希算法及其在分布式系统中的应用.虽然我在项目中使用memcached的java客户端spymemcached好几年了,但是对它的一致性哈希算法的细节从来

(转) 一致性Hash算法在Memcached中的应用

前言 大家应该都知道Memcached要想实现分布式只能在客户端来完成,目前比较流行的是通过一致性hash算法来实现.常规的方法是将 server的hash值与server的总台数进行求余,即hash%N,这种方法的弊端是当增减服务器时,将会有较多的缓存需要被重新分配且会造成缓 存分配不均匀的情况(有可能某一台服务器分配的很多,其它的却很少). 今天分享一种叫做”ketama”的一致性hash算法,它通过虚拟节点的概念和不同的缓存分配规则有效的抑制了缓存分布不均匀,并最大限度地减少服务器增减时缓

一致性Hash算法(分布式算法)

一致性哈希算法是分布式系统中常用的算法,为什么要用这个算法? 比如:一个分布式存储系统,要将数据存储到具体的节点(服务器)上, 在服务器数量不发生改变的情况下,如果采用普通的hash再对服务器总数量取模的方法(如key%服务器总数量),如果期间有服务器宕机了或者需要增加服务器,问题就出来了. 同一个key经过hash之后,再与服务器总数量取模的结果跟之前的结果会不一样,这就导致了之前保存数据的丢失.因此,引入了一致性Hash(Consistent Hashing)分布算法 把数据用hash函数(