Redis事务和秒杀业务设计

Redis事务

F1oW5V.md.png

Redis事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断,Redis事务的主要作用就是串联多个命令防止别的命令插队

Multi

用于标记事务块的开始。Redis会将后续的命令逐个放入队列中,然后才能使用EXEC命令原子化地执行这个命令序列。

这个命令的运行格式如下所示:

MULTI

这个命令的返回值是一个简单的字符串,总是OK。

EXEC

在一个事务中执行所有先前放入队列的命令,然后恢复正常的连接状态。

当使用WATCH命令时,只有当受监控的键没有被修改时,EXEC命令才会执行事务中的命令,这种方式利用了检查再设置(CAS)的机制。

这个命令的运行格式如下所示:

EXEC

这个命令的返回值是一个数组,其中的每个元素分别是原子化事务中的每个命令的返回值。 当使用WATCH命令时,如果事务执行中止,那么EXEC命令就会返回一个Null值。

DISCARD

清除所有先前在一个事务中放入队列的命令,然后恢复正常的连接状态。

如果使用了WATCH命令,那么DISCARD命令就会将当前连接监控的所有键取消监控。

这个命令的运行格式如下所示:

DISCARD

这个命令的返回值是一个简单的字符串,总是OK。

WATCH

当某个事务需要按条件执行时,就要使用这个命令将给定的键设置为受监控的。

这个命令的运行格式如下所示:

WATCH key [key ...]

这个命令的返回值是一个简单的字符串,总是OK。

对于每个键来说,时间复杂度总是O(1)。

UNWATCH

清除所有先前为一个事务监控的键。

如果你调用了EXEC或DISCARD命令,那么就不需要手动调用UNWATCH命令。

这个命令的运行格式如下所示:

UNWATCH

这个命令的返回值是一个简单的字符串,总是OK。

时间复杂度总是O(1)。

总结


从输入Multi命令开始,输入的命令都会依次进入命令队列中,但不会执行,至到输入Exec后,Redis会将之前的命令队列中的命令依次执行。

F1oTKJ.md.png

组队的过程中可以通过discard来放弃组队。

事务的错误处理

如果执行阶段某个命令报出了错误,则只有报错的命令不会被执行,而其他的命令都会执行,不会回滚。

F1T9rd.md.png

Redis 事务的三特性

单独的隔离操作

事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断

没有隔离级别的概念

队列中的命令没有提交之前都不会实际的被执行,因为事务提交前任何指令都不会被实际执行,也就不存在“事务内的查询要看到事务里的更新,在事务外查询不能看到”这个让人万分头痛的问题

不保证原子性

Redis同一个事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚

为什么要做成事务

应用场景:抢购

两个请求

一个请求想给金额减8000

一个请求想给金额减5000

一个请求想给金额减1000

F1TKqs.md.png

这样的话即使在用户卡里没有金额的情况下仍旧可以进行支付。为了解决这个问题我们在Redis中使用到了锁的机制

悲观锁

悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。

F1HmHs.md.png

乐观锁

乐观锁(Optimistic Lock), 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量。Redis就是利用这种check-and-set机制实现事务的。

F1HUER.md.png

Rediss事务 -------秒杀

解决计数器和人员记录的事务操作

F1HyKe.md.png

超卖问题

F1HRUI.md.png

乐观锁

F1HvGV.md.png

lua脚本

