redis事务、并发及应用场景
目录
事务概念
redis事务是一组命令的集合。多组命令进入到等待执行的事务队列中,执行exec命令告诉redis将等待执行的事务队列中的所有命令,按顺序执行,返回值就是这些命令组成的列表。
SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。Redis 事务可以一次执行多个命令, 具有下列保证:
- 批量操作在发送 EXEC 命令前被放入队列缓存。
- 收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。
- 在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。
一个事务从开始到执行会经历以下三个阶段:
- 开始事务。
- 命令入队。
- 执行事务。
事务命令
包含5个命令 MULTI、EXEC、DISCARD、WATCH、UNWATCH。
DISCARD 取消事务,放弃执行事务块内的所有命令。
EXEC 执行所有事务块内的命令。
MULTI 标记一个事务块的开始。
UNWATCH 取消 WATCH 命令对所有 key 的监视。
WATCH key [key ...] 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。
乐观锁
乐观的认为数据不会出现冲突,使用version或timestamp来记录判断。乐观锁的优点开销小,不会出现锁冲突。
可利用watch命令监听key,实现乐观锁,来保证不会出现冲突,应用场景比如秒杀来防止超卖。
秒杀伪代码如下:
WATCH 锁定量
MULTI
incr 锁定量
if 锁定量 <= 库存量
减库存
EXEC
并发控制及过期时间
服务器访问并发比较大,无效访问频繁,比如说频繁请求接口,爬虫频繁访问服务器,抢购瞬时请求过大,我们需要限流处理。
限流:对访问来源计数,超过设定次数,设置过期时间,提醒访问频繁,稍后再试
limits=500 #设置1秒内限制次数50
if EXISTS userid
return '访问频繁,锁定时间剩余(ttl userid)秒'
if userid_count_time > limits
exprice userid,3600
return '访问频繁,稍后再试'
else
MUlTI
incr userid_count_time # 对用户每秒的请求进行原子递增计数
exprice userid_count_time , 60
EXEC
//使用事务的目的是避免执行错误中断,userid_count_time持久化到磁盘,高并发下这个很有必要
队列
运用数据格式list,lpush、rpop就可以入队、出队,但是会有个问题 假设出队的业务执行发生错误,数据会不会因此丢失,所以需要确保出队时确实被消费了,可以参考下面伪代码处理:
while(val = lrange(list,0,-1))
try{
//对val这条数据的业务代码处理
rpop(list)
}catch(Exception e){
//记录错误,通知programmer处理
break;
}
参考下lrange语法
排序
redis可以当作数据库来存贮数据,如何解决排序查询呢?
SORT命令:
消息通知
订阅
管道
redis禁用危险命令
keys *
虽然其模糊匹配功能使用非常方便也很强大,在小数据量情况下使用没什么问题,数据量大会导致 Redis 锁住及 CPU 飙升,在生产环境建议禁用或者重命名!
flushdb
删除 Redis 中当前所在数据库中的所有记录,并且此命令从不会执行失败
flushall
删除 Redis 中所有数据库中的所有记录,不只是当前所在数据库,并且此命令从不会执行失败。
config
客户端可修改 Redis 配置。
参考:
https://blog.csdn.net/a169388842/article/details/82838818
