Redis的高级特性与应用场景(一)
Redis的高级特性与应用场景(一)
巧用expire
redis
中可以使用 expire
命令设置一个键的生存时间,到期后 redis
会自动删除他
- 过期时间可以设置为秒或者毫秒精度。
- 过期时间分辨率总是 1 毫秒。
- 过期信息被复制和持久化到磁盘,当
Redis
停止时时间仍然在计算 (也就是说Redis
保存了过期时间)。
应用场景
- 限时优惠活动
- 网站热数据缓存
- 积分排行榜
- 手机验证码
- 访客访问频率限制(例如:1分钟最多访问10次)
数据排序-sort
排序可以说是 redis
里面比较复杂的一个操作了
sort
命令可以对列表类型,集合类型和有序集合类型,以及hash
类型键进行排序
# 命令格式
sort key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern ...]] [ASC|DESC] [ALPHA] [STORE destination]
举个例子: 列表里面存储用户id
, 正常键值可以存储对应用户id
的分数,根据对应分数进行排序,并将排序的操作保存到新的列表里面
lpush list-t 1
lpush list-t 2
lpush list-t 3
set user:1 20
set user:2 10
set user:3 30
# 对list-t进行排序 根据user:id 的值进行排序 进行分页 将查询结果写入新的列表 list-new
sort list-t by user:* get user:* limit 0 2 store list-new
sort
使用不好很容易成为性能瓶颈,所以一般都会把排序后的结果写入新的缓存
发布订阅
- 发布:publish
- 订阅:subscribe
- 取消订阅:unsubscribe
- 按照规则订阅:psubscribe
- 按照规则取消订阅:punsubscribe
注意:使用punsubscribe
命令只能退订通过psubscribe
订阅的频道。
这个场景基本不用多说,一个操作对应多个操作就可以使用
任务队列
任务队列:使用lpush
和rpop(brpop)
可以实现普通的任务队列。brpop
是列表的阻塞式(blocking)
弹出原语。
它是 RPOP
命令的阻塞版本,当给定列表内没有任何元素可供弹出的时候,连接将被 BRPOP
命令阻塞,直到等待超时或发现可弹出元素为止。
当给定多个 key
参数时,按参数 key
的先后顺序依次检查各个列表,弹出第一个非空列表的尾部元素。
- 优先级队列:
brpop key1 key2 key3 timeout
利用redis
的这个机制可以制作一个轻量级队列
限制网站访客访问频率
进行各种数据统计的用途是非常广泛的,比如想知道什么时候封锁一个IP
地址。INCRBY
命令让这些变得很容易,通过原子递增保持计数;GETSET
用来重置计数器;过期属性expire
用来确认一个关键字什么时候应该删除。
这里的getset
命令使获取和修改操作具有原子性,才能保证程序正常,如果使用先get
,在set
是会出现意外情况的.
例子
function checkIp($ip)
{
$value = (int) $redis->get($ip);
if ($value) {
// 设置初始访问值
$redis->set($ip, 1);
//设置IP的生存时间为60秒,60秒内IP的访问次数由程序控制
$redis->expire($ip, 60);
} else {
//如果60秒内IP的访问次数超过10,返回false,实现了超过10次禁止
if ($value > 10) {
return false;
} else {
//如果没有10次,可以自增
$redis->incr($ip);
}
}
return true;
}
巧用缓存
- 商品维度计数
喜欢数,评论数,鉴定数,浏览数
hset good:1 visit 1
hincrby good:1 visit 1
hgetall good:1
- 用户维度计数
动态数、关注数、粉丝数、喜欢商品数、发帖数 等
- 存储社交关系
譬如将用戶的好友/粉丝/关注,可以存在一个sorted set
中,score
可以是timestamp
,这样求两个人的共同好友的操作,可能就只需要用求交集命令即可。
- 灵活运用计数实现反 spam(垃圾)
登录次数限制,支付次数限制,一分钟评论不能超过2次 可以根据业务设计很多规则
采用sorted set
将最近一天用户操作记录起来(为什么不全部记录?节省memory
,全部操作会记录到log
,后续利用hadoop
进行更全面分析统计)
日志可以持续增量到es
或者 数据库
- 排行榜
这里采用Redis
的List
数据结构或sorted set
结构, 方便实现最新列表
or排行榜
等业务场景。
redis调优
- 精简键名和键值
键名:尽量精简,但是也不能单纯为了节约空间而使用不易理解的键名。 键值:对于键值的数量固定的话可以使用0和1这样的数字来表示
- SLOWLOG 和
mysql
一样 记录慢操作命令
slowlog-log-slower-than //它决定要对执行时间大于多少微秒(microsecond,1秒 = 1,000,000 微秒)的命令进行记录
slowlog-max-len //它决定 slowlog 最多能保存多少条日志
- 限制
redis
的内存大小
通过redis
的info
命令查看内存使用情况,如果不设置maxmemory
或者设置为0,64位系统不限制内存,32位系统最多使用3GB内存。
maxmemory:最大内存
maxmemory-policy:内存不足时,数据清除策略
如果数据不可预估的情况下,还是需要设置一下最大使用内存,不然会抛出错误导致服务停止工作
- 缓存技巧
尽可能的使用Hash
数据结构。因为Redis
在储存小于100
个字段的Hash
结构上,其存储效率是非常高的。所以在不需要集合(set)
操作或list
的push/pop
操作的时候,尽可能的使用Hash
结构。比如,在一个web
应用程序中,需要存储一个对象表示用户信息,使用单个key
表示一个用户,其每个属性存储在Hash
的字段里,这样要比给每个属性单独设置一个key-value
要高效的多。 通常情况下倘若有数据使用string
结构,用多个key
存储时,那么应该转换成单key
多字段的Hash
结构。 如上述例子中介绍的Hash
结构应包含,单个对象的属性或者单个用户各种各样的资料。
尽可能设置key
的生存时间,并指定阀值去限制Redis
使用的最大内存。
若是启用了Redis
快照功能,应该设置maxmemory
值为系统可使用内存的45%
,因为快照时需要一倍的内存来复制整个数据集,也就是说如果当前已使用45%
,在快照期间会变成95%(45%+45%+5%)
,其中5%
是预留给其他的开销。 如果没开启快照功能,maxmemory
最高能设置为系统可用内存的95%
。
多命令使用管道 pipeline
,这个下篇文章会说明
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Tensorflow Serving模型指向s3地址,Could not find base path?
- Python之turtle模块初体验
- tcsetpgrp failed重新编译tini
- s3cmd ls之迷惑
- 构建pyflink镜像
- apt-get update遇到NO_PUBKEY
- 遇到mpi worker exited on signal 9
- 容器共享GPU时查看容器使用的GPU编号
- oci runtime error: exec failed: container_linux.go:247: starting container process caused “exec: “/
- R|UpSet-集合可视化
- 美国队长的盾(一) 同心圆
- R|clusterProfiler-富集分析
- R|fastqcr QC数据处理
- R|timeROC-分析
- R|ML_code-线性回归(2)