一、目录结构

二、具体代码

MemcacheCluster.php

  1. <?php
  2.  
  3. /**
  4. * 一致性哈希memcache分布式,采用的是虚拟节点的方式解决分布均匀性问题,查找节点采用二分法快速查找
  5. */
  6. class MemcacheCluster
  7. {
  8. private $_node = array();
  9. private $_nodeData = array();
  10. private $_keyNode = 0;
  11. private $_memcache = null;
  12.  
  13. //每个物理服务器生成虚拟节点个数 [注:节点数越多,cache分布的均匀性越好,同时set get操作时,也更耗资源,10台物理服务器,采用200较为合理]
  14. private $_virtualNodeNum = 2;
  15.  
  16. private function __construct()
  17. {
  18. /* 放入配置文件 */
  19. $config = array(
  20. '127.0.0.1:11211',
  21. );
  22.  
  23. if (!$config) throw new Exception('Cache config NULL');
  24. foreach ($config as $key => $value) {
  25. for ($i = 0; $i < $this->_virtualNodeNum; $i++) {
  26. $this->_node[sprintf("%u", crc32($value . '_' . $i))] = $value . '_' . $i;
  27. }
  28. }
  29. ksort($this->_node);
  30. }
  31.  
  32. private function __clone()
  33. {
  34. }
  35.  
  36. /**
  37. * 单例,保证只有一个实例
  38. */
  39. static public function getInstance()
  40. {
  41. static $memcacheObj = null;
  42. if (!is_object($memcacheObj)) {
  43. $memcacheObj = new self();
  44. }
  45. return $memcacheObj;
  46. }
  47.  
  48. /**
  49. * 根据key做一致性hash后连接到一台物理memcache服务器
  50. * @param string $key
  51. */
  52. private function _connectMemcache($key)
  53. {
  54. $this->_nodeData = array_keys($this->_node);
  55. $this->_keyNode = sprintf("%u", crc32($key));
  56. $nodeKey = $this->_findServerNode();
  57. //如果超出环,从头再用二分法查找一个最近的,然后环的头尾做判断,取最接近的节点
  58. if ($this->_keyNode > end($this->_nodeData)) {
  59. $this->_keyNode -= end($this->_nodeData);
  60. $nodeKey2 = $this->_findServerNode();
  61. if (abs($nodeKey2 - $this->_keyNode) < abs($nodeKey - $this->_keyNode)) $nodeKey = $nodeKey2;
  62. }
  63. //var_dump($this->_node[$nodeKey]); 127.0.0.1:11211_20
  64. list($config, $num) = explode('_', $this->_node[$nodeKey]);
  65. if (!$config) throw new Exception('Cache config Error');
  66. if (!isset($this->_memcache[$config])) {
  67. $this->_memcache[$config] = new Memcache;
  68. list($host, $port) = explode(':', $config);
  69. $this->_memcache[$config]->connect($host, $port);
  70. }
  71. return $this->_memcache[$config];
  72. }
  73.  
  74. /**
  75. * 采用二分法从虚拟memcache节点中查找最近的节点
  76. * @param unknown_type $m
  77. * @param unknown_type $b
  78. */
  79. private function _findServerNode($m = 0, $b = 0)
  80. {
  81. $total = count($this->_nodeData);
  82. if ($total != 0 && $b == 0) $b = $total - 1;
  83. if ($m < $b) {
  84. $avg = intval(($m + $b) / 2);
  85. if ($this->_nodeData[$avg] == $this->_keyNode) return $this->_nodeData[$avg];
  86. elseif ($this->_keyNode < $this->_nodeData[$avg] && ($avg - 1 >= 0)) return $this->_findServerNode($m, $avg - 1);
  87. else return $this->_findServerNode($avg + 1, $b);
  88. }
  89. if (abs($this->_nodeData[$b] - $this->_keyNode) < abs($this->_nodeData[$m] - $this->_keyNode)) return $this->_nodeData[$b];
  90. else return $this->_nodeData[$m];
  91. }
  92.  
  93. public function set($key, $value, $expire = 0)
  94. {
  95. return $this->_connectMemcache($key)->set($key, json_encode($value), 0, $expire);
  96. }
  97.  
  98. public function add($key, $value, $expire = 0)
  99. {
  100. return $this->_connectMemcache($key)->add($key, json_encode($value), 0, $expire);
  101. }
  102.  
  103. public function get($key)
  104. {
  105. return json_decode($this->_connectMemcache($key)->get($key), true);
  106. }
  107.  
  108. public function delete($key)
  109. {
  110. return $this->_connectMemcache($key)->delete($key);
  111. }
  112.  
  113. }