F1HzxU.png

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 对于您的问题,我可以提供一些设计基于 Redis秒杀架构的建议。 首先,Redis 是一个快速、开源的内存键值存储系统,支持多种数据结构。在实现秒杀架构时,Redis 的高性能和支持原子性操作的特性使得其成为一个非常好的选择。 以下是一些基于 Redis秒杀架构设计建议: 1. 使用 Redis 存储商品信息和库存。可以使用 Redis 的 Hash 数据类型来存储每个商品的详细信息,如商品名称、描述、价格、剩余库存等。使用 Redis 的计数器数据类型来实现商品的库存管理。 2. 使用 Redis 的分布式锁来实现商品的售卖和库存的减少。当一个用户购买商品时,使用分布式锁来确保在同一时间只有一个用户可以购买该商品。如果锁定成功,则将商品的库存减少一个数量,并将订单信息存储在 Redis 中。 3. 使用消息队列来处理用户订单。在秒杀活动期间,订单量可能非常大。为了避免订单丢失或延迟处理,可以使用消息队列来确保所有订单都能被及时处理。 4. 可以考虑使用 Redis 集群来扩展系统的性能和容量。Redis 集群可以自动将数据分布在多个节点上,并实现高可用性和故障转移。 5. 最后,需要对系统进行充分的压力测试和性能测试,以确保其在高并发环境下能够正常运行。 这些是设计基于 Redis秒杀架构的一些建议,希望能对您有所帮助。 ### 回答2: 秒杀是一种高并发的业务场景,为了保证系统能够在短时间内处理大量的并发请求,可以设计一个基于Redis秒杀架构。 首先,为了确保系统的高可用性和水平扩展性,可以使用主从复制的方式部署Redis服务器。将读写请求分发到不同的Redis实例,提高系统的并发处理能力。 在设计秒杀业务数据库模型时,可以使用Redis的Hash数据结构,将商品ID作为Key,将商品库存和商品信息等存储在Hash中。这样可以将商品信息保存在内存中,提高读取速度。 为了防止超卖和维护商品库存的一致性,可以使用Redis事务机制和CAS(Compare and Set)操作。在用户发起秒杀请求时,首先判断商品库存是否大于0,如果大于0,则使用Redis事务机制将商品库存减1,并将秒杀成功的用户信息加入到一个集合(Set)中。如果库存小于等于0,则秒杀失败。通过CAS操作,可以保证商品库存的准确性,避免多个请求同时减少库存而导致超卖的问题。 为了应对高并发请求,可以使用分布式锁来控制用户的并发访问。Redis提供了分布式锁的实现方式,如使用SETNX命令来获取锁以及使用DEL命令来释放锁。当用户发起秒杀请求时,先尝试获取锁,如果获取成功,则执行秒杀逻辑,否则等待一段时间后重新尝试。 为了减轻数据库的压力,可以结合异步处理的方式。将秒杀请求放入消息队列中,通过消费者的方式异步处理秒杀逻辑,这样可以将高并发的请求分散到不同的时间段内进行处理,提高系统的并发处理能力。 最后,为了保证系统的稳定性和故障恢复能力,可以设置监控和恢复机制。通过Redis的监控工具对Redis服务器进行监控,并设置服务器宕机时的自动切换机制,将流量引导到备用节点上,确保系统的可用性。 总之,基于Redis秒杀架构需要考虑高可用性、水平扩展性、数据一致性和并发处理能力等方面,并结合分布式锁、事务机制、异步处理和监控机制等技术手段来实现。 ### 回答3: 秒杀架构是一种高并发场景下常见的设计方案,旨在解决大量用户同时请求同一商品的情况下保证系统的可用性和稳定性。基于Redis秒杀架构可以采用以下设计方案: 1. 商品库存管理:使用Redis的Hash结构来存储商品的库存信息。每个商品对应一个Hash结构,包括库存数量、已售数量、商品ID等字段。可以通过Redis的原子操作将库存数量进行减少和增加,保证库存的实时性和一致性。 2. 请求限流:为了控制系统的并发请求量,可以使用Redis的计数器功能实现请求的限流。每次用户发起秒杀请求时,利用Redis的INCR操作对计数器进行自增操作,同时设置过期时间,超过限定值的请求将被拒绝。 3. 重复请求处理:由于高并发场景下,用户可能多次提交秒杀请求,为了避免重复购买商品,引入Redis的Set数据结构记录已经购买过的用户ID。每次用户发起秒杀请求前,先判断用户ID是否存在于Set中,若存在则拒绝请求,否则可以继续进行秒杀操作。 4. 异步下单:为了提高系统的并发处理能力,并降低响应时间,可以使用消息队列来实现异步下单的操作。秒杀成功后,将下单的请求存入消息队列中,由消费者进行实际的下单操作,将订单信息写入数据库。 5. 分布式部署:为了进一步提高系统的稳定性和可扩展性,可以采用分布式部署架构。将商品的库存和用户ID等信息分片存储在不同的Redis节点上,通过分布式缓存中间件来实现数据的一致性和负载均衡。 通过以上的设计方案,基于Redis秒杀架构可以实现高并发场景下的安全、稳定和高效的秒杀操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值