首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Redis+lua进行类似秒杀的实现

please read in markdown format

#Redis+lua进行类似秒杀的实现

> 由于项目需要,需要多线程去获取和修改数据库的库存,考虑到给数据库加锁效率低,所以采用redis+lua来进行实现 。

>redis的单线程操作特性来执行lua脚本,通过lua脚本来保证原子性。如果通过单纯的redis指令来进行更改,在读和写之间会存在多线程并发更新的问题。

1.首先定义redis数据结构

```

goodId:

{

"total":100,

"released":0;

}

```

-其中goodId为商品id号,可根据此来查询相关的数据结构信息,total为总数,released为发放出去的数量,可使用数为total-released

2.编写lua脚本

```

local n = tonumber(ARGV[1])

if not n or n == 0 then

return 0

end

local vals = redis.call("HMGET", KEYS[1], "total", "released");

local total = tonumber(vals[1])

local blocked = tonumber(vals[2])

if not total or not blocked then

return 0

end

if blocked + n

redis.call("HINCRBY", KEYS[1], "released", n)

return n;

end

return 0

```

-执行脚本命令`EVAL script_string 1 goodId apply_count`

-若库存足够则返回申请的数量,否则返回0,不返回可满足的剩余数

3.spring boot 调用

-pom dependency

```

org.springframework.boot

spring-boot-starter-data-redis

2.0.1.RELEASE

```

-java code

```java

long count = redisHelper.getStrCache().execute(new RedisCallback() {

@Nullable

@Override

public Long doInRedis(RedisConnection redisConnection) throws DataAccessException {

long ret = redisConnection.eval(script.getScriptAsString().getBytes(), ReturnType.INTEGER, 1, key.getBytes(), String.valueOf(count).getBytes());

return ret;

}

});

```

4.redis->database

> 针对redis到databases的更新,思考了很久,没有找到较好的解决办法,先采用定时任务异步更新。至于数据是否丢失的问题,如果redis挂了,重启后redis会恢复数据,等下次定时任务就可以将数据库中的数据保持一致,缺点是redis挂了秒杀活动会失败。

至于redis到database更新的如何驱动,列出两种愚见:

-redis存一份相关hash键名单表,通过读取名单表来读取更新

-通过流式读取databases中的表来读取更新。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180514G1UZ3K00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券