# 缓存插件
`ESD` 已默认启用本插件。
## 插件使用
缓存可以使用注解的形式,在需要加缓存的函数中添加相关注释。
>[danger] **添加注解的函数不能为`private`。**
引用
~~~
use ESD\Plugins\Cache\Annotation\Cacheable;
~~~
## Cacheable 方法
>[info]如果缓存不存在就创建,如果存在就直接返回。
参数说明
> ### $key = "";
代表需要删除的命名空间下唯一的缓存`key`。 使用`php`语法,`$p[0]` 获取对应参数,可以增加前缀,其值最终将作为表达式在 `eval` 中执行。
~~~
/**
* @Cacheable(key="$p[0]", namespace="user")
* @param $id
* @return array
*/
~~~
~~~
/**
* @Cacheable(key="'user_'.$p[0]", namespace="user")
* @param $id
* @return array
*/
~~~
~~~
/**
* @Cacheable(key="'user_'.$p[0]->user", namespace="user")
* @param $id
* @return array
*/
~~~
> ### $time = 0;
缓存时间 0 代表使用默认时间,-1 代表无限时间,对有 `namespace` 的无效,`namespace`底层使用`hset`存储,无法单独设置时间。同时如果使用默认时间底层会对缓存超时设置一个`20%`以内的浮动。如果不需要此特性请设置该参数或覆盖默认设置。
~~~
/**
* @Cacheable(key="$p[0]", time="3000")
* @param $id
* @return array
*/
~~~
> ### namespace= ""
对缓存进行分组,分组的数据底层存放`hset`,所以不能设置过期时间。后期删除可以针对`namespace`批量删除。
~~~
/**
* @Cacheable(key="$p[0]", namespace="user")
* @param $id
* @return array
*/
~~~
> ### $condition = "";
有的时候我们可能并不希望缓存一个方法所有的返回结果。
通过 `condition `属性可以实现这一功能。`condition`属性默认为空,表示将缓存所有的调用情形。
其值是通过PHP表达式来指定的,当为true时表示进行缓存处理;
当为false时表示不进行缓存处理,即每次调用该方法时该方法都会执行一次。
~~~
/**
* @Cacheable(key="'cache_test'.$p[0]", namespace="test", condition="$p[0] >= 5")
*/
~~~
使用例子
~~~
/**
* get操作创建缓存
* @Cacheable(key="'cache_test'.$p[0]", namespace="test", condition="$p[0] >= 5")
* @param $id
* @return array
*/
protected function cacheTest($id){
$res = $this->mysql->query("SHOW GLOBAL STATUS LIKE '%connections%'");
$this->log->debug('cacheTest db', $res);
return $res;
}
~~~
## CacheEvict
>[info]无论缓存是否存在,始终清除缓存
引用
~~~
use GoSwoole\Plugins\Cache\Annotation\CacheEvict;
~~~
除了Cacheable方法之外的参数还有以下参数
> ### $allEntries = false;
标记是否删除命名空间下所有缓存,默认为`false`
> ### $beforeInvocation = false;
在调用方法之前清除缓存中的指定元素,默认为`false`
默认设置下,清除操作是在对应方法成功执行之后触发的,如果方法因为抛出异常而未能成功返回时也不会触发清除操作。使用`beforeInvocation`可以改变触发清除操作的时间,当我们指定该属性值为`true`时,会在调用该方法之前清除缓存中的指定元素。
使用例子
~~~
/**
* update删除缓存
* @CacheEvict(key="'cache_test'.$p[0]",namespace="test", allEntries="true", beforeInvocation="true")
* @param $id
* @return array
*/
public function updateTest($id){
//do something
return $res;
}
~~~
### CachePut
>[info]不检查缓存是否存在,始终生成缓存
引用
~~~
use GoSwoole\Plugins\Cache\Annotation\CachePut;
~~~
参数与 Cacheable 一致。
对于使用 `@Cacheable` 标注的方法,在每次执行前都会检查 Cache 中是否存在相同key的缓存元素,如果存在就不再执行该方法,而是直接从缓存中获取结果进行返回,否则才会执行并将返回结果存入指定的缓存中。
`@CachePut` 也可以声明一个方法支持缓存功能。与 `@Cacheable `不同的是使用`@CachePut` 标注的方法在执行前`不会去检查`缓存中是否存在之前执行过的结果,
而是`每次都会`执行该方法,并将执行结果以键值对的形式存入指定的缓存中。
## 配置项
无需配置即可直接使用,如果需要覆盖默认配置,需要将被覆盖的部分参数增加到 `application.yml`文件中。下面依次说明相关配置,
> 如无特别说明,以下列出的均为默认值,不改配置无需修改配置文件。
~~~
cache:
timeout: 1800 (缓存超时时间)
db: default (使用的redis连接标识)
cacheStorageClass: ESD\Plugins\Cache\RedisCacheStorage(使用的缓存驱动)
lock_timeout: 0 (是否开启缓存读锁等待。此为高级功能下面详细说明)
lock_wait: 500(读取锁等待重试间隔)
lock_alive: 20000(锁存活时间)
~~~
## lock_timeout 配置
如果设置为0则不启用读写锁,开启后写入缓存时会进行加锁,避免高并发缓存穿透。
高并发建议开启该设置,并且调高 redis 连接池以及 redis 的连接数。
如果每秒并发2000,超时设置为3秒,那么会有2000个连接等待。
如果秒级 set 建议设置 3000
如果几百毫秒 set 建议设置 1000
如果不到100毫秒 set 建议设置 500
注意只有 Cacheable 方法支持该功能
>[danger] 如果锁超时,同样会直接访问数据库获取数据。
## lockWait 配置
读取锁等待重试时长,单位(毫秒)。
每隔 lockWait 重试,如果缓存写入需要秒级,建议调整 lockWait 为 500 毫秒以上
如果缓存写入需要 几百毫秒级,建议使用默认 100 毫秒
如果缓存写入需要 一百毫秒以内,建议设置 50 毫秒
注意: 此值设置的太低会严重增加 redis get 负载, 如果每秒并发 2000,超时设置3秒,默认锁等待100 毫秒,那么最差会有6万get操作
注意:等待时长不要超过lockTimeout,否则会浪费协程资源。
## lockAlive 配置
死锁过期时间 单位(毫秒)
注意:lockAlive 一定要大于lock_timeout 时间,否则如果锁释放了还没有写入缓存同样会造成缓存穿透。
注意:配置在 application.yml 中,大写字符需要以下划线的形式覆盖默认配置。
- 前言
- 捐赠ESD项目
- 使用篇-通用
- 环境
- 安装
- 规范
- 压力测试
- 配置
- 如何设置YML配置
- server配置
- 端口配置
- 项目结构
- 事件派发
- 日志
- 注解
- DI容器
- 自定义进程
- 并发及协程池
- Console插件
- Scheduled插件
- Redis插件
- AOP插件
- Saber插件
- Mysql插件
- mysql事务
- Actuator插件
- Whoops插件
- Cache插件
- PHPUnit插件
- Security插件
- Session插件
- EasyRoute插件
- http路由
- ProcessRpc插件
- AutoReload插件
- AnnotationsScan插件
- Tracing-plugin插件
- MQTT插件
- Pack插件
- AMQP插件
- Validate插件
- Uid插件
- Topic插件
- Blade插件
- CsvReader插件
- hashed-wheel-timer-plugin插件
- 使用篇-HTTP
- 路由
- 静态文件
- 路由定义
- 修饰方法
- 路由分组
- 资源路由
- 端口作用域
- 异常处理
- 跨域请求
- 路由缓存
- 控制器
- 控制器初始化
- 前置操作
- 跳转和重定向
- 异常处理
- 请求
- 请求对象
- 请求信息
- request消息
- response消息
- stream消息
- url接口
- 验证器
- 内置验证器
- 内置过滤器
- 使用篇-WS
- 如何使用
- 路由
- 使用篇-TCP
- 插件篇-PluginSystem
- 微服务篇-ESDCloud
- CircuitBreaker插件
- SaberCloud插件
- 分布式链路追踪系统
- Consul插件