memcache一致性hash的php落成方式,略提及Cache工具的原理

前文提到的在系统安装Cache组件
Cache::getInstance()的时候,会去调用processManager去成立Cache的进程,然后以管道通讯的点子展开设置缓存和获得缓存。

前文连接,讲了es是哪些运行swoole服务的。

正文实例讲述了memcache一致性hash的php完成情势。分享给我们供大家参考。具体如下:

后边笔者写了一篇在 Laravel 4 框架中应用Ali云 OCS
缓存的小说,介绍了哪些通过扩张Laravel 4 来支撑供给 SASL 认证的Ali云 OCS 缓存服务。有网络好友问小编,ACE
的缓存怎么在 Laravel 4
中应用。小编当然认为应该可以完全用同一的主意,后来祥和尝尝的时候才意识,ACE
的缓存差别非常的大。所以再写一篇,介绍一下哪些在 Laravel 框架中动用Ali云
ACE 的缓存服务。

Cache是以单例形式达成的。构造器会举行如下操作

当中有三个工具类TableManager。这么些类为了处理进程间数据共享。是对swoole_table的一层封装
swoole_table一个依照共享内部存款和储蓄器和锁实现的超高质量,并发数据结构。用于缓解多进度/三十二线程数据共享和一块加锁难题。

如今在看一些分布式方面包车型大巴小说,所以就用php达成一致性hash来练练手,以前一般用的是最原始的hash取模做
分布式,当生产进程中加上或删除一台memcache都会造成数据的全数失效,一致性hash便是为了消除这么些标题,把失效数据降到最低,相关质感可以google一下!

哪些扩充 Laravel 的缓存驱动

//根据配置创建指定数目的Cache服务进程,然后启动。
$num = intval(Config::getInstance()->getConf("EASY_CACHE.PROCESS_NUM"));//默认配置数目是1,在Config.php里'EASY_CACHE.PROCESS_NUM'=>1
if($num <= 0){
   return;
}
$this->cliTemp = new SplArray();//这个数组以后会给单元测试时候单独使用,正常模式这个数组是不使用的
//若是在主服务创建,而非单元测试调用
if(ServerManager::getInstance()->getServer()){
    //创建了一个swoole_table ,表名为__Cache,里面存储data(后面就讲到其实这里存储的是操作Cache的指令)作用是用来做GC(防止Cache被撑爆)
    TableManager::getInstance()->add(self::EXCHANGE_TABLE_NAME,[
        'data'=>[
            'type'=>Table::TYPE_STRING,
            'size'=>10*1024
        ],
        'microTime'=>[
            'type'=>Table::TYPE_STRING,
            'size'=>15
        ]
    ],2048);
    $this->processNum = $num;
    for ($i=0;$i < $num;$i++){
        ProcessManager::getInstance()->addProcess($this->generateProcessName($i),CacheProcess::class);
    }
}

TableManager主要做了上边几件事
add方法
一经$list数组中有那个表名($name是2个表名可能叫做集合名),就起先化swoole_table,然后配置的字段类型数组实行创办

php完结功能有必然的缺乏,假若要高功效,照旧写扩充比较好

在 Laravel 4 中选用 Cache::get($key), Cache::put($key, $value, $minutes)
那样的代码时,实际上是造访 实例化的 Illuminate\Cache\Repository,
所以大家通过 Cache::extend 方法扩充自定义缓存驱动时,同样应当回到二个Illuminate\Cache\Repository 对象。

ProcessManager::getInstance()->addProcess($this->generateProcessName($i),CacheProcess::class)那句话才是Cache的主旨逻辑。

if(!isset($this->list[$name])){
    $table = new Table($size);
    foreach ($columns as $column => $item){
        $table->column($column,$item['type'],$item['size']);
    }
    $table->create();
    $this->list[$name] = $table;
}

经测试,伍个memcache,每种memcache生成九十九个虚拟节点,set加get一千次,与单个memcache直接set加get慢5倍,所以功用一般,有待优化!