memcached.php

  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: 25754
  5. * Date: 2019/9/17
  6. * Time: 16:17
  7. */
  8.  
  9. include_once APPPATH . "/third_party/MemcacheCluster.php";
  10.  
  11. class Memcached
  12. {
  13. public function set($key, $value, $expire = 0)
  14. {
  15. return MemcacheCluster::getInstance()->set($key, $value, $expire);
  16. }
  17.  
  18. public function add($key, $value, $expire = 0)
  19. {
  20. return MemcacheCluster::getInstance()->add($key, $value, $expire);
  21. }
  22.  
  23. public function delete($key)
  24. {
  25. return MemcacheCluster::getInstance()->delete($key);
  26. }
  27.  
  28. public function get($key)
  29. {
  30. return MemcacheCluster::getInstance()->get($key);
  31. }
  32. }

MY_Controller.php

  1. class Home_Controller extends CI_Controller
  2. {
  3. public function __construct()
  4. {
  5. parent::__construct();
  6. $this->load->library('memcached', null, 'memcache');
  7. }
  8. }

index.php

  1. class Index extends Home_Controller
  2. {
  3. public function __construct()
  4. {
  5. parent::__construct();
  6. $this->load->set_home_view_dir();
  7. }
  8.  
  9. public function index()
  10. {
  11. //要设置随机缓存时间,防止缓存失效,大的访问量造成数据库崩溃
  12. $time = rand(1, 10);
  13. $key = md5("yy");
  14. $cacheValue = $this->memcache->get($key);
  15. if (!$cacheValue) {
  16. //随机保存时间
  17. $flag = $this->memcache->set($key, "yang", $time);
  18. if ($flag) {
  19. echo "缓存时间:".$time."秒";
  20. }
  21. }
  22. echo $cacheValue;
  23. }
  24. }

PHP+CI框架+Memcache集成的更多相关文章

  1. CI框架中集成CKEditor编辑器的教程

    CKEditor是在很多开发过程中都会用到的一个富文本编辑器,那么如何在CI框架中使用它呢?这里介绍了在CI下使用CKEditor的方法,版本比较低,是在CI 1.7.3下使用fckeditor 2. ...

  2. 【军哥谈CI框架】之CI中集成百度UEditor

    Hello,各位亲,新的一周来临啦,很高兴这么快又跟大家伙见面!话说上一回,军哥带大家用JQuery写了一个城市级联菜单的例子 ,不知道亲们学会了多少,是否自己可以独立写出来了呢. 军哥很是期待大家学 ...

  3. **【ci框架】PHP的CI框架集成Smarty的最佳方式

    因为CI自带的模板功能不是很方便,所以大家普遍采用集成Smarty的方式来弥补CI这方面的不足. 本人在网上看了不少CI集成Smarty的教程,包括咱们CI论坛里面的一个精华帖子 http://cod ...

  4. CI框架使用PHPmail插件发送QQ邮件:

    有助请顶,不好请评.0:33 2016/3/12CI框架使用PHPmail插件发送QQ邮件:发送成功,不过修改了主机参数,还包含了一个phpmail中的一个另外的文件,详见下方:参见:http://c ...

  5. CI框架源码阅读笔记1 - 环境准备、基本术语和框架流程

    最开始使用CI框架的时候,就打算写一个CI源码阅读的笔记系列,可惜虎头蛇尾,一直没有行动.最近项目少,总算是有了一些时间去写一些东西.于是准备将之前的一些笔记和经验记录下来,一方面权作备忘,另一方面时 ...

  6. **【ci框架】精通CodeIgniter框架

    http://blog.csdn.net/yanhui_wei/article/details/25803945 一.大纲 1.codeigniter框架的授课内容安排 2.codeigniter框架 ...

  7. CI框架大纲总结

    一.大纲 1.codeigniter框架的授课内容安排 2.codeigniter框架的简介 |-----关于框架的概念 |-----使用CI框架的好处 |-----为什么选择CI框架 3.codei ...

  8. 【ci框架基础】之部署百度编辑器

    在ci框架下加载编辑器,现在复习下内容.我的框架文件名称为ci 1.下载百度编辑器ueditor,http://ueditor.baidu.com/ 一般情况下下载ubuilder版即可,并将uedi ...

  9. PHP的CI框架流程基本熟悉

    CI框架是PHP的一个快速开发框架,我是目前的公司项目后台语言用的PHP,因为我做前端开发,需要用php去填充页面数据,所以就开始去了解这个框架,学习了一些php和数据库的东西,这篇文章先具体介绍CI ...

