memcached一致性哈希及php客户端实现
memcached分布式算法
memcached的分布式是依靠客户端的算法来实现,假设键名为$key,服务器数量为N,常规的实现方式有两种:
- 取模哈希
- crc32($key)%N,通过这个算法将键名映射到某一台服务器,比如需要存取一个键名为myname的缓存,服务器数量为3,那么通过算法计算:crc32('myname')%3=0,那么这个缓存就落到第1台服务器上面
- 这种方式虽然简单可行,但是增减服务器的时候,缓存将面临大量的重建,比如上面的例子中,新增了1台服务器,服务器数量变为4台,通过算法计算:crc32('myname')%4=3,从第1台变成第3台了,导致缓存重建;又比如第1台服务器挂了,缓存的存取都会失败,导致短时间内大量的请求涌入mysql
- 一致性哈希
- 一致性哈希就是为了解决上面的缓存重建而设计的,取模法不理想的原因就是算法的本质就是根据服务器数量来计算的,缓存跟服务器是一一对应,要想灵活一点就不能是一对一的关系,一致性哈希算法首先创建出一个首( 0 )尾( 2^32-1 )相接的环形的哈希空间,如下图的圆环,然后把服务器通过hash算法映射到环形的某一点,如下图中node1、node2、node3、node4,然后再把缓存的键映射到环形的某一点,获取某个键的内容是从这个键的节点按顺时针方向开始查找服务器节点,找到的第一台服务器就是这个缓存要进行存取的服务器,如此一来当node1服务器挂了,影响到的只是从node3到node1节点之间的缓存数据,这些数据将会去node2中存取,这样可以把缓存重建的代价降低