Laravel 4 内置的 Memcached 缓存驱动,落成的流程是这么的:

ProcessManager::getInstance()那句话首要做了上边包车型地铁操作
ProcessManager
的__construct构造函数创立了二个swoole_table,表名是process_hash_map

get方法
直白重返swoole_table的实例。

在读书本文在此之前,最好通晓二分查找法。

1.开立三个规范 Memcached 类的新目的
2.用上一步创立的 Memcached 对象创设1个完结了
Illuminate\Cache\StoreInterface 接口的
Illuminate\Cache\MemecachedStore 对象。
3.用上一步创制的 MemcachedStore 对象成立二个Illuminate\Cache\Repository 对象。

TableManager::getInstance()->add(
    'process_hash_map',[
        'pid'=>[
            'type'=>Table::TYPE_INT,
            'size'=>10
        ]
    ],256
);

应用的地点有成都百货上千
前文提到的在系统安装Cache组件 Cache::getInstance()的时候

贯彻进度:

从而大家在扩张自定义的 Cache
驱动时,依据本身的状态,采用方面包车型地铁某多个步骤自定义,最后依旧要回去
Illuminate\Cache\Repository
对象。比如上一篇作品中,小编便是在第二步,创设标准
Memcached 对象之后,通过 setSaslAuthData() 方法设定 OCS
须求的用户名密码。之后第三步、第壹步并不需求自定义。

addProcess($this->generateProcessName($i),CacheProcess::class);
$this->generateProcessName($i)这么些代码相当的粗略正是基于$i来安装进度名称
addProcess 是在processList存储CacheProcess::class的实例,具体代码如下

构造方法做了之类事情

memcache的布局 ip+端口+虚拟节点种类号
做hash,使用的是crc32,形成叁个闭环。
对要操作的key实行crc32
二分法在编造节点环中查找如今的二个虚拟节点
从虚拟节点中领取真实的memcache ip和端口,做单例连接

ACE 的缓存服务

$key = md5($processName);
if(!isset($this->processList[$key])){
    try{

        $process = new $processClass($processName,$args,$async);
        $this->processList[$key] = $process;
        return true;
    }catch (\Throwable $throwable){
        Trigger::throwable($throwable);
        return false;
    }
}else{
    trigger_error("you can not add the same name process : {$processName}.{$processClass}");
    return false;
}
$num = intval(Config::getInstance()->getConf("EASY_CACHE.PROCESS_NUM"));//Config默认配置是1,如果配置为小于等于0则不开启Cache
if($num <= 0){
   return;
}
$this->cliTemp = new SplArray();
//若是在主服务创建,而非单元测试调用
if(ServerManager::getInstance()->getServer()){
    //创建table用于数据传递
    TableManager::getInstance()->add(self::EXCHANGE_TABLE_NAME,[
        'data'=>[
            'type'=>Table::TYPE_STRING,
            'size'=>10*1024
        ],
        'microTime'=>[
            'type'=>Table::TYPE_STRING,
            'size'=>15
        ]
    ],2048);
    //创建了一个__Cache的swoole_table表,字段为 data String 10240,microTime String 15的表
    $this->processNum = $num;
    for ($i=0;$i < $num;$i++){
        ProcessManager::getInstance()->addProcess($this->generateProcessName($i),CacheProcess::class);
    }
}

复制代码 代码如下:

Ali云 ACE 的缓存服务,跟私下认可的 OCS 有所差别:

那正是说CacheProcess::class的实例话做了如何操作呢
$this->cacheData = new
SplArray();//那里很要紧,为啥如此说各类Cache进度实际保存的缓存值都以在此间的,每一个Cache进度都有协调的3个cacheData数组
$this->persistentTime =
Config::getInstance()->getConf(‘EASY_CACHE.PERSISTENT_TIME’);
parent::__construct($processName, $args);
CacheProcess::class继承于AbstractProcess
AbstractProcess的构造方法

