PHP+CI框架+Memcache集成
一、目录结构

二、具体代码
MemcacheCluster.php
<?php /**
* 一致性哈希memcache分布式,采用的是虚拟节点的方式解决分布均匀性问题,查找节点采用二分法快速查找
*/
class MemcacheCluster
{
private $_node = array();
private $_nodeData = array();
private $_keyNode = 0;
private $_memcache = null; //每个物理服务器生成虚拟节点个数 [注:节点数越多,cache分布的均匀性越好,同时set get操作时,也更耗资源,10台物理服务器,采用200较为合理]
private $_virtualNodeNum = 2; private function __construct()
{
/* 放入配置文件 */
$config = array(
'127.0.0.1:11211',
); 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;
}
//var_dump($this->_node[$nodeKey]); 127.0.0.1:11211_20
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);
} }
memcached.php
<?php
/**
* Created by PhpStorm.
* User: 25754
* Date: 2019/9/17
* Time: 16:17
*/ include_once APPPATH . "/third_party/MemcacheCluster.php"; class Memcached
{
public function set($key, $value, $expire = 0)
{
return MemcacheCluster::getInstance()->set($key, $value, $expire);
} public function add($key, $value, $expire = 0)
{
return MemcacheCluster::getInstance()->add($key, $value, $expire);
} public function delete($key)
{
return MemcacheCluster::getInstance()->delete($key);
} public function get($key)
{
return MemcacheCluster::getInstance()->get($key);
}
}
MY_Controller.php
class Home_Controller extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->library('memcached', null, 'memcache');
}
}
index.php
class Index extends Home_Controller
{
public function __construct()
{
parent::__construct();
$this->load->set_home_view_dir();
} public function index()
{
//要设置随机缓存时间,防止缓存失效,大的访问量造成数据库崩溃
$time = rand(1, 10);
$key = md5("yy");
$cacheValue = $this->memcache->get($key);
if (!$cacheValue) {
//随机保存时间
$flag = $this->memcache->set($key, "yang", $time);
if ($flag) {
echo "缓存时间:".$time."秒";
}
}
echo $cacheValue;
}
}
PHP+CI框架+Memcache集成的更多相关文章
- CI框架中集成CKEditor编辑器的教程
CKEditor是在很多开发过程中都会用到的一个富文本编辑器,那么如何在CI框架中使用它呢?这里介绍了在CI下使用CKEditor的方法,版本比较低,是在CI 1.7.3下使用fckeditor 2. ...
- 【军哥谈CI框架】之CI中集成百度UEditor
Hello,各位亲,新的一周来临啦,很高兴这么快又跟大家伙见面!话说上一回,军哥带大家用JQuery写了一个城市级联菜单的例子 ,不知道亲们学会了多少,是否自己可以独立写出来了呢. 军哥很是期待大家学 ...
- **【ci框架】PHP的CI框架集成Smarty的最佳方式
因为CI自带的模板功能不是很方便,所以大家普遍采用集成Smarty的方式来弥补CI这方面的不足. 本人在网上看了不少CI集成Smarty的教程,包括咱们CI论坛里面的一个精华帖子 http://cod ...
- CI框架使用PHPmail插件发送QQ邮件:
有助请顶,不好请评.0:33 2016/3/12CI框架使用PHPmail插件发送QQ邮件:发送成功,不过修改了主机参数,还包含了一个phpmail中的一个另外的文件,详见下方:参见:http://c ...
- CI框架源码阅读笔记1 - 环境准备、基本术语和框架流程
最开始使用CI框架的时候,就打算写一个CI源码阅读的笔记系列,可惜虎头蛇尾,一直没有行动.最近项目少,总算是有了一些时间去写一些东西.于是准备将之前的一些笔记和经验记录下来,一方面权作备忘,另一方面时 ...
- **【ci框架】精通CodeIgniter框架
http://blog.csdn.net/yanhui_wei/article/details/25803945 一.大纲 1.codeigniter框架的授课内容安排 2.codeigniter框架 ...
- CI框架大纲总结
一.大纲 1.codeigniter框架的授课内容安排 2.codeigniter框架的简介 |-----关于框架的概念 |-----使用CI框架的好处 |-----为什么选择CI框架 3.codei ...
- 【ci框架基础】之部署百度编辑器
在ci框架下加载编辑器,现在复习下内容.我的框架文件名称为ci 1.下载百度编辑器ueditor,http://ueditor.baidu.com/ 一般情况下下载ubuilder版即可,并将uedi ...
- PHP的CI框架流程基本熟悉
CI框架是PHP的一个快速开发框架,我是目前的公司项目后台语言用的PHP,因为我做前端开发,需要用php去填充页面数据,所以就开始去了解这个框架,学习了一些php和数据库的东西,这篇文章先具体介绍CI ...
随机推荐
- Window环境下使用多个Git账号(github,gitee,gitlab,gogs等)
个人电脑之前已经设置好github账号了,公司用的是gitlab私服,一直互不干扰,因为用的是不同的电脑,也就懒得配置git多账户环境.最近看了一下多年空空如也的码云,想着怎么的也会用到gitee来托 ...
- Python练习_装饰器、生成器_day12
装饰器 装饰器篇: 1.编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码. def login(func): def inner( ...
- 3 webpack 4 加vue 2.0生产环境搭建
1 在前两篇笔记中已经能把开发环境弄好了,接来下构建他的生产环境 2 使用npm 安装url-loader和file-loader来支持图片和字体 npm install --save-dev url ...
- python matplotlib动态绘图
matplotlib animation的官方文档: http://matplotlib.org/api/animation_api.html 接下来完成一个实时获取cpu数值,并绘图的功能. 1.动 ...
- iOS有哪些数据类型/基本数据类型?
简述 本文主要探究使用OC作为iOS开发语言时,我们能使用哪些数据类型. 一切类型始于C. C语言的类型 基本数据类型: 基本数据类型(fundamental data types)也叫原始数据类型( ...
- linux服务脚本
#!/bin/sh ARG=$1 case $ARG in start): nohup /path/program & ;; stop): pkill program ;; restart): ...
- 【vue开发】vue插件的install方法
MyPlugin.install = function (Vue, options) { // 1. 添加全局方法或属性 Vue.myGlobalMethod = function () { // 逻 ...
- 【python】python configparser模块
ConfigParser模块在python中用来读取配置文件,配置文件的格式跟windows下的ini配置文件相似,可以包含一个或多个节(section), 每个节可以有多个参数(键=值).使用的配置 ...
- [Docker][Hadoop]基于Docker1.12.3 搭建Hadoop 2.7.2 集群以及简单分析
一 Hadoop简介 Hadoop 2.7.2 Doc refer to http://hadoop.apache.org/docs/r2.7.2/ HDFS (The following is a ...
- windwos服务器 无法与本地电脑进行复制粘贴解决办法
之前复制粘贴功能可以使用 现在突然间不能使用了 1.打开任务管理器,查看进程,如果有 rdpclip.exe 进程,先关闭该进程2.开始->运行->rdpclip.exe,重新运行此程序 ...