1、Memcached常规应用

  1. $mc = new Memcache();
  2. $mc->conncet('127.0.0.1', 11211);
  3. $sql = sprintf("SELECT * FROM users WHERE uid = %d", $_GET['uid']);
  4. $key = md5($sql);
  5. //检测结果是否已经被缓存
  6. if( ! $data = $mc->get($key)){
  7. //没有缓存则直接从数据库读取
  8. mysql_conncet('localhost', 'test', 'test');
  9. mysql_select_db('test');
  10. while($row = mysql_fetch_object(mysql_query($sql))){
  11. $data[] = $row;
  12. }
  13. //并将查询结果缓存
  14. $mc->add($key, $data);
  15. }
  16. var_dump($data);

说明:首先通过md5()将SQL语句转化成一个唯一的KEY,并用此KEY查询Memcached检测是否已经缓存,是的话在直接返回结果,否则先查询数据库再缓存,并返回结果。这样,下次使用此KEY就可以直接返回结果了。

2、Memcached分布式部署方案,对于多台Memcached服务器,怎么确定一个数据应该保存到哪台服务器呢?有两种方案,一是普通Hash分布,二是一致性Hash分布。下面详细说明。

方案一:简单的取模运算

  1. <?php
  2.  
  3. //Hash函数
  4. function mHash($key){
  5. $md5 = substr(md5($key), 0, 8);
  6. $seed = 31;
  7. $hash = 0;
  8. for($i = 0; $i < 8; $i++){
  9. $hash = $hash * $seed + ord($md5{$i});
  10. $i++;
  11. }
  12. return $hash & 0x7FFFFFFF;
  13. }
  14. //假设有2台Memcached服务器
  15. $servers = array(
  16. array('host' => '192.168.1.1', 'port' => 11211),
  17. array('host' => '192.168.1.1', 'port' => 11211)
  18. );
  19. $key = 'MyBlog';
  20. $value = 'http://www.cnblogs.com/gide';
  21. $sc = $servers[mHash($key) % 2];
  22. $memcached = new Memcached($sc);
  23. $memcached->set($key, $value);

说明:首先通过MD5函数把KEY处理成32位字符串,然后截取前8位,再经过Hash算法处理成一个整数并返回。利用这个整数与Memcached服务器数量取模,决定当前KEY存储于哪台Memcached服务器,就完成了Memcached的分布式部署。可想而知,当要读取KEY的值时,依然是先要通过Hash算法判断存储于哪台服务器

方案二:一致性hash部署

  1. <?php
  2.  
  3. class FlexiHash{
  4. //服务器列表
  5. private $serverList = array();
  6. //记录是否已经排序
  7. private $isSorted = FALSE;
  8. //添加一台服务器
  9. public function addServer($server){
  10. $hash = $this->mHash($server);
  11. if(!isset($this->serverList[$hash])){
  12. $this->serverList[$hash] = $server;
  13. }
  14. //需要重新排序
  15. $this->isSorted = FALSE;
  16. return TRUE;
  17. }
  18. //移除一台服务器
  19. public function removeServer($server){
  20. $hash = $this->mHash($server);
  21. if(isset($this->serverList[$hash])){
  22. unset($this->serverList[$hash]);
  23. }
  24. //需要重新排序
  25. $this->isSorted = FALSE;
  26. return TRUE;
  27. }
  28. //在当前服务器列表查找合适的服务器
  29. public function lookup($key){
  30. $hash = $this->mHash($key);
  31. //先进行倒序排序操作
  32. if(!$this->isSorted){
  33. krsort($this->serverList, SORT_NUMERIC);
  34. $this->isSorted = TRUE;
  35. }
  36. //圆环上顺时针方向查找当前KEY紧邻的一台服务器
  37. foreach($this->serverList as $pos => $server){
  38. if($hash >= $pos) return $server;
  39. }
  40. //没有找到则返回顺时针方向最后一台服务器
  41. return $this->serverList[count($this->serverList) - 1];
  42. }
  43. //Hash函数
  44. private function mHash($key){
  45. $md5 = substr(md5($key), 0, 8);
  46. $seed = 31;
  47. $hash = 0;
  48. for($i = 0; $i < 8; $i++){
  49. $hash = $hash * $seed + ord($md5{$i});
  50. $i++;
  51. }
  52. return $hash & 0x7FFFFFFF;
  53. }
  54. }
  55. ?>

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