ProcessManager也是1个很重点的定义。其实就是1个管理职务映射的工具。

<?php
class memcacheHashMap {
        private $_node = array();
        private $_nodeData = array();
        private $_keyNode = 0;
        private $_memcache = null;
        //每种物理服务器生成虚拟节点个数
[注:节点数越来越多,cache分布的均匀性越好,同时set
get操作时,也更耗电源,10台物理服务器,采取200较为客体]
        private $_memcache一致性hash的php落成方式,略提及Cache工具的原理。virtualNodeNum = 200;
        private function __construct() {
                $config = array(//五个memcache服务器
                                                ‘127.0.0.1:11211’,
                                                ‘127.0.0.1:11212’,
                                                ‘127.0.0.1:11213’,
                                                ‘127.0.0.1:11214’,
                                                ‘127.0.0.1:11215’
                                        );
                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;//循环为各样memcache服务器成立200个虚拟节点
                        }
                }
               
ksort($this->_node);//创设出来的一千个虚拟节点依据键名从小到大排序
        }
        //实例化该类
        static public function getInstance() {
                static $memcacheObj = null;
                if (!is_object($memcacheObj)) {
                        $memcacheObj = new self();
                }
                return $memcacheObj;
        }
        //依照传来的键查找到呼应虚拟节点的职分
        private function _connectMemcache($key) {
                $this->_nodeData =
array_keys($this->_node);//全数的杜撰节点的键的数组
                $this->_keyNode = sprintf(“%u”,
crc32($key));//算出键的hash值
                $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->_memcache一致性hash的php落成方式,略提及Cache工具的原理。keyNode))  $nodeKey = $nodeKey2;
                }
                var_dump($this->_node[$nodeKey]);
                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];
        }
        //二分法依照提交的值找出以来的虚拟节点地点
        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);
        }
}
$runData[‘BEGIN_TIME’] = microtime(true);
//测试一千0次set加get
for($i=0;$i<10000;$i++) {
        $key = md5(mt_rand());
        $b = memcacheHashMap::getInstance()->set($key, time(), 10);
}
var_dump(number_format(microtime(true) –
$runData[‘BEGIN_TIME’],6));
$runData[‘BEGIN_TIME’] = microtime(true); $m= new Memcache;
$m->connect(‘127.0.0.1’, 11211);
for($i=0;$i<10000;$i++) {
        $key = md5(mt_rand());
        $b = $m->set($key, time(), 0, 10);
}
var_www.5929.com,dump(number_format(microtime(true) –
$runData[‘BEGIN_TIME’],6));
?>

1.通过 Alibaba(Alibaba)::Cache() 方法取得 Cache 对象。
2.ACE 的 Cache 对象与正式 Memcached 对象分裂,援救的办法简单。

$this->async = $async;
$this->args = $args;
$this->processName = $processName;
$this->swooleProcess = new \swoole_process([$this,'__start'],false,2);
ServerManager::getInstance()->getServer()->addProcess($this->swooleProcess);//然后swoole服务会addProcess一个Cache的任务进程。

此地能够看看ProcessManager::getInstance()->addProcess($this->generateProcessName($i),CacheProcess::class)

期望本文所述对大家的php程序设计有着协理。

由此,此次率先步获得的不是正统 Memcached 对象,由此就不能够创设Illuminate\Cache\MemcachedStore 对象。须求协调完结Illuminate\Cache\StoreInterface 接口。

__start方法首倘若给swoole_table,表名为process_hash_map插入当前CacheProcess的历程名为key,进度IDpid为value。并且注册进程退出的事件。

骨子里那里是因而ProcessManager,让swoole服务添加了一个历程。swoole的addProcess方法,文档链接

