Redis之Redis协议与异步方式

Redis 网络层

首先我们来了解串行、并发与并行的区别;
一个队列对应一个处理器是串行;
多个队列对应一个处理器是并发(交叉执行);
多个队列对应多个处理器是并行;
如有n个队列和n个处理器,但他们是交换执行的,虽然也是一对一,但因为处理器与队列的对应关系不断切换,所以也属于是并发(多个并发)
在这里插入图片描述
了解完串行、并发与并行之后,再来看Redis;
Redis是单线程reactor模型;
对于所有连接的数据处理,Redis并发执行;
对于单条连接的数据处理,Redis串行执行;
在这里插入图片描述

Redis 事务

MULTI 开启事务,事务执行过程中,单个命令是入队操作,直到调用EXEC才会一起执行

MULTI

开启事务
相当于mysql中的begin/start transaction

EXEC

提交事务
相当于mysql中的commit

DISCARD

取消事务
相当于mysql的rollback

WATCH

检测key的变化,若在事务执行中,key变动则取消事务;
在事务开启前调用,由乐观锁实现(cas);若被取消则事务返回nil;

分析

redis自带的事务命令,是队列控制的。每次执行完一条命令,就是入队。只有在提交(exec)事务后,统一按顺序进行执行。出现错误后redis不会自动回滚,DISCARD是一个手动的回滚命令。

Lua 脚本

Lua脚本来实现原子性。
Redis中加载了一个lua虚拟机,用来执行Redis lua脚本,redis lua脚本的执行是原子性的,当某个脚本正在执行的时候,不会有其他的命令或者脚本被执行。lua脚本当中有命令的会直接修改数据状态。
注意:如果项目中使用了lua脚本,不需要上述的事务命令

使用步骤:
1、SCRIPT LOAD script
 script即lua脚本,这么做是将lua脚本放到redis服务器中,返回的是一个sha1校验码。
2、EVALSHA sha1 numkeys key [key …] arg [arg …]
 用evalsha调用对应的lua脚本。
在这里插入图片描述
具体使用可以参考这个链接

lua应用

1: 项目启动时,建立redis连接并验证后,先加载所有项目中使用的lua脚本(script load);
2: 项目中若需要热更新,通过redis-cli script flush;然后可以通过订阅发布功能通知所有服
务器重新加载lua脚本;
3:若项目中lua脚本发生阻塞,可通过script kill暂停当前阻塞脚本的执行;

ACID特性分析

A 原子性

 事务是一个不可分割的工作单位,事务中的操作要么全部成功,要么全部失败;
 redis自带的事务命令不支持回滚;即使事务队列中的某个命令在执行期间出现了错误,整个事务也会继续执行下去,直到将事务队列中的所有命令都执行完毕为止。若使用lua脚本可以对错误的返回值进行分析,然后我们手动做回滚操作;

C 一致性

 事务使数据库从一个一致性状态到另外一个一致性状态;
 这里的一致性是指预期的一致性而不是异常后的一致性;所以redis也不满足;这个争议很大:redis 能确保事务执行前后的数据的完整约束;但是并不满足传统意义上的一致性;比如转账功能,一个扣钱一个加钱;可能出现扣钱执行错误(服务器宕机),加钱执行正确,那么最终还是会加钱成功;系统凭空多了钱;

I 隔离性

事务的操作不被其他用户操作所打断;redis 是单线程执行,天然具备隔离性;

D 持久性

redis只有在 aof 持久化策略的时候,并且需要在 redis.conf 中appendfsync=always 才具备持久性;实际项目中几乎不会使用 aof 持久化策略

Redis 发布/订阅

为了支持消息的多播机制,redis 引入了发布订阅模块;
但消息不一定可达,要确保消息可达,可以使用分布式消息队列的方式。

# 订阅频道
subscribe 频道
# 订阅模式频道
psubscribe 频道
# 取消订阅频道
unsubscribe 频道
# 取消订阅模式频道
punsubscribe 频道
# 发布具体频道或模式频道的内容
publish 频道 内容
# 客户端收到具体频道内容
message 具体频道 内容
# 客户端收到模式频道内容
pmessage 模式频道 具体频道 内容

应用

发布订阅功能一般要区别命令连接重新开启一个连接;因为命令连接严格遵循请求回应模式;而pubsub能收到redis主动推送的内容;所以实际项目中如果支持pubsub的话,需要另开一条连接用于处理发布订阅;
在这里插入图片描述

缺点

发布订阅的生产者传递过来一个消息,redis会直接找到相应的消费者并传递过去;假如没有消费者,消息直接丢弃;假如开始有2个消费者,一个消费者突然挂掉了,另外一个消费者依然能收到消息,但是如果刚挂掉的消费者重新连上后,在断开连接期间的消息对于该消费者来说彻底丢失了;
另外,redis停机重启,pubsub的消息是不会持久化的,所有的消息被直接丢弃

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值