Memcache 分布式存储 【一致性Hash】crc32
class memcacheHash {
private $_node = array();
private $_nodeData = array();
private $_keyNode = 0;
private $_memcache = null;
//每个物理服务器生成虚拟节点个数 [注:节点数越多,cache分布的均匀性越好,同时set get操作时,也更耗资源,10台物理服务器,采用200较为合理]
private $_virtualNodeNum = 200;
private function __construct() {
/* 放入配置文件 */
$config = array(
'127.0.0.1:11211',
'127.0.0.1:11212',
'127.0.0.1:11213',
'127.0.0.1:11214',
'127.0.0.1:11215'
);
if (!$config) throw new Exception('Cache config NULL');
foreach ($config as $key => $value) {
for ($i = 0; $i < $this->_virtualNodeNum; $i++) {
$this->_node[sprintf("%u", crc32($value . '_' . $i))] = $value . '_' . $i;
}
}
ksort($this->_node);
}
private function __clone(){}
/**
* 单例,保证只有一个实例
*/
static public function getInstance() {
static $memcacheObj = null;
if (!is_object($memcacheObj)) {
$memcacheObj = new self();
}
return $memcacheObj;
}
/**
* 根据key做一致性hash后连接到一台物理memcache服务器
* @param string $key
*/
private function _connectMemcache($key) {
$this->_nodeData = array_keys($this->_node);
$this->_keyNode = sprintf("%u", crc32($key));
$nodeKey = $this->_findServerNode();
//如果超出环,从头再用二分法查找一个最近的,然后环的头尾做判断,取最接近的节点
if ($this->_keyNode > end($this->_nodeData)) {
$this->_keyNode -= end($this->_nodeData);
$nodeKey2 = $this->_findServerNode();
if (abs($nodeKey2 - $this->_keyNode) < abs($nodeKey - $this->_keyNode)) $nodeKey = $nodeKey2;
}
list($config, $num) = explode('_', $this->_node[$nodeKey]);
if (!$config) throw new Exception('Cache config Error');
if (!isset($this->_memcache[$config])) {
$this->_memcache[$config] = new Memcache;
list($host, $port) = explode(':', $config);
$this->_memcache[$config]->connect($host, $port);
}
return $this->_memcache[$config];
}
/**
* 采用二分法从虚拟memcache节点中查找最近的节点
* @param unknown_type $m
* @param unknown_type $b
*/
private function _findServerNode($m = 0, $b = 0) {
$total = count($this->_nodeData);
if ($total != 0 && $b == 0) $b = $total - 1;
if ($m < $b){
$avg = intval(($m+$b) / 2);
if ($this->_nodeData[$avg] == $this->_keyNode) return $this->_nodeData[$avg];
elseif ($this->_keyNode < $this->_nodeData[$avg] && ($avg-1 >= 0)) return $this->_findServerNode($m, $avg-1);
else return $this->_findServerNode($avg+1, $b);
}
if (abs($this->_nodeData[$b] - $this->_keyNode) < abs($this->_nodeData[$m] - $this->_keyNode)) return $this->_nodeData[$b];
else return $this->_nodeData[$m];
}
public function set($key, $value, $expire = 0) {
return $this->_connectMemcache($key)->set($key, json_encode($value), 0, $expire);
}
// 去重添加
public function add($key, $value, $expire = 0) {
return $this->_connectMemcache($key)->add($key, json_encode($value), 0, $expire);
}
public function get($key) {
return json_decode($this->_connectMemcache($key)->get($key), true);
}
public function delete($key) {
return $this->_connectMemcache($key)->delete($key);
}
}
$runData['BEGIN_TIME'] = microtime(true);
//测试一万次set加get
for($i=0;$i<10000;$i++) {
$key = md5(mt_rand());
$b = memcacheHash::getInstance()->set($key, time(), 10);
}
var_dump(number_format(microtime(true) - $runData['BEGIN_TIME'],6));
// 测试直接单台
$runData['BEGIN_TIME'] = microtime(true); $m= new Memcache;
$m->connect('127.0.0.1', 11211);
for($i=0;$i<10000;$i++) {
$key = md5(mt_rand());
$b = $m->set($key, time(), 0, 10);
}
var_dump(number_format(microtime(true) - $runData['BEGIN_TIME'],6));
总结:多台存储会慢一些。具体时间,请自行运行。
Memcache 分布式存储 【一致性Hash】crc32的更多相关文章
- memcache分布式 [一致性hash算法] 的php实现
最近在看一些分布式方面的文章,所以就用php实现一致性hash来练练手,以前一般用的是最原始的hash取模做分布式,当生产过程中添加或删除一台memcache都会造成数据的全部失效,一致性hash就是 ...
- memcache的一致性hash算法
<?php /** * 一致性哈希memcache分布式,采用的是虚拟节点的方式解决分布均匀性问题,查找节点采用二分法快速查找 * the last known user to change t ...
- memcache的一致性hash算法使用
一.概述 1.我们的memcache客户端(这里我看的spymemcache的源码),使用了一致性hash算法ketama进行数据存储节点的选择.与常规的hash算法思路不同,只是对我们要存储数据的k ...
- 关于memcache分布式一致性hash
consistent hashing 算法早在 1997 年就在论文 Consistent hashing and random trees 中被提出,目前在 cache 系统中应用越来越广泛: 1 ...
- tornado--SESSION框架,一致性hash,分布式存储
预备知识 tornado框架session要自己写 cookie存储在客户端浏览器上,session数据放在服务器上 session依赖cookie 扩展tornado,返回请求前自定义session ...
- Nginx+Memcache+一致性hash算法 实现页面分布式缓存(转)
网站响应速度优化包括集群架构中很多方面的瓶颈因素,这里所说的将页面静态化.实现分布式高速缓存就是其中的一个很好的解决方案... 1)先来看看Nginx负载均衡 Nginx负载均衡依赖自带的 ngx_h ...
- 【转】分布式存储和一致性hash
本文我将对一致性算法作介绍,同时谈谈自己对一致性hash和一般意义上的hash算法的区别 hash是什么 hash即hash算法,又称为散列算法,百度百科的定义是 哈希算法将任意长度的二进制值映射为较 ...
- php一致性hash性能测试(flexihash/memcache/memcached)
一致性hash的使用在PHP中有三种选择分别是原生的memcache扩展,memcached扩展,还有一个是网上比较流行的flexihash类. 最近有项目需要使用flexihash类操作memcac ...
- php 实现一致性hash 算法 memcache
散列表的应用 涉及到数据查找比对,首先考虑到使用HashSet.HashSet最大的好处就是实现查找时间复杂度为O(1).使用HashSet需要解决一个重要问题:冲突问题.对比研究了网上一些字符串哈希 ...
随机推荐
- Linux 常用命令九 tar
一.tar命令 tar命令用于打包,解包. gzip命令用于压缩,解压缩. bzip2命令用于压缩,解压缩. 这三个是在linux中常用的,还有一些不常用的. tar打包: wang@wang:~/w ...
- bzoj 4898: [Apio2017]商旅【Floyd+分数规划+二分】
其实并不会分数规划 因为要最大化 ans=总收益/总路程 ,所以考虑二分答案,找到一条 ans<=总收益/总路程 的回路.先预处理出d(i,j)为(i,j)最短路,w(i,j)为在i买某个物品在 ...
- bzoj 4822: [Cqoi2017]老C的任务【扫描线+树状数组+二维差分】
一个树状数组能解决的问题分要用树套树--还写错了我别是个傻子吧? 这种题还是挺多的,大概就是把每个矩形询问差分拆成四个点前缀和相加的形式(x1-1,y1-1,1)(x2.y2,1)(x1-1,y2,- ...
- 51nod 1119 机器人走方格 V2 【组合数学】
挺水的但是我好久没写组合数了- 用这样一个思想,在1~m列中,考虑每一列上升几格,相当于把n-1个苹果放进m个篮子里,可以为空,问有几种方案. 这个就是一个组合数学经典问题了,考虑n个苹果放进m个篮子 ...
- 51nod 1227 平均最小公倍数【欧拉函数+杜教筛】
以后这种题能用phi的就不要用mu-mu往往会带着个ln然后被卡常致死 把题目要求转换为前缀和相减的形式,写出来大概是要求这样一个式子: \[ \sum_{i=1}^{n}\sum_{j=1}^{i} ...
- 《windows核心编程系列》二十一谈谈基址重定位和模块绑定
每个DLL和可执行文件都有一个首选基地址.它表示该模块被映射到进程地址空间时最佳的内存地址.在构建可执行文件时,默认情况下链接器会将它的首选基地址设为0x400000.对于DLL来说,链接器会将它的首 ...
- 数学/找规律/暴力 Codeforces Round #306 (Div. 2) C. Divisibility by Eight
题目传送门 /* 数学/暴力:只要一个数的最后三位能被8整除,那么它就是答案:用到sprintf把数字转移成字符读入 */ #include <cstdio> #include <a ...
- DP Codeforces Round #260 (Div. 1) A. Boredom
题目传送门 /* 题意:选择a[k]然后a[k]-1和a[k]+1的全部删除,得到点数a[k],问最大点数 DP:状态转移方程:dp[i] = max (dp[i-1], dp[i-2] + (ll) ...
- Android 内存溢出处理方案
转自 : http://www.cnblogs.com/hello-ruby/archive/2013/04/19/3031098.html 首先我们来看看android内存溢出的原因,有可能是: 由 ...
- SimpleDateForma类
package Format_daqo; import java.text.SimpleDateFormat; import java.util.Date; public class SimpleDa ...