你也许感兴趣的篇章:

  • php 分库分表hash算法
  • php的hash算法介绍
  • PHP中对各类加密算法、Hash算法的速度测试对照代码
  • PHP
    Hash算法:Times33算法代码实例
  • PHP实现的各样hash算法长度及质量测试实例
  • PHP落成的一致性HASH算法示例
  • php常用hash加密函数
  • PHP随机生成唯一HASH值自定义函数
  • php对文件实行hash运算的点子
  • PHP实现的一致性Hash算法详解【分布式算法】

在控制台创制了缓存空间之后,会有唯一的“缓存空间名称”,然后通过
Alibaba::Cache(‘缓存空间名称’) 来收获 Cache 对象。以下便是落到实处 ACE
缓存服务驱动的步子:

if(PHP_OS != 'Darwin'){
    $process->name($this->getProcessName());
}
TableManager::getInstance()->get('process_hash_map')->set(
    md5($this->processName),['pid'=>$this->swooleProcess->pid]
);
ProcessManager::getInstance()->setProcess($this->getProcessName(),$this);
if (extension_loaded('pcntl')) {
    pcntl_async_signals(true);
}
Process::signal(SIGTERM,function ()use($process){
    $this->onShutDown();
    TableManager::getInstance()->get('process_hash_map')->del(md5($this->processName));
    swoole_event_del($process->pipe);
    $this->swooleProcess->exit(0);
});
if($this->async){
    swoole_event_add($this->swooleProcess->pipe, function(){
        $msg = $this->swooleProcess->read(64 * 1024);
        $this->onReceive($msg);
    });
}
$this->run($this->swooleProcess);

www.5929.com 1

1.为了便于修改,笔者在布署文件 app/config/cache.php 中扩张2个名为 ace
的键,存款和储蓄缓存空间名称。
2.然后创设一个 AceMemcachedStore 类,这一个类落成Illuminate\Cache\StoreInterface 接口。
3.末尾,用 AceMemcachedStore 对象来成立 Illuminate\Cache\Repository
对象。

$this->run($this->swooleProcess)那些函数是CacheProcess假若配置了persistentTime,就会打开一个定时器定时去取$file

Config::getInstance()->getConf(‘TEMP_DISportage’).”/{$processName}.data”;的数据备份,暗中同意是0也正是不会去做定时数据落地的操作

观望此间才是Cache组件在第3遍实例化的时候做的连带事务,计算正是创办了内定数量的Cache进程绑定到swoole服务器上。在全局的process_hash_map表中能找到相应的Cache进度ID。然后Cache进度是能够以管道方式来进行通信。

 

set缓存方法

public function set($key,$data)
{
    if(!ServerManager::getInstance()->isStart()){
        $this->cliTemp->set($key,$data);
    }
    if(ServerManager::getInstance()->getServer()){
        $num = $this->keyToProcessNum($key);
        $msg = new Msg();
        $msg->setCommand('set');
        $msg->setArg('key',$key);
        $msg->setData($data);
        ProcessManager::getInstance()->getProcessByName($this->generateProcessName($num))->getProcess()->write(\swoole_serialize::pack($msg));//直接把需要缓存的数据,封装成msg然后write给hash映射到的Cache进程
    }
}

当进程取获得的时候会回调onReceive方法

