75142913在线留言
【Laravel笔记】缓存的使用详解_PHP技术_网络人

【Laravel笔记】缓存的使用详解

Kwok 发表于:2022-04-05 14:05:09 点击:29 评论: 0

缓存可以大大减少数据库查询操作以减轻服务器的压力,特别是一些短时间内的大量任务执行(搜索、点赞、文章查看数更新等),像这样频繁对数据库操作会产生大量的查询,我们可以将其缓存起来,在服务器空闲的时候批量操作,这样我们就使用缓存系统来完成,Larave的缓存特别的强大,如果在 config/cache.php 未配置使用更高性能的Redis、Memcached类软件时,默认将内容缓存到storage/framework/cache/data文件夹里。

一、缓存基本操作

在正常的项目中,我们都会使用到mysql数据库(如果使用默认的文件缓存则可以使用默认即可),而以不想安装Redis的情况下(Redis我个人超爱,缓存到内存里,速度可以起飞),首先快速了解一下Laravel为我们提供的各种方法:

  1. Cache::put(key, data, duration)  接受3个关键参数:缓存Key,缓存数据,缓存时间(秒)
  2. Cache::get(key)  通过key获取缓存data
  3. Cache::many(keys)  同时缓存多个key与data
  4. Cache::putMany(data, duration)  接受2个参数,data 为一个数组,缓存时间秒
  5. Cache::increment()  增加缓存的整数值
  6. Cache::decrement()  减少缓存的整数值
  7. Cache::forever(key,data)  同put,但不需要指定缓存时间,这是一个长时间有效的
  8. Cache::forget(key)  删除缓存 
  9. Cache::flush()  清除所有缓存
  10. Cache::remember(key, duration, closure)  接受3个参数,缓存key,缓存时间(秒),闭包返回要缓存的数据
  11. Cache::rememberForever()  使用同上但缓存不过期。

这里只是针对提供的方法快速浏览,要了解缓存使用的详细方法,请继续看下面的内容!

文章缓存实例:http://www.55mx.com/php/214.html

找到config/cache.php里的default,并修改为下面的database缓存项:

'default' => env('CACHE_DRIVER', 'database'),

然后使用artisan生成可迁移的缓存表:

php artisan cache:table

执行上面的命令后,会在database/migrations目录生成一个当前日期的迁移表,如我刚才生成的名字为:database/migrations/2022_04_05_062757_create_cache_table.php,然后使用表迁移命令:

php artisan migrate --env=local --path=./database/migrations/2022_04_05_062757_create_cache_table.php

映射到我们配置的mysql中,通过迁移文件就可以得到生成的表结构:

public function up()
{
    //创建cache表(实际缓存)
    Schema::create('cache', function (Blueprint $table) {
        $table->string('key')->primary(); //key为主键
        $table->mediumText('value'); //使用mediumText缓存内容
        $table->integer('expiration'); //缓存有效期(过期时间)
    });
    //创建cache_locks表(原子锁)
    Schema::create('cache_locks', function (Blueprint $table) {
        $table->string('key')->primary(); //要锁定的key
        $table->string('owner'); //所有者
        $table->integer('expiration'); //锁定时间 
    });
}

进入mysql可以看到多出来了上面迁移的2个表,结果按注释一样。做好上面的准备工作后,我们就可以对缓存进行CRUD操作了(增删改查)。

PS:我为什么要使用mysql做为缓存而不使用默认的文件 ,当前使用文件只上了上面的配置,但要清理缓存的时候会比较麻烦,我使用mysql的主要目的是可以使用1行命令清空缓存表即可。

1、获取缓存

Laravel的缓存底层实际位于Facade里的Cache操作类里,所以在使用前我们应该先引包:

<?php

namespace AppHttpControllers;
use IlluminateSupportFacadesCache;//引入缓存操作包
class UserController extends Controller
{
    public function index()
    {
        $value = Cache::get('key');//获取key缓存
        
    }
}

