memcached六:分布式集群算法
memcached本身不是分布式缓存;所谓memcached的分布式缓存,是由用户自己定义的。而且多个memcached节点之间互不通信。
所以,它本身不是分布式的。
假设有30万个key,有10台memcached服务器,我们该怎么将这30万个key放在10台服务上?
根据一致性哈希算法,来分配。
一致性哈希算法:将各服务器节点映射到钟表的各个时刻上;把key也映射到钟表的某个时刻上;
该key沿钟表顺时针走,碰到的第1个节点,即为该key的存储点。
各服务器节点和key,都是根据某种相同的规则,转化为整数。
down机示例:
假设有N个节点memcached服务器,当2号节点down,该查找2号节点的key,转到下一节点3号节点上查找;此时只会影响2号节点的key不会被命中,其它节点不受影响;因此整体命中率只减少1/N。
这样做的影响,将减到最少。
但是压力都在3号节点上。进一步优化:将其压力均匀分布到其它节点。
各节点的key不一定负载相近。进一步优化:引入虚拟节点。
虚拟节点:N个真实节点,把每个真实节点映射成M个虚拟节点,再把M*N个虚拟节点散列在圆环上。
各真实节点对应的虚拟节点相互交错分布。
这样,当某真实节点down之后,则把其影响平均分担到其它所有节点上。
用PHP代码实现基于取余的分布式算法:
# 计算某个键的hash interface hasher { public function _hash($str) } # 计算某个键应该存放的圆盘位置 interface distribution { public function lookup($key); } class Moder implements haser, distribution { protected $_server = []; protected $_serverNum = 0 public function _hash($str) { return sprintf('%u', crc32($str)); # 将一个字符串,转化为一个有符号数字 } public function lookup ($key) { $index = $this->_hash(&key) % $this->_serverNum; return $this->_server[$index]; } public function addNode($s) { $this->_server[] = $s; $this-> _serverNum += 1; } public function delNode($s) { foreach($this->_server as $k=$v) { if($s == $v) { unset($this->_server[$k]; $this->_serverNum -=1; } } $this->_server = array_merge($this->_server; #重新排列数组 } }
$moder = new moder(); $moder->addNode('a'); $moder->addNode('b'); $moder->addNode('c'); $moder->addNode('d'); for($i=1;$i<=100;$i++) { $key = 'key_'.$i; echo $key , '--> ' , $moder->lookup($key), "\n"; }
用PHP实现基于一致性哈希的分布式算法:
# 计算某个键的hash interface hasher { public function _hash($str) } # 计算某个键应该存放的圆盘位置 interface distribution { public function lookup($key); } class Moder implements haser, distribution { protected $nodes = []; protected $points = []; protected $_mul = 64; public function _hash($str) { return sprintf('%u', crc32($str)); # 将一个字符串,转化为一个有符号数字 } public function lookup($key) { $position = $this->_hash($key);
reset($this->points); $neddle = key($this->points) foreach($this->points as $p=>$v) { if($p >= $postion) { $neddle = $p; break; } return $this->points[$p]; } } public function addNode($node){ $this->nodes[$node] = []; for($i=0;$i<$this->_mul;$i+=1) { $point = $node . '_' . $i; $point = $this->_hash($point); //虚拟节点转化为数字 $this->points[$point] = $node; $this->nodes[$node][] = $point; //虚拟节点与真实节点建立对应关系 } $this->resort(); } protected function resort() { ksort($this->points); } public function delNone($node) { //删除64个虚拟节点 foreach($this->nodes[$node] as $p) { unset($this->points[$p]); } unset($this->nodes[$node]); //删除真实节点 } }
图表展示工具:http://www.hcharts.cn/
posted on 2018-08-19 16:36 myworldworld 阅读(111) 评论(0) 收藏 举报
浙公网安备 33010602011771号