public function onReceive(string $str,...$agrs)
{
    // TODO: Implement onReceive() method.

    $msg = \swoole_serialize::unpack($str);
    $table = TableManager::getInstance()->get(Cache::EXCHANGE_TABLE_NAME);
    if(count($table) > 1900){
        //接近阈值的时候进行gc检测
        //遍历Table 依赖pcre 如果发现无法遍历table,检查机器是否安装pcre-devel
        //超过0.1s 基本上99.99%为无用数据。
        $time = microtime(true);
        foreach ($table as $key => $item){
            if(round($time - $item['microTime']) > 0.1){
                $table->del($key);
            }
        }
    }
    if($msg instanceof Msg){
        switch ($msg->getCommand()){
            case 'set':{
                $this->cacheData->set($msg->getArg('key'),$msg->getData());
                break;
            }
            case 'get':{
                $ret = $this->cacheData->get($msg->getArg('key'));
                $msg->setData($ret);
                $table->set($msg->getToken(),[
                    'data'=>\swoole_serialize::pack($msg),
                    'microTime'=>microtime(true)
                ]);
                break;
            }
            case 'del':{
                $this->cacheData->delete($msg->getArg('key'));
                break;
            }
            case 'flush':{
                $this->cacheData->flush();
                break;
            }
            case 'enQueue':{
                $que = $this->cacheData->get($msg->getArg('key'));
                if(!$que instanceof \SplQueue){
                    $que = new \SplQueue();
                    $this->cacheData->set($msg->getArg('key'),$que);
                }
                $que->enqueue($msg->getData());
                break;
            }
            case 'deQueue':{

                $que = $this->cacheData->get($msg->getArg('key'));
                if(!$que instanceof \SplQueue){
                    $que = new \SplQueue();
                    $this->cacheData->set($msg->getArg('key'),$que);
                }
                $ret = null;
                if(!$que->isEmpty()){
                    $ret = $que->dequeue();
                }
                $msg->setData($ret);
                //deQueue 有cli 服务未启动的请求,但无token
                if(!empty($msg->getToken())){
                    $table->set($msg->getToken(),[
                        'data'=>\swoole_serialize::pack($msg),
                        'microTime'=>microtime(true)
                    ]);
                }
                break;
            }
            case 'queueSize':{
                $que = $this->cacheData->get($msg->getArg('key'));
                if(!$que instanceof \SplQueue){
                    $que = new \SplQueue();
                }
                $msg->setData($que->count());
                $table->set($msg->getToken(),[
                    'data'=>\swoole_serialize::pack($msg),
                    'microTime'=>microtime(true)
                ]);
                break;
            }
        }
    }
}

那边一初步会进展缓存GC确认保证内部存储器不会撑爆

set方法会直接给$this->cacheData,设置缓存值。

 

get方法相比较独特,它会去给Cache进程发送get的通令,然后Cache读取到命令会将值写到_Cache,Swoole_table表中。然后再去读取(那么些会有1个while循环,类似自旋)出缓存内容。那样的利益,能够确定保证能够读取到立时的数额缓存,不会因为高并发读取到最新的缓存值内容。而且还是能够更实惠的做gc,幸免Cache内部存款和储蓄器撑爆。

public function get($key,$timeOut = 0.01)
{
    if(!ServerManager::getInstance()->isStart()){
        return $this->cliTemp->get($key);
    }
    $num = $this->keyToProcessNum($key);
    $token = Random::randStr(9);//这个是一个凭证,是确保获取到自己此刻想获取的cache数据,和事务类似为了保证可重复读
    $process = ProcessManager::getInstance()->getProcessByName($this->generateProcessName($num));
    $msg = new  Msg();
    $msg->setArg('timeOut',$timeOut);
    $msg->setArg('key',$key);
    $msg->setCommand('get');
    $msg->setToken($token);
    $process->getProcess()->write(\swoole_serialize::pack($msg));
    return $this->read($token,$timeOut);
}

$process->getProcess()->write(\swoole_serialize::pack($msg))发那几个包给Cache进度,Cache进度会展开下边这一个操作

$ret = $this->cacheData->get($msg->getArg('key'));//获取到当前的缓存值
$msg->setData($ret);
//将当前的内容设置到_Cache表中,token是请求的时候发过来的凭证原样拼装。这有什么好处呢,就是确保在高并发下,在A时刻获取的缓存,不会拿到后面B时刻更新的值。
$table->set($msg->getToken(),[
    'data'=>\swoole_serialize::pack($msg),
    'microTime'=>microtime(true)
]);

$this->read($token,$timeOut);

