spring - Redis 中的并发用于分布式系统中的闪购

标签 spring concurrency redis

我打算构建一个限时抢购系统,该系统将共享同一个 Redis 实例并同时在 15 个服务器上运行。

因此闪购的算法将是。

Set Max inventory for any product id in Redis 
 using redisTemplate.opsForValue().set(key, 400L);

for every request :
   get current inventory using Long val = redisTemplate.opsForValue().get(key);
    check if it is non zero
     if (val == null || val == 0) {
                            System.out.println("not taking order....");
     } 
else{

put order in kafka 
and decrement using redisTemplate.opsForValue().decrement(key)
}

但这里的问题是并发性: 如果我设置库存 400 并使用 500 请求线程对其进行测试, 库存变为负数, 如果我使功能同步,我将无法在分布式服务器中管理它。

那么最好的方法是什么? 注意:由于请求数过多,我无法使用 RDBMS 并设置隔离级别。

最佳答案

Redis 是单线程的,因此在其上运行 Lua 脚本始终是原子的。 然后,您可以在 Redis 实例上定义一个 Lua 脚本,并从您的 Spring 实例运行它。

您的 Lua 脚本只是对您的 redis 实例(唯一具有正确股票值的实例)执行的一系列操作,并返回新值,例如,如果值为负,则返回错误。

你的 Lua 脚本基本上是一个 Redis 事务,还有其他方法可以实现 Redis 事务,但恕我直言,Lua 是最简单的(可能是性能最低的,但我发现在大多数情况下它足够快)。

关于spring - Redis 中的并发用于分布式系统中的闪购,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56197215/

相关文章:

java - 如何在 spring 的 xmls 中定义变量以在 log4j.properties 中使用

spring - 如何设置 Spring session 作用域 bean 的属性名称?

java - 通过AOP拦截重载方法

go - 如何跨 goroutines 共享 map

python - 嵌套排序的最佳数据库管理系统?

node.js - 比较两个值的计算结果为 false 而不是 true

java - 将具有现有 pom.xml 的 maven 项目运行到 netbeans 时出现不同的错误

java - wait()方法对java同步块(synchronized block)中线程的影响

mysql - 管理商店结帐流程的并发性

redis - Rails 自定义环境 Resque.enqueue 不创建作业