安装依赖软件
[root@localhost ~]# yum install gcc
[root@localhost ~]# yum install gcc-c++
[root@localhost ~]# yum install autoconf
安装libmemcached
memcached扩展依赖于libmemcached,因此先安装libmemcached
[root@localhost ~]# cd /usr/local/src
[root@localhost src]# wget https://launchpad.net/libmemcached/1.0/1.0.17/+download/libmemcached-1.0.17.tar.gz
[root@localhost src]# tar -zxvf libmemcached-1.0.18.tar.gz
[root@localhost src]# cd libmemcached-1.0.18
[root@localhost libmemcached-1.0.18]# ./configure --prefix=/usr/local/libmemcached --with-memcached
[root@localhost libmemcached-1.0.18]# make && make install
安装php的memcached扩展
[root@localhost ~]# cd /usr/local/src
[root@localhost src]# wget http://pecl.php.net/get/memcached-3.0.3.tgz
[root@localhost src]# cd memcached-3.0.3
[root@localhost memcached-3.0.3]# tar -zxvf memcached-3.0.3.tgz
[root@localhost memcached-3.0.3]# ./configure --prefix=/usr/local/pecl-memcached --with-php-config=/usr/local/php/bin/php-config --with-libmemcached-dir=/usr/local/libmemcached
error: no, sasl.h is not available
[root@localhost memcached-3.0.3]# yum install cyrus-sasl-devel
[root@localhost memcached-3.0.3]# make && make install
#修改php配置,加入memcache扩展
[root@localhost memcached-3.0.3]# vi /usr/local/php/lib/php.ini
extension=memcached.so #重启apache
[root@localhost memcached-3.0.3]# apachectl restart #启动memcached服务器并记录日志
[root@localhost src]# memcached -d -u nobody -p 32054 -vv >> /tmp/memcached.32054.log 2>&1
[root@localhost src]# memcached -d -u nobody -p 32055 -vv >> /tmp/memcached.32055.log 2>&1
[root@localhost src]# memcached -d -u nobody -p 32056 -vv >> /tmp/memcached.32056.log 2>&1
测试一致性哈希
$m = new Memcached();
$m->setOptions(array(
Memcached::OPT_DISTRIBUTION=>Memcached::DISTRIBUTION_CONSISTENT,
Memcached::OPT_LIBKETAMA_COMPATIBLE=>true,
Memcached::OPT_REMOVE_FAILED_SERVERS=>true,
));
$m->addServers(array(
array('localhost', 32054),
array('localhost', 32055),
array('localhost', 32056),
//array('localhost', 32057),
));
$m->set('key1', 1);
$m->set('key2', 'abc');
$m->set('key3', array('foo', 'bar'));
$m->set('key4', new stdClass);
$m->set('key5', 'pigfly');
$m->set('key6', 999);
var_dump($m->get('key1'), $m->get('key2'), $m->get('key3'), $m->get('key4'), $m->get('key5'), $m->get('key6'));
运行这段php代码,我们再查看日志:
#memcached.32054.log
36 STORED
36 STORED
36 sending key key2
>36 END
36 sending key key3
>36 END
#memcached.32055.log
<36 new auto-negotiating client connection
36: Client using the ascii protocol
<36 set key1 1 0 1
>36 STORED
<36 set key4 4 0 19
>36 STORED
<36 get key1
>36 sending key key1
>36 END
<36 get key4
>36 sending key key4
>36 END
<36 quit
<36 connection closed.
#memcached.32056.log
<36 new auto-negotiating client connection
36: Client using the ascii protocol
<36 set key5 0 0 6
>36 STORED
<36 set key6 1 0 3
>36 STORED
<36 get key5
>36 sending key key5
>36 END
<36 get key6
>36 sending key key6
>36 END
<36 quit
<36 connection closed.
缓存的分布情况:
| host | key |
|---|---|
| 32054 | key2,key3 |
| 32055 | key1,key4 |
| 32056 | key5,key6 |
现在我们加一台32057的memcached试试:
[root@localhost src]# memcached -d -u nobody -p 32057 -vv >> /tmp/memcached.32057.log 2>&1
取消php代码第13行的注释,运行php,查看日志文件:
#memcached.32054.log
<36 new auto-negotiating client connection
36: Client using the ascii protocol
<36 set key3 4 0 34
>36 STORED
<36 get key3
>36 sending key key3
>36 END
<36 quit
#memcached.32055.log
<36 new auto-negotiating client connection
36: Client using the ascii protocol
<36 set key1 1 0 1
>36 STORED
<36 set key4 4 0 19
>36 STORED
<36 get key1
>36 sending key key1
>36 END
<36 get key4
>36 sending key key4
>36 END
<36 quit
<36 connection closed.
#memcached.32056.log
<36 new auto-negotiating client connection
36: Client using the ascii protocol
<36 set key5 0 0 6
>36 STORED
<36 set key6 1 0 3
>36 STORED
<36 get key5
>36 sending key key5
>36 END
<36 get key6
>36 sending key key6
>36 END
<36 quit
<36 connection closed.
#memcached.32057.log
<36 new auto-negotiating client connection
36: Client using the ascii protocol
<36 set key2 0 0 3
>36 STORED
<36 get key2
>36 sending key key2
>36 END
<36 quit
<36 connection closed.
缓存的分布情况:
| host | key |
|---|---|
| 32054 | key3 |
| 32055 | key1,key4 |
| 32056 | key5,key6 |
| 32057 | key2 |
我们发现32054的key2跑到32057去了,32055和32056的key都没有受到影响,说明一致性哈希起作用了,我们再来模拟一下有一台memcached服务器宕机的情况
[root@local htdocs]# ps -aux | grep memcached
nobody 7621 0.0 0.3 415860 3440 ? Ssl 16:16 0:00 memcached -d -u nobody -p 32054 -vv
nobody 7632 0.0 0.4 414832 4432 ? Ssl 16:16 0:00 memcached -d -u nobody -p 32055 -vv
nobody 7643 0.0 0.8 414832 8532 ? Ssl 16:17 0:00 memcached -d -u nobody -p 32056 -vv
nobody 7659 0.0 0.4 414832 4432 ? Ssl 16:26 0:00 memcached -d -u nobody -p 32057 -vv
[root@local htdocs]# kill 7621 #杀掉32054
运行php代码,查看日志:
#memcached.32055.log
<36 new auto-negotiating client connection
36: Client using the ascii protocol
<36 set key1 1 0 1
>36 STORED
<36 set key3 4 0 34
>36 STORED
<36 set key4 4 0 19
>36 STORED
<36 get key1
>36 sending key key1
>36 END
<36 get key3
>36 sending key key3
>36 END
<36 get key4
>36 sending key key4
>36 END
<36 quit
<36 connection closed.
#memcached.32056.log
<36 new auto-negotiating client connection
36: Client using the ascii protocol
<36 set key5 0 0 6
>36 STORED
<36 set key6 1 0 3
>36 STORED
<36 get key5
>36 sending key key5
>36 END
<36 get key6
>36 sending key key6
>36 END
<36 quit
<36 connection closed.
#memcached.32057.log
<36 new auto-negotiating client connection
36: Client using the ascii protocol
<36 set key2 0 0 3
>36 STORED
<36 get key2
>36 sending key key2
>36 END
<36 quit
<36 connection closed.
缓存的分布情况:
| host | key |
|---|---|
| 32055 | key1,key3,key4 |
| 32056 | key5,key6 |
| 32057 | key2 |
由于32054挂了,我们看到32054的key3跑到32055去了,其他端口的缓存没有受到影响,这样就把缓存的重建代价降低了
memcached一致性哈希及php客户端实现的更多相关文章
- memcached 一致性哈希算法
本文转载自:http://blog.csdn.net/kongqz/article/details/6695417 一.概述 1.我们的memcache客户端使用了一致性hash算法ketama进行数 ...
- 10 Memcached 一致性哈希分布式算法原理与实现[PHP实现]
<?php header("Content-type:text/html;charset=utf-8"); interface hash{ public function _ ...
- Memcached 笔记与总结(8)Memcached 的普通哈希分布算法和一致性哈希分布算法命中率对比
准备工作: ① 配置文件 config.php ② 封装 Memcached 类 hash.class.php,包含普通哈希算法(取模)和一致性哈希算法 ③ 初始化 Memcached 节点信息 in ...
- Memcached 笔记与总结(5)Memcached 的普通哈希分布和一致性哈希分布
普通 Hash 分布算法的 PHP 实现 首先假设有 2 台服务器:127.0.0.1:11211 和 192.168.186.129:11211 当存储的 key 经过对 2 (2 台服务器)取模运 ...
- memcached分布式一致性哈希算法
<span style="font-family: FangSong_GB2312; background-color: rgb(255, 255, 255);">如果 ...
- Nginx网络架构实战学习笔记(四):nginx连接memcached、第三方模块编译及一致性哈希应用
文章目录 nginx连接memcached 第三方模块编译及一致性哈希应用 总结 nginx连接memcached 首先确保nginx能正常连接php location ~ \.php$ { root ...
- memcache 的内存管理介绍和 php实现memcache一致性哈希分布式算法
1 网络IO模型 安装memcached需要先安装libevent Memcached是多线程,非阻塞IO复用的网络模型,分为监听主线程和worker子线程,监听线程监听网络连接,接受请求后,将连接描 ...
- 一致性哈希算法——算法解决的核心问题是当slot数发生变化时,能够尽量少的移动数据
一致性哈希算法 摘自:http://blog.codinglabs.org/articles/consistent-hashing.html 算法简述 一致性哈希算法(Consistent Hashi ...
- 一致性哈希(consistent hashing)算法
文章同步发表在博主的网站朗度云,传输门:http://www.wolfbe.com/detail/201608/341.html 1.背景 我们都知道memcached服务器是不提供分布 ...
随机推荐
- WebService的简单运用添加删除
WebService是一种跨编程语言和跨操作系统平台的远程调用技术,简单来说就是将数据存储到项目的文件夹下 .NET中基于DOM核心类 XmlDocument 表示一个XML文档 XmlNode表示X ...
- Unix时代的开创者Ken Thompson
自图灵奖诞生以来,其获得者一直都是计算机领域的科学家与学者,而在所有这些界的图灵奖中只有唯一的一届有个例外,那就是Ken Thompson与Dennis M. Ritchie,他们都是计算机软件工程师 ...
- TensorFlow Object Detection API(Windows下测试)
"Speed/accuracy trade-offs for modern convolutional object detectors." Huang J, Rathod V, ...
- 微信小程序支付
@Controllerpublic class UserPayToMerchantController { public static final String appid="******* ...
- 译:Asp.Net Identity与Owin,到底谁是谁?
送给正在学习Asp.Net Identity的你 :-) 原文出自 trailmax 的博客AspNet Identity and Owin. Who is who. Recently I have ...
- 【机器学习实战】第12章 使用FP-growth算法来高效发现频繁项集
第12章 使用FP-growth算法来高效发现频繁项集 前言 在 第11章 时我们已经介绍了用 Apriori 算法发现 频繁项集 与 关联规则.本章将继续关注发现 频繁项集 这一任务,并使用 FP- ...
- ASP.NET Core的身份认证框架IdentityServer4(5)- 包和构建
包和构建 IdentityServer有许多nuget包 IdentityServer4 nuget | github 包含IdentityServer核心对象模型,服务和中间件. 仅支持内存配置和用 ...
- MUI框架开发HTML5手机APP(一)--搭建第一个手机APP
前 言 JRedu 随着HTML5的不断发展,移动开发成为主流趋势!越来越多的公司开始选择使用HTML5开发手机APP,而随着手机硬件设备配置的不断提升,各种开发框架的不断优化,也使着H5开发的 ...
- oracle存储过程统计用户各表记录数
declare v_tName varchar(50); v_sqlanalyze varchar(500); v_num number; v_sql varchar(500); cursor c1 ...
- 《Linux命令行与shell脚本编程大全》第九章 安装软件程序
包管理系统(PMS):用来进行软件安装.管理和删除的命令行工具 9.1包管理基础 1.主流的Linux发行版都采用了某种形式的包管理系统来控制软件和库的安装 2.PMS用一个数据库来记录:系统上安装了 ...