//这里的操作是直接从_Cache表中获取缓存数据,如果缓存存在并且进程调度没有超时,然后在表中将取过数据的内容删除掉返回
private function read($token,$timeOut)
{
    $table = TableManager::getInstance()->get(self::EXCHANGE_TABLE_NAME);
    $start = microtime(true);
    $data = null;
    while(true){
        usleep(1);
        if($table->exist($token)){
            $data = $table->get($token)['data'];
            $data = \swoole_serialize::unpack($data);
            if(!$data instanceof Msg){
                $data = null;
            }
            break;
        }
        if(round($start - microtime(true),3) > $timeOut){
            break;
        }
    }
    $table->del($token);
    if($data){
        return $data->getData();
    }else{
        return null;
    }
}

 

超前略带讲解一下Cache的set方法加深概念

上面来看现实的代码完成:

//讲解一下Cache的set方法加深概念
if(!ServerManager::getInstance()->isStart()){//兼容测试模式。也就是不开启服务的情景下直接是clitemp中取缓存数据
    $this->cliTemp->set($key,$data);
}
if(ServerManager::getInstance()->getServer()){
    $num = $this->keyToProcessNum($key);//这里是通过key然后hash到应该投放的Cache进程中去。
    $msg = new Msg();
    $msg->setCommand('set');
    $msg->setArg('key',$key);
    $msg->setData($data);
    //下面一句话还是挺复杂的,根据key名hash到ProcessManager对应的映射,然后获取到swoole_process的实例,以swoole的write函数向管道内写入数据。
    ProcessManager::getInstance()->getProcessByName($this->generateProcessName($num))->getProcess()->write(\swoole_serialize::pack($msg));
    //在写完数据后,在CacheProcess的onReceive方法中可以看到对应setCommand的操作细节。其实数据都被写到了一个Arr数组中。下篇接着讲一下Cache的实现细节。这节还是主要讲TableManager和它的相关作用.
}

编码完结自定义 ACE 缓存驱动:

率先步,修改配置文件。打开 app/config/cache.php,在最后扩展一行:

复制代码 代码如下:

// 内定缓存空间名称
‘ace’ => ‘lblog-cache’,

第2步,为了方便,把温馨的类公事放在 src/Ace 目录下,使用 Ace
作为命名空间。

1.在 app 的同级目录成立目录 src/Ace。
2.打开 composer.json 文件,修改 autoload 节,在 classmap 下边用 psr-0
也许 psr-4 来机关加载文件。

复制代码 代码如下:

“autoload”: {
    “classmap”: [
        // autoload class
    ],
    “psr-4”: {
      “Ace\\”: “src/Ace”
    }
},

创建 src/Ace/AceMemcachedStore.php 文件,代码如下:

复制代码 代码如下:

<?php
 
namespace Ace;
use Illuminate\Cache\StoreInterface;
use Illuminate\Cache\TaggableStore;
 
class AceMemcachedStore extends TaggableStore implements StoreInterface
{
 
    protected $memcached;
    protected $prefix;
 
    public function __construct($space, $prefix = ”) {
        $this->memcached = \Alibaba::Cache($space);
        $this->prefix = strlen($prefix) > 0 ? $prefix.’:’ : ”;
    }
 
    /**
     * Retrieve an item from the cache by key.
     *
     * @param  string $key
     * @return mixed
     */
    public function get($key)
    {
        $value = $this->memcached->get($this->prefix.$key);
        if(is_bool($value) && $value === false) {
            return null;
        }
        return $value;
    }
 
    /**
     * Store an item in the cache for a given number of minutes.
     *
     * @param  string $key
     * @param  mixed $value
     * @param  int $minutes
     * @return boolean
     */
    public function put($key, $value, $minutes)
    {
        return $this->memcached->set($this->prefix.$key,
$value, $minutes);
    }
 
    /**
     * Increment the value of an item in the cache.
     *
     * @param  string $key
     * @param  mixed $value
     * @return boolean
     */
    public function increment($key, $value = 1)
    {
        return $this->memcached->increment($this->prefix.$key,
$value);
    }
 