具体应用:

  1. <?php
  2. $hserver = new FlexiHash();
  3. //初始5台服务器
  4. $hserver->addServer("192.168.1.1");
  5. $hserver->addServer("192.168.1.2");
  6. $hserver->addServer("192.168.1.3");
  7. $hserver->addServer("192.168.1.4");
  8. $hserver->addServer("192.168.1.5");
  9. echo "save key1 in server: ", $hserver->lookup('key1'), "<br/>";
  10. echo "save key2 in server: ", $hserver->lookup('key2'), "<br/>";
  11. echo '===============================================<br/>';
  12. //移除1台服务器
  13. $hserver->removeServer("192.168.1.4");
  14. echo "save key1 in server: ", $hserver->lookup('key1'), "<br/>";
  15. echo "save key2 in server: ", $hserver->lookup('key2'), "<br/>";
  16. echo '===============================================<br/>';
  17. //添加1台服务器
  18. $hserver->addServer('192.168.1.6');
  19. echo "save key1 in server: ", $hserver->lookup('key1'), "<br/>";
  20. echo "save key2 in server: ", $hserver->lookup('key2');
  21. ?>
  22. //测试结果如下:
  23. save key1 in server: 192.168.1.4
  24. save key2 in server: 192.168.1.2
  25. ==================================
  26. save key1 in server: 192.168.1.3
  27. save key2 in server: 192.168.1.2
  28. ==================================
  29. save key1 in server: 192.168.1.3
  30. save key2 in server: 192.168.1.2

不过Memcached自带了addServer

Memcached::addServer — 向服务器池中增加一个服务器
public bool Memcached::addServer ( string $host , int $port [, int $weight = 0 ] )
host
memcached服务端主机名。如果主机名无效,相关的数据操作的返回代码将被设置为Memcached::RES_HOST_LOOKUP_FAILURE。

port
memcached服务端端口号,通常是11211。

weight
此服务器相对于服务器池中所有服务器的权重。此参数用来控制服务器在操作时被选种的概率。这个仅用于一致性 分布选项,并且这个值通常是由服务端分配的内存来设置的。

成功时返回 TRUE, 或者在失败时返回 FALSE。

  1. <?php
  2. $m = new Memcached();
  3.  
  4. $m->addServer('mem1.domain.com', 11211, 33);
  5. $m->addServer('mem2.domain.com', 11211, 67);

完毕!

Memcached常规应用与分布式部署方案的更多相关文章

  1. Window Redis分布式部署方案 java

    Redis分布式部署方案 Window 1.    基本介绍 首先redis官方是没有提供window下的版本, 是window配合发布的.因现阶段项目需求,所以研究部署的是window版本的,其实都 ...

  2. Memcache分布式部署方案

    基础环境 其实基于PHP扩展的Memcache客户端实际上早已经实现,而且非常稳定.先解释一些名词,Memcache是danga.com的一个开源项目,可以类比于MySQL这样的服务,而PHP扩展的M ...

  3. zookeeper分布式部署方案

    版本:http://apache.fayea.com/zookeeper/zookeeper-3.4.8/环境:debian 7/8说明:最低配置3台步骤:1.下载zookeeper-3.4.8并解压 ...

  4. memcached缓存分布式部署方案

    一.分布式方案介绍 比较流行的两种方案: 1.取余分布: 计算key的哈希值,与服务器数量取余,得到目标服务器.优点:实现简单,当某台服务器不可用时,故障转移方便:缺点:当增减服务器时, Key与服务 ...

  5. Linux-Memcache分布式部署方案(magent代理解决单点故障)

    Memcached的特点 Memcached作为高速运行的分布式缓存服务器具有以下特点. 1. 协议简单:memcached的服务器客户端通信并不使用复杂的MXL等格式, 而是使用简单的基于文本的协议 ...

  6. 一文读懂 Redis 分布式部署方案

    为什么要分布式 Redis是一款开源的基于内存的K-V型数据库,因为内存访问速度快,一般被用来做系统的缓存. Redis作为单机部署能够支持业务简单,数据量不大的系统需求,但在实际应用中,一旦系统规模 ...

  7. 矢量切片应用中geoserver与geowebcache分布式部署方案

    在进行GIS项目开发中,常使用Geoserver作为开源的地图服务器,Geoserver是一个JavaEE项目,常通过Tomcat进行部署.而GeoWebCache是一个采用Java实现用于缓存WMS ...

  8. Redis集群的分布式部署

    3.2.2:Redis Cluster: Redis  分布式部署方案: 1)  客户端分区:由客户端程序决定 key 写分配和写入的 redis node,但是需要客户端自己处理写入 分配.高可用管 ...

  9. 项目分布式部署那些事(2):基于OCS(Memcached)的Session共享方案

    在不久之前发布了一篇"项目分布式部署那些事(1):ONS消息队列.基于Redis的Session共享,开源共享",因为一些问题我们使用了阿里云的OCS,下面就来简单的介绍和分享下相 ...

