- 说明:一般redis作为缓存工具使用,例如统计类数据,热点数据放在redis,因为redis是内存数据库,读取速度很可观,能够有效减轻mysql压力;
- 注意:需要注意的是缓存穿透和雪崩问题
- 缓存穿透即绕过redis直接读取mysql,例如热点数据为空,不保存redis,导致每次请求读取不到redis时都去查询MySQL,建议是空数据时也要写一个空值到redis中,并且设置一个小的过期时间(如几分钟等等);
- 缓存雪崩是redis突然失效,导致所有请求都去到了mysql,这种情况简单方法是用互斥锁,网上还有各种方法自行搜索
<br/>
##### 缓存穿透
```php
if (!($cacheData = $redis->get('key'))) {
$data = $mysql->getData();
if (empty($data)) {
$redis->set('key', json_encode($data), 60); // 当数据为空时,设置一个小的过期时间,这样的好处是可以减低数据更新延时率
} else {
$redis->set('key', json_encode($data), 7200); // 正常的过期时间为两个小时
}
}
```
##### 缓存雪崩 (参考:http://huoding.com/2015/09/14/463)
```php
$key = 'cache_create_lock'; // 锁的名称
$value = sha1(uniqid(getmypid().'_'.mt_rand().'_', true)); // 唯一值,加入唯一值判断是为了避免删除到其他操作的锁(这种情况是发生在生成cache过程很久导致锁到了过期时间,此时锁被另一个用户拿到,而当代码继续执行时,会把另一个用户拿到的锁误删掉)
$ttl = 10; // ttl表示超时时间time to live,单位是秒.
if ($redis->set($key, $value, array('nx', 'ex' => $ttl))) { // 锁: nx表示not exists. ex表示expire.
$cache->create(); // 加锁后执行业务逻辑,这里是生成缓存,注意锁的过期时间必须比create长,否则会出现死锁
if ($redis->get($key) === $value) { // 认证锁,防止误删
$redis->del($key);
}
} else {
// 拿不到锁,是sleep几秒后重新查询缓存,还是直接返回系统繁忙状态?
// 缓存失效,又拿不到锁生成缓存,怎么办?直接返回请求失败?
}
```
- php
- 编译安装
- 基本概念
- 垃圾回收机制
- 生命周期
- zval底层实现
- c扩展开发
- gdb调试工具
- 自定义扩展简单demo
- 钩子函数
- 读取php.ini配置
- 数组
- 函数
- 类
- yaf扩展底层源码
- swoole扩展底层源码
- memoryGlobal内存池
- swoole协程使用记录
- 单点登录sso原理
- compser使用
- session实现机制
- c & linux
- gcc
- 指针
- 结构体,联合和位字段
- 宏定义井号说明
- printf家族函数和可变参数
- 共享函数
- 静态库和动态库
- makefile自动化构建
- 信号一
- 信号二
- inotify监控文件事件
- socket编程
- 简介
- UNIX DOMAIN
- Internet DOMAIN
- TCP/IP
- 文件IO多路复用
- 内存管理
- 进程组,会话和控制终端
- daemon守护进程
- 多进程
- 多线程
- 常用进制转换
- go
- 入门知识
- 字节和整数装换
- python
- redis
- 应用场景
- 消息队列
- 热点数据
- 扫码登录
- 订阅发布
- 次数限制
- 抢购超卖
- 持久化机制
- mysql
- 工作流程
- MyISAM和InnoDB区别
- 用户和权限管理
- 执行计划
- sql优化
- 事务和锁
- 慢查询日志
- case...when...then...end用法
- sql
- 参考
- linux
- 内核参数优化
- 防火墙设置
- docker
- docker入门知识
- 算法
- 多维数组合
- DFA算法
- 红包金额分配