    /**
     * Decrement the value of an item in the cache.
     *
     * @param  string $key
     * @param  mixed $value
     * @return boolean
     */
    public function decrement($key, $value = 1)
    {
        return $this->memcached->decrement($this->prefix.$key,
$value);
    }
 
    /**
     * Store an item in the cache indefinitely.
     *
     * @param  string $key
     * @param  mixed $value
     * @return boolean
     */
    public function forever($key, $value)
    {
        return $this->memcached->set($key, $value, 0);
    }
 
    /**
     * Remove an item from the cache.
     *
     * @param  string $key
     * @return boolean
     */
    public function forget($key)
    {
        return $this->memcached->delete($this->prefix.$key);
    }
 
    /**
     * Remove all items from the cache.
     *
     * @return void
     */
    public function flush()
    {
        //$this->memcached->flush();
        return false;
    }
 
    public function getMemcached()
    {
        return $this->memcached;
    }
    /**
     * Get the cache key prefix.
     *
     * @return string
     */
    public function getPrefix()
    {
        return $this->prefix;
    }
}

那段代码比较简单,可是要特别注意一下 get($key) 方法的完结。标准
memcached 以及 ACE 的缓存对象的 get
方法都以key有效时重回对应的缓存值,不然重回false,而在 Laravel 4
中,是因而检查和测试 get 方法再次来到的是或不是 null
来做判断,所以那边须要处理一下,返回缓存值大概null。

AceMemcachedStore类已经创制好了,接下去在 bootstrap/start.php 文件中扩大Cache:

开辟 bootstrap/start.php, 添加以下代码:

复制代码 代码如下:

// 扩张名为 ace 的缓存驱动
Cache::extend(‘ace’, function($app)
{
    // 从 app/config/cache.php 文件中读取 “ace” 的值
    $space = $app[‘config’][‘cache.ace’];
    
    // 从 app/config/cache.php 文件中读取 “prefix” 的值
    $prefix = $app[‘config’][‘cache.prefix’];
    
    // 创建 \Ace\AceMemcachedStore 对象
    $store = new \Ace\AceMemcachedStore($space, $prefix);
    
    // 制造并回到 \Illuminate\Cache\Repository 对象
    return new \Illuminate\Cache\Repository($store);
 
});

点名系统利用 ‘ace’ 作为缓存驱动:打开 app/config/cache.php,找到
‘driver’ => ‘…’ 所在行,修改为:’driver’ => ‘ace’.

行使和范围

通过以上操作,就能够在 Laravel 4 中调用 ACE
的缓存服务,使用上与平日的用法完全一致,比如:

复制代码 代码如下:

// 添加缓存,有效时间10秒钟
Cache::put(‘my_key’, ‘my value’, 10);
 
// 读取缓存
Cache::get(‘my_key’)
 
// 判断缓存是还是不是存在
Cache::has(‘my_key’)
 
// 数据查询缓存
$users = DB::table(‘users’)->remember(10)->get();

然则出于 ACE 缓存对象自笔者的限定,只好删除钦定 key
的缓存对象,无法遍历、全量操作,因而 Cache::flush()
方法就无法采纳。在地点的 AceMemcachedStore 对象中,flush
方法没有做别的操作,只是重临 false.

你或许感兴趣的篇章:

  • Laravel
    Memcached缓存驱动的配置与利用措施分析
  • Laravel中扩展Memcached缓存驱动落成应用Ali云OCS缓存
  • Laravel使用Caching缓存数据减轻数据库查询压力的章程
  • Laravel框架数据库CURubiconD操作、连贯操作总括
  • PHP开发框架Laravel数据库操作方法计算
  • 跟作者学Laravel之迅捷入门
  • Laravel框架中扩充函数、扩大自定义类的主意
  • Laravel框架路由配置总结、设置技巧大全
  • Laravel中运用自个儿编写类库的3种办法
  • Laravel使用memcached缓存对作品增加和删除改查进行优化的法子

Leave a Comment.