Memcached 之取模与哈希算法命中率实验
当5台memcache服务器中有一台宕机时的命中率实验。
一、php实现代码
1. config.php
$server = array(
"A" => array("host" => "127.0.0.1", "port" => 11211),
"B" => array("host" => "127.0.0.1", "port" => 11212),
"C" => array("host" => "127.0.0.1", "port" => 11213),
"D" => array("host" => "127.0.0.1", "port" => 11214),
"E" => array("host" => "127.0.0.1", "port" => 11215),
); $_dis = "Moder";//Consistent
2. hash.php
interface hasher {public function _hash($str);}
interface distribution {public function lookup($key);}
/**
* 取模算法类
*/
class Moder implements hasher,distribution
{
protected $_nodes = array();
protected $_cnt = 0;
public function _hash($str) {
return sprintf('%u',crc32($str)); // 把字符串转成 32 位符号整数
}
public function addNode($node){
if (in_array($node, $this->_nodes)) {
return true;
}
$this->_nodes[] = $node;
$this->_cnt += 1;
return true;
}
public function delNode($node) {
if (!in_array($node, $this->_nodes)) {
return true;
}
$key = array_search($node, $this->_nodes);
unset($this->_nodes[$key]);
$this->_cnt -= 1;
return true;
}
public function lookup($key) {
$key = $this->_hash($key) % $this->_cnt;
return $this->_nodes[$key];
}
public function printNodes()
{
print_r($this->_nodes);
}
}
/*
$mode = new Moder();
$mode->addNode('a');
$mode->addNode('b');
$mode->addNode('c');
$key = "sssa";
$mode->printNodes();
echo $mode->_hash($key)."<br/>";
echo $mode->lookup($key);
*/
/**
* 一致性hash算法类
*/
class Consistent implements hasher,distribution{
protected $_nodes = array(); //服务器节点
protected $_postion = array();//虚拟节点
protected $_mul = 64; //每个节点对应 64 个虚节点
public function _hash($str) {
return sprintf('%u',crc32($str)); // 把字符串转成 32 位符号整数
}
// 核心功能
public function lookup($key) {
$point = $this->_hash($key);
$node = current($this->_postion); //先取圆环上最小的一个节点,当成结果
foreach($this->_postion as $k=>$v) {
if($point <= $k)
{
$node = $v;
break;
}
}
reset($this->_postion);
return $node;
}
//添加节点
public function addNode($node) {
if(isset($this->nodes[$node])) {
return;
}
for($i=0; $i<$this->_mul; $i++) {
$pos = $this->_hash($node . '-' . $i);
$this->_postion[$pos] = $node;
$this->_nodes[$node][] = $pos;
}
$this->_sortPos();
}
// 循环所有的虚节点,谁的值==指定的真实节点 ,就把他删掉
public function delNode($node) {
if(!isset($this->_nodes[$node])) {
return;
}
foreach($this->_nodes[$node] as $k) {
unset($this->_postion[$k]);
}
unset($this->_nodes[$node]);
}
//将虚拟节点排序
protected function _sortPos() {
ksort($this->_postion,SORT_REGULAR);
}
}
/*
// 测试
$con = new Consistent();
$con->addNode('a');
$con->addNode('b');
$con->addNode('c');
$key = 'www.zixue.it';
echo '此 key 落在'.$con->lookup($key).'号节点';
*/
3.initData.php(初始化数据)
include './config.php';
include './hash.php';
set_time_limit(0);
$mem = new Memcache();
$diser = new $_dis();
foreach ($server as $key => $value) {
$diser->addNode($key);
}
for ($i=0; $i < 1000; $i++) {
//获取服务器
$serv = $server[$diser->lookup("key" . $i)];
$mem->connect($serv['host'], $serv['port'], 2);
$mem->add("key".$i, "value".$i, 0, 0);
} echo "full";
4.load.php (获取数据的概率)
include './config.php';
include './hash.php';
set_time_limit(0);
$mem = new Memcache();
$diser = new $_dis();
foreach ($server as $key => $value) {
$diser->addNode($key);
}
for ($i=0; $i < 1000; $i++) {
//获取服务器
$serv = $server[$diser->lookup("key" . $i)];
$mem->connect($serv['host'], $serv['port'], 2);
$mem->add("key".$i, "value".$i, 0, 0);
} echo "full";
5.exec.php (执行)
//模拟减少一台服务器
include './config.php';
include './hash.php'; $mem = new Memcache();
$diser = new $_dis();
foreach ($server as $key => $value) {
$diser->addNode($key);
} //删除一台服务器
$diser->delNode("D"); for ($i=0; $i < 10000; $i++) {
//获取服务器
$serv = $server[$diser->lookup("key" . $i)];
if ($serv) {
$mem->connect($serv['host'], $serv['port'], 2);
if(!$mem->get("key" . $i)){
$mem->add("key".$i, "value".$i, 0, 0);
}
} usleep(3000);
}
二、取模算法命中率
如图:
1.初始状态:

2.过程中状态:


3.结束状态

三、哈希算法命中率
如图:
1.初始状态:

2.过程中:

3.结束状态:

三、总结
1.取模命中率为20%(1 / N),哈希命中率为80%左右((N - 1) / N)。
2.当 memcached 节点越多时,一致性哈希算法对缓存的命中率比取模算法对缓存的命中率要高很多。
Memcached 之取模与哈希算法命中率实验的更多相关文章
- memcached集群和一致性哈希算法
场景 由于memcached集群各节点之间都是独立的,互不通信,集群的负载均衡是基于客户端来实现的,因此需要客户端用户设计实现负载均衡算法. 取模算法 N个节点,从0->N-1编号,key对N ...
- 09 Memcached 分布式之取模算法的缺陷
一: Memcached 分布式之取模算法的缺陷(1)假设你有8台服务器,运行中突然down一台,则求余数的底数就7. 后果: key_0%8==0 ,key_0%7==0 =>hist(命中) ...
- Memcached 笔记与总结(8)Memcached 的普通哈希分布算法和一致性哈希分布算法命中率对比
准备工作: ① 配置文件 config.php ② 封装 Memcached 类 hash.class.php,包含普通哈希算法(取模)和一致性哈希算法 ③ 初始化 Memcached 节点信息 in ...
- memcached 一致性哈希算法
本文转载自:http://blog.csdn.net/kongqz/article/details/6695417 一.概述 1.我们的memcache客户端使用了一致性hash算法ketama进行数 ...
- memcached分布式一致性哈希算法
<span style="font-family: FangSong_GB2312; background-color: rgb(255, 255, 255);">如果 ...
- 【转】C语言快速幂取模算法小结
(转自:http://www.jb51.net/article/54947.htm) 本文实例汇总了C语言实现的快速幂取模算法,是比较常见的算法.分享给大家供大家参考之用.具体如下: 首先,所谓的快速 ...
- Raising Modulo Numbers_快速幂取模算法
Description People are different. Some secretly read magazines full of interesting girls' pictures, ...
- 位运算之——按位与(&)操作——(快速取模算法)
学习redis 字典结构,hash找槽位 求槽位的索引值时,用到了 hash值 & sizemask操作, 其后的scan操作涉及扫描顺序逻辑,对同模的槽位 按一定规则扫描! 其中涉及位运算 ...
- 【Java基础】14、位运算之——按位与(&)操作——(快速取模算法)
学习redis 字典结构,hash找槽位 求槽位的索引值时,用到了 hash值 & sizemask操作, 其后的scan操作涉及扫描顺序逻辑,对同模的槽位 按一定规则扫描! 其中涉及位运算 ...
随机推荐
- 洛谷 P2548 [AHOI2004]智能探险车
P2548 [AHOI2004]智能探险车 题目描述 输入输出格式 输入格式: 输出格式: 输入输出样例 输入样例#1: 复制 4 3 sunny plain full many sunny moun ...
- Linux统计行数命令wc(转)
Linux wc命令用于计算字数. 利用wc指令我们可以计算文件的Byte数.字数.或是列数,若不指定文件名称.或是所给予的文件名为"-",则wc指令会从标准输入设备读取数据. 语 ...
- 相克军_Oracle体系_随堂笔记 PPT
http://www.cnblogs.com/jyzhao/category/581259.html http://download.csdn.net/detail/yzj149286454/8960 ...
- RDS For MySQL 字符集相关说明
https://help.aliyun.com/knowledge_detail/41706.html?spm=5176.7841698.2.9.F5YjI5 字符序命名规则 字符集相关 MySQL ...
- [MongoDB]Python 操作 MongoDB
from pymongo import MongoClient mc = MongoClient('localhost',27017) db = mc.users db.users.save({'na ...
- C++和C#的指针小解
昨天和赵崇说了一下工作的事情,说起了性能问题就讨论起了数据结果和指针对性能的影响.曾经一直没有想到这方面的事情,这几天专门抽时间回想一下这方面的知识,然后一点一点的总结一下,看看数据结构和指针在咱们代 ...
- JMS解决系统间通信问题
近期在给公司项目做二次重构,将原来庞大的系统拆分成几个小系统.系统与系统之间通过接口调用,系统间通信有非常多方式,如系统间通信接口做成请求controller,只是这样不方便也不安全,经常使用的方式是 ...
- @Repository @Service 和@Autowired 的使用
解释: @Controller 声明Action组件 @Service 声明Service组件 @Service("myMovieLister") @Repositor ...
- Android - Error: "java.io.IOException: setDataSource failed.: status=0x80000000"
Error: "java.io.IOException: setDataSource failed.: status=0x80000000" 本文地址: http://blog.c ...
- Android 线程 Looper.prepare()、Looper.loop() 使用
优化项目过程中发现了一个非常Low的问题,整理一下.备忘: 说问题之前先看下HandlerThread的定义 一个封装了looper的线程: Looper用于封装了android线程中的消息循环. ...