我们通过->get()方法获取key缓存,如果缓存并不存在或者已过期的情况下,则会返回一个null。我们可以设置->get()的第2个参数将其做为默认值:

$value = Cache::get('key', '默认值');

默认值支持使用一个闭包来实现更高级的操作:

$value = Cache::get('key', function () {
    return DB::table(...)->get();//当key不存在在执行此闭包
});

 2、设置缓存

使用->put()方法将数据缓存起来:

Cache::put('url', 'https://www.meishiq.com');//缓存一个url键

如果未指定第二个参数,即有效期时,则为长期有效哦~

上面忘记设置有效期了,下面可以通过再次设置使用第2参数指定有效期:

Cache::put('url', 'http://www.55mx.com/', now()->addMinutes(10));//有效时间为10分钟

有时候我们我们需要检测数据是否存在,如果存在就不存了,不存在的时候才缓存数据,可以使用->add()方法:

Cache::add('key', 'value', $seconds);//$seconds为有效期,单位秒

如果需要设置一个永久有效的缓存时,我们通常使用->forever()方法:

Cache::forever('key', 'value');//如果要删除此缓存需要使用下面的forget方法哦

小提示:如果您使用的是 Memcached 驱动程序,则当缓存达到其大小限制时,可能会删除「永久」存储的项目。

 3、删除缓存

如果缓存不在使用时,我们需要通过-> forget()方法将其释放掉以节约资源: 

Cache::forget('key');//删除key

当然也可以通过put将缓存时间改为负数或者为0也能自动释放掉。

如果缓存的项有点多,我们需要通过:

Cache::flush();//清空缓存

注意:刷新缓存不会考虑您配置的缓存「前缀」,并且会从缓存中删除所有条目。在清除由其他应用程序共享的缓存时,请仔细考虑这一点。

4、更新缓存

 increment 和 decrement 方法可用于调整缓存中整数项的值。这两种方法都接受一个可选的第二个参数,指示增加或减少项目值的数量: 

Cache::increment('key');//key++
Cache::increment('key', $amount);//key = key + $amount
Cache::decrement('key');//key--
Cache::decrement('key', $amount);//key = key - $amount

5、检测缓存

如果要检测缓存是否可用时我们需要使用到->has()方法,当key存在返回true,过期或者为空时返回false:

if (Cache::has('key')) {
    //key存在才执行里面的代码
}

二、缓存进阶操作

1、切换存储引擎

在上面的缓存基本操作里我们将数据存在了数据库里,但我们又想临时使用一下file或者其它缓存时,我们可以通过调用store方法指定要操作的缓存存储引擎:

$value = Cache::store('file')->get('foo');//获取file里的缓存
Cache::store('redis')->put('bar', 'baz', 600); //将缓存到Redis里,有效期10分钟

2、查询并存储缓存

有时候我们需要使用缓存里的一个设置值,存在则返回,不存在时,我们需要通过从数据库里查询并缓存起来:

//尝试通过remember从缓存里读取缓存
$settings = Cache::remember('settings', $seconds, function () {
    return DB::table('settings')->get();//缓存不存在从数据库里获取设置项存缓存起来,有效期$seconds
});

上面的$seconds指定了缓存的有效时,如果你希望可以长时间缓存,则可以将上面的remember替换为rememberForever(将缓存999999999秒):

//rememberForever不需要设置缓存时间
$value = Cache::rememberForever('users', function () {
    return DB::table('users')->get();
});

3、查询并删除缓存

当我们设置缓存只用一次就无效的场景时,可以使用->pull()方法,使用起来与->get()方法一样:

$value = Cache::pull('key');//查询到key返回给$value并删除key缓存,如果缓存并不存在时,返回null

4、使用助手函数快速调用缓存方法

使用全局的助手函数可以快速的调用缓存方法:

$value = cache('key');//获取key
cache(['key' => 'value'], $seconds);//设置key=value,有效期$seconds
cache(['key' => 'value'], now()->addMinutes(10));//设置key=value,有效期10分钟

