下单减库存

1. 减库存redis

通常下单减库存的流程大概是这样的:数据库

一、查询商品库存。这里直接查的Redis中的库存。缓存

二、Redis中的库存减1。这里用到的Redis命令是:incrby -1并发

三、扣减数据库中的库存。这里用数据库乐观锁,不用额外加锁异步

四、异步刷新Redis中的库存分布式

五、定时扫描超时未支付的交易,库存加回去性能

总结一下这个流程就是:先减redis库存,再减数据库库存,最后刷新redis库存优化

用到的Redis命令可能:DECR key  或者  INCRBY key -1spa

更新数据库的SQL多是这样的:线程

update 商品库存表 set 库存 = 库存 - 1 where 商品ID = xxx and 库存 > 0;

或者

update 商品库存表 set 库存 = 库存 - 1 where 商品ID = xxx and version = xxx;

用乐观锁是一种比较好的方式,并且一遍ID字段都有索引,能够充分利用MySQL行级锁

这种方式还有一个比较巧妙的地方是,利用redis的单线程来操做库存,并且又是原子命令,能够避免并发问题

同时,先减redis库存后能够防止后续因库存不足而形成下单失败

最后,数据库更新完之后,再经过MQ异步刷新缓存,可使得redis中的库存偏差不会太大

交易系统会定时扫描超时未支付的订单,而后用MQ异步通知订单和商品中心,将订单关闭,库存再放回去

2. 加锁

加锁(好比:基于Redis的分布式锁)

MQ能够把并行转成串行,可是并不能很好的解决并发访问的问题,只能靠锁

加锁会影响性能,可是影响不大。假设咱们用Redisson分布式锁,操做redis只须要几毫秒,所以这点儿损耗不是什么大问题。都是这么玩儿的,不加锁还能怎么办呢。

3. 内存缓存

在cms管理后台修改数据后,同步或异步刷新redis缓存,同时利用zookeeper刷新内存缓存,这样就能够不用等到须要用的时候再从redis中同步。

必定要避免redis大key,最多见的就是hash key,设置的时候不注意,一不当心里面就几千个field了,这对查询很是不利,能够取模进行分片。

必定要避免HGETALL命令,利用Pinpoint能够帮助咱们分析每一个请求在每一个操做所消耗的时候,从而有助于咱们优化

数据迁移用Canal

 

https://redis.io/commands/incr 

相关文章
相关标签/搜索