分布式锁
- 适用场景: 秒杀
$rand = rand(); // 设置一个随机数作为标签
// 第三个参数: 过期时间类型, EX 指秒数, PX 指毫秒数
// 第五个参数: NX 指不存在此 key 时才 set, XX 相反
$lock = $redis->set('lock', $rand, 'EX', 5, 'NX');
if ($lock) {
// ... 业务逻辑
if ($redis->get('lock') == $rand) { // 当值匹配时才解锁, 防止 A 任务时间过长导致 B 解锁 A
$redis->del(['lock']);
}
}
分布式锁不宜用于时间过长的任务
位图
- 适用场景: 签到
HyperLogLog
- 适用场景: 统计 UV
布隆过滤器
- 适用场景: 推送新闻, 检查垃圾邮件地址, 爬虫 URL 地址去重, 解决缓存穿透问题
过滤前总数: 5 -> 过滤 ( 已推送的新闻 || 垃圾邮件地址 || 已爬 url ) -> 过滤后总数: 2
不精确, 过滤器认为过滤列表有时却可能没有, 认为没有时则一定没有, 如垃圾邮件误报
Redis-Cell
- 适用场景: 限流
// 扩展 https://github.com/brandur/redis-cell
// 参数 3: 总允许请求次数 -1
// 参数 4和参数 5: 每 60 秒完全请求完毕 30 个, 影响 **漏斗变空剩余时间**
// 参数 6: 每次使用额度, 默认 1
$response = $redis->executeRaw(['cl.throttle', 'test', 15, 30, 60, 1]);
print_r([
'是否允许请求' => $response[0] ? '否' : '是',
'总允许请求次数' => $response[1] . ' 次',
'剩余可请求次数' => $response[2] . ' 次',
'下一次允许请求时间' => $response[3] == -1 ? '即时' : $response[3] . ' 秒后',
'漏斗变空剩余时间' => $response[4] . ' 秒后',
]);
GeoHash
- 适用场景: 附近的人
scan
- 适用场景: 匹配 key
// 参数 6: 不是指返回的结果量, 而是遍历的字节槽位数量
$redis->executeRaw(['scan', 0, 'match', '*keyword*', 'count', 10]);