当不带任何参数调用 cache 函数时,它会返回 IlluminateContractsCacheFactory 实现的实例,允许您调用其他缓存方法:

//同上面的cache:: remember
cache()->remember('users', $seconds, function () {
    return DB::table('users')->get();
});

5、在Redis与memcached里使用标签以获得最佳性能

缓存标签允许您在缓存中标记相关项目,然后刷新所有已分配给定标签的缓存值。您可以通过传入标记名称的有序数组来访问标记缓存。例如,让我们访问一个标记的缓存并将一个值「put」缓存中:

Cache::tags(['people', 'artists'])->put('John', $john, $seconds);//设置people的artist项为John= $john
Cache::tags(['people', 'authors'])->put('Anne', $anne, $seconds);

如果要获取上面的设置项:

$john = Cache::tags(['people', 'artists'])->get('John');//获取刚才设置的$john

$anne = Cache::tags(['people', 'authors'])->get('Anne');

查询后我们不再需要时,可以通过->flush()方法清除缓存:

Cache::tags(['people', 'authors'])->flush();
//相反,此语句将仅删除带有 authors 标记的缓存值,因此将删除 Anne,但不会删除 John:
Cache::tags('authors')->flush();

6、原子锁

多核编程中,由于并发的问题,可以会同时操作一个数据库,缓存也可能被多个请求同时操作,为了保存数据的原子性,我们可以使用原子锁功能,将重要的数据锁定起来,不让其它请求破坏。在上面的迁移表中,Laravel为我们生成了一个原子锁表,我们可以通过 Cache::lock 方法来创建与管理锁:

$lock = Cache::lock('foo', 10);//锁定foo,时间10秒

if ($lock->get()) {
    //10 秒后才能返回此数据 ...
    $lock->release();
}

get 方法也接受一个闭包。闭包执行后,Laravel 会自动释放锁:

Cache::lock('foo')->get(function () {
    // 锁定无限期获得并自动释放...
});

如果在您请求时锁不可用,您可以指示 Laravel 等待指定的秒数。如果在指定的时间限制内无法获取锁,则会抛出LockTimeoutException异常,所以我们应该使用try来处理:

use IlluminateContractsCacheLockTimeoutException;
$lock = Cache::lock('foo', 10);
try {
    $lock->block(5);
    // 等待最多 5 秒后获得锁定...
} catch (LockTimeoutException $e) {
    // 无法获取锁...
} finally {
    optional($lock)->release();
}

上面的例子可以通过将闭包传递给 block 方法来简化。当一个闭包被传递给这个方法时,Laravel 将尝试在指定的秒数内获取锁,并在闭包执行后自动释放锁:

Cache::lock('foo', 10)->block(5, function () {
    // 等待最多 5 秒后获得锁定...
});

跨进程管理锁:有时,您可能希望在一个进程中获取锁并在另一个进程中释放它。例如,您可能在 Web 请求期间获取锁,并希望在由该请求触发的排队作业结束时释放锁。在这种情况下,您应该将锁的作用域「owner 令牌」传递给排队的作业,以便作业可以使用给定的令牌重新实例化锁。

$podcast = Podcast::find($id);//排队作业ID

$lock = Cache::lock('processing', 120);//锁定120秒

if ($lock->get()) {
    ProcessPodcast::dispatch($podcast, $lock->owner());//通过锁的 owner 方法将锁的所有者令牌传递给排队的作业
}

在我们应用程序的 ProcessPodcast 作业中,我们可以使用所有者令牌恢复和释放锁:

Cache::restoreLock('processing', $this->owner)->release();//恢复锁并返回
Cache::lock('processing')->forceRelease();//不考虑它的当前所有者
除非注明,网络人的文章均为原创,转载请以链接形式标明本文地址:https://www.55mx.com/post/207
标签:缓存cacheKwok最后编辑于:2022-04-11 21:11:26
0
感谢打赏!

《【Laravel笔记】缓存的使用详解》的网友评论(0)

本站推荐阅读

热门点击文章