随机推荐

  1. python安装pycrypto报错error: command 'x86_64-linux-gnu-gcc' failed with exit status 1

    系统3.19.0-15-generic #15-Ubuntu 安装pycrypto提示error: command 'x86_64-linux-gnu-gcc' failed with exit st ...

  2. 手机驱动无法正常安装,出现adb interface失败

    手机一直无法用usb连接上电脑,试了各种方法,总是提示安装驱动失败,或者找不到文件. 在网上找了各种方法,后来结果证明,是我自己手贱了,... 方法: Win7系统用户已经碰到几次在安装adb驱动时提 ...

  3. java中final,finally和finalize的区别

    final,finally和finalize的区别: final:最终的意思,可以修饰类,成员变量,成员方法 修饰类,类不能被继承 修饰变量,变量是常量 修饰方法,方法不能被重写 finally:是异 ...

  4. 《UML大战需求分析》阅读笔记2

    在第三章往后的章节里面,作者着重描述了uml各个图的具体用法,首先则是类图. 类图则表示程序中所出现的用到的类,用方框来表示,方框中分为三行,第一行是类的名字,第二行是类的成员变量(属性),第三行是成 ...

  5. 2.Unable to instantiate Action, templateAction, defined for 'template_list' in namespace '/'templateAction

    1.错误说没有命名空间'templateAction,但是在struts里写了这个,名字跟Action的名字是一样的,为什么会报这个错误 2.反复检查路径和名字,都没有问题 3.发现没有对其进行注入操 ...

  6. 关于eclipse在线下载安装android SDK没反应解决方法

    虽然天朝将google这个服务器给和谐掉了 虽然我们也可以选择其他各类FQ软件 虽然你可能有其他手段解决 不过我还是要提供一个参考方法: 具体操作方式: 点击桌面左下角开始菜单中的搜索,把以下路径,复 ...

  7. 过滤器(servlet.filter)和拦截器(springmvc.interceptor)区别

    ①拦截器是基于java的反射机制的,而过滤器是基于函数回调. ②拦截器不依赖与servlet容器,过滤器依赖与servlet容器. ③拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求 ...

  8. 命令行查看linux发行版版本信息

    有时候安装完自己的linux发行版系统(如ubuntu.centos.redhat.opensuse.--)时,把版本信息忽略了,又不想重启电脑,此时我们可以通过命令行方式来查看: 1.cat /et ...

  9. AndroidStudio Lod.d在LogCat中不输出

    今天Log.d无论怎样都没有输出. 要在手机开发者选项那开启权限,莫名其妙,之前一直都没事的,具体操作参考:http://jingyan.baidu.com/article/84b4f56597e7b ...

  10. 对象池与.net—从一个内存池实现说起

    本来想写篇关于System.Collections.Immutable中提供的ImmutableList里一些实现细节来着,结果一时想不起来源码在哪里--为什么会变成这样呢--第一次有了想写分析的源码 ...