美文网首页
laravel 文件缓存的过期处理机制原理

laravel 文件缓存的过期处理机制原理

作者: 云龙789 | 来源:发表于2019-06-29 15:07 被阅读0次

前言

我们在使用 Cache 这个 Facede 的时候,可以知道 laravel 是提供了六种缓存实现方案,这六种配置在 app/cache.php 的 stores 数组配置中可以看到。对于 redis 和 memcached 这种实现方式,相信我们大家都很了解,直接有相关的方法可以实现键值对的添加和取消。但是如果使用文件作为缓存,是怎么实现的过期时间处理呢?

文件缓存实现原理

  • 1.存储的数据格式
原数据
\Cache::put('key',['value',1,2,3,'e'],1);
缓存中格式
1561791364a:5:{i:0;s:5:"value";i:1;i:1;i:2;i:2;i:3;i:3;i:4;s:1:"e";}

   public function put($key, $value, $minutes)
    {
        $this->ensureCacheDirectoryExists($path = $this->path($key));
dd($this->expiration($minutes),$this->expiration($minutes).serialize($value));
        $this->files->put(
            $path, $this->expiration($minutes).serialize($value), true
        );
    }
1561791599
"1561791599a:5:{i:0;s:5:"value";i:1;i:1;i:2;i:2;i:3;i:3;i:4;s:1:"e";}"
    1. 实现原理

其实是以键为文件名,文件中,过期时间为键,序列化的值为值的值。
在取值的时候,如果发现时间过期,则删除本文件
redis 的清除过期键值缓存策略也包括这种方案

缓存文件
    1. 缓存文件夹的处理

可以看到文件上还有两级文件夹,但从代码中没有找到删除文件夹的处理。我个人想,可能文件夹是不会删除的

   protected function path($key)
    {
        $parts = array_slice(str_split($hash = sha1($key), 2), 0, 2);
        dump($parts,sha1($key));
dd($this->directory.'/'.implode('/', $parts).'/'.$hash);
        return $this->directory.'/'.implode('/', $parts).'/'.$hash;
    }
图片.png 缓存方式

我们首先可以查看 \Cache::get('key') 这个函数的文件处理是怎么实现的

代码追踪
1.\Illuminate\Cache\Repository::get($key, $default);
 public function get($key, $default = null)
    {
        if (is_array($key)) {
            return $this->many($key);
        }

        $value = $this->store->get($this->itemKey($key));
        if (is_null($value)) {
            $this->event(new CacheMissed($key));

            $value = value($default);
        } else {
            $this->event(new CacheHit($key, $value));
        }

        return $value;
    }

2.此处的 $this->store 代表的就是文件缓存类  \Illuminate\Cache\FileStore
  public function get($key)
    {
        return $this->getPayload($key)['data'] ?? null;
    }

   protected function getPayload($key)
    {
// 1.获取文件路径
        $path = $this->path($key);
// 2.获取文件中的全部内容
        try {
            $expire = substr(
                $contents = $this->files->get($path, true), 0, 10
            );
        } catch (Exception $e) {
            return $this->emptyPayload();
        }
// 3.查看内容的时间
        if ($this->currentTime() >= $expire) {
// 4.如果时间过期,则删除此文件
            $this->forget($key);
            return $this->emptyPayload();
        }

        $data = unserialize(substr($contents, 10));
        $time = ($expire - $this->currentTime()) / 60;

        return compact('data', 'time');
    }
// $key  对应的文件  文件名是做过加密的,但是 $key 值对应的文件名是不变的,大家不用关系这个函数
 protected function path($key)
    {
        $parts = array_slice(str_split($hash = sha1($key), 2), 0, 2);

        return $this->directory.'/'.implode('/', $parts).'/'.$hash;
    }

apc 缓存

这个缓存的解释我不是很清楚,可能理解可能是减少了编译时间。他的使用场景是比较小的数据。有资料表示比 redis 还快。但是不要存储数据量比较大的数据,因为他的空间很有限

自己写的缓存类

<?php

namespace Core;

/**
 * Class Cache
 * @package Core缓存
 */
class Cache
{
    /**
     * 存入数据
     * @param $key
     * @param $data
     * @param int $cacheTime
     * @return bool
     */
    public static function put($key, $data, $cacheTime = 60)
    {
        $file = BASE_PATH . '/storage/cache/' . $key;
        touch($file);
        return file_put_contents($file, time() + $cacheTime . ':' . serialize($data));
    }

    /**
     * 获取缓存数据
     * @param $key
     * @return string|array|null
     */
    public static function get($key)
    {
        $file = BASE_PATH . '/storage/cache/' . $key;
        if (!file_exists($file)) {
            // 缓存的键不存在
            return null;
        }
        $data = file_get_contents($file);
        if (!$data) {
            // 数据为空
            return null;
        }
        $startTime = substr($data, 0, 10);// 数据写入时间
        if ($startTime <= time()) {
            // 文件过期了
            unlink($file);
            return null;
        }
        // 获取数据,并解析序列化 时间戳是10位数字,:占一位,所以序列化的数据是从第11位开始的
        return unserialize(substr($data, 11));
    }
}

相关文章

网友评论

      本文标题:laravel 文件缓存的过期处理机制原理

      本文链接:https://www.haomeiwen.com/subject/zyrpcctx.html