随机推荐

  1. ASP.NET WEB应用程序(.network4.5)MVC 程序的结构解读1

    https://www.cnblogs.com/-beauTiFul/p/8036509.html 简介 开发环境:VS2015 ASP.NET:可以开发出几乎所有运行在Windows上的应用程序:. ...

  2. 补充:Python安装

    需要安装Python2.7.Numpy和Matplotlib.由于Python不支持向下兼容,因此在Python3.×下你一定能正常运行Python2.×的代码.上述模块最简单的安装方法就是用软件包安 ...

  3. Mac下安装和配置Vue项目

    题记:学vue有一段时间了,终于今天下定决心每日书写一篇学习笔记.1.访问node.js官网:https://nodejs.org/en/ 下载对应安装包.2.安装完成,在终端输入 : node -v ...

  4. Spring中Bean的管理问题

    首先,配置文件中定义的bean并不是都在启动时实例化. <bean id="accountService" class="com.foo.DefaultAccoun ...

  5. 用一个N点复序列的FFT同时计算两个N点实序列离散傅里叶变换

    一.功能 用一个\(N\)点复序列快速傅立叶变换算法来同时计算两个\(N\)点实序列的离散傅立叶变换. 二.方法简介 假设\(x(n)\)与\(y(n)\)都是长度为\(N\)的实序列,为计算其离散傅 ...

  6. ajax _flask

    同步访问 当客户端向服务器发送请求时,服务器在处理过程中,浏览器只能等等,效率偏低 异步访问: 当客户端向服务器发送请求时,服务器在处理过程中,客户端可以做其他的操作,不需要一直等待,效率偏高 AJA ...

  7. 关于Linux、python的PDF书籍整理(附带亲测的 IT 电子书网站)

    [18.1.3][在博客园发的文章不是很多呢,接下来的博客会转移到独立的个人博客网站上去了,具体的学习笔记和内容都会在独立网站上发布,后期还会有博主的个人资源库和教程还有独立网盘存储(可以关注一波哈) ...

  8. Centos 升级至 OpenSSH 8 rpm包制作

    背景 安全部门扫描系统漏洞,OpenSSH 7.9出现漏洞,需升级到8. 使用 rpmbuild 将源码包编译为 rpm包. yum install rpm-build zlib-devel open ...

  9. Window脚本学习笔记之BAT调用设置

    用一句bat脚本调用window的系统设置: rem 调用回收站 explorer.exe ::{645FF040-5081-101B-9F08-00AA002F954E} rem 检查Windows ...

  10. [转]python3 跨目录模块调用,你真的懂了吗?

    小伙伴们,你们有遇到过调用自己写的模块(跨目录模块调用),提示你ImportError:No module named ...的情况,如果有,而且到现在还没有搞明白的,我想说,你今天看对文章了. 这篇 ...