【亚洲必赢官网】memcache一致性hash的php达成格局,Laravel框架中完结应用Ali云ACE缓存服务

前文提到的在系统设置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是以单例情势达成的。构造器会实行如下操作

【亚洲必赢官网】memcache一致性hash的php达成格局,Laravel框架中完结应用Ali云ACE缓存服务。内部有一个工具类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是三个表名可能叫做集合名),就开首化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加get1000次,与单个memcache直接set加get慢5倍,所以作用一般,有待优化!

Laravel 4 内置的 Memcached 缓存驱动,完毕的流程是这般的:

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

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

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

1.创办一个正式 Memcached 类的新对象
2.用上一步创设的 Memcached 对象创制一个贯彻了
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
供给的用户名密码。之后第3步、第三步并不必要自定义。

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也是三个很重点的概念。其实就是二个管制职务映射的工具。

<?php
class memcacheHashMap {
        private $_node = array();
        private $_nodeData = array();
        private $_keyNode = 0;
        private $_memcache = null;
        //每一种物理服务器生成虚拟节点个数
[注:节点数越来越多,cache分布的均匀性越好,同时set
get操作时,也更耗财富,10台物理服务器,选择200较为客体]
        private $_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();//找出相应的虚拟节点
               
//要是超出环,从头再用二分法查找1个多年来的,然后环的头尾做判断,取最接近的节点
                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]);
                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);
//测试30000次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_dump(number_format(microtime(true) –
$runData[‘BEGIN_TIME’],6));
?>

1.因此 阿里Baba(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(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);

亚洲必赢官网 1

1.为了便利修改,笔者在配备文件 app/config/cache.php 中加进多个名为 ace
的键,存款和储蓄缓存空间名称。
2.然后创制二个 AceMemcachedStore 类,那么些类实现Illuminate\Cache\StoreInterface 接口。
3.末段,用 AceMemcachedStore 对象来创建 Illuminate\Cache\Repository
对象。

$this->run($this->swooleProcess)这几个函数是CacheProcess假诺配置了persistentTime,就会开启三个定时器定时去取$file

Config::getInstance()->getConf(‘TEMP_DI猎豹CS6’).”/{$processName}.data”;的数据备份,默许是0也正是不会去做定时数据落地的操作

观望那里才是Cache组件在率先次实例化的时候做的连锁事情,总括正是成立了点名数量的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表中。然后再去读取(那几个会有2个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’,

其次步,为了有利于,把本人的类公事放在 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
的缓存服务,使用上与通常的用法完全一致,比如:

复制代码 代码如下:

// 添加缓存,有效时间十二分钟
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框架数据库CU奥迪Q5D操作、连贯操作计算
  • PHP开发框架Laravel数据库操作方法总计
  • 跟小编学Laravel之快捷入门
  • Laravel框架中扩展函数、扩大自定义类的点子
  • Laravel框架路由配置总结、设置技巧大全
  • Laravel中使用本人编排类库的3种办法
  • Laravel使用memcached缓存对小说增加和删除改查举行优化的法门
网站地图xml地图