前言
大家好,我是路由器没有路。
在上一讲的实现方案里,我们讨论采用数据库的扣减实现方案,如果以常规的机器或者 Docker
来进行评估,此方案将来实现单机级的 TPS
。
之所以介绍,是要告诉你架构是面向业务功能、成本、实现难度、时间等因素的取舍,而不是绝对的追求高性能、高并发及高可用等非功能性指标。
另外。在上一讲里介绍的扣减业务的技术实现方案有一定的需求基础介绍了。因此今天我们讲解的方案将直接复用以上信息,不再赘述。
有忘记的同学,可以查看这篇文章:《由浅入深的介绍扣减业务中的一些高并发构建方案(上)》。
另外,大家可以关注公众号:Go键盘侠
,在上面会第一时间更新编程技术、开发经验的分享文章,回复“Redis”可免费领取《Redis 核心技术与实战》资料。
这一讲我将由浅入深的介绍如何基于缓存来实现单机万级这些并发扣减目标。
引入缓存方案的原因
数据库的方案虽然避免了超卖和少卖的情况。但因采用了事物的方式保证一致性和原子性,所以在 SKU
数量较多时,性能下降较明显。
在学习下面的内容之前,我们先来回顾一下事物本质上的四个特点,ACID
,分别是原子性、一致性、隔离性及持久性。
我们知道扣减有一个要求,就当一个 SKU 购买的数量不够时,整个批量扣减就要回滚,因此我们需要使用类似循环的方式对每一个扣减的返回值进行检查。
另外一个原因是,当多个用户一个 SKU 的性能也并不乐观,因为当出现高并发扣减或者并发扣减同一个 SKU 时,事物的隔离性会导致加锁、等待释放锁情况出现。
首先你要知道,扣减只需要保证原子性即可,并不需要数据库提供的 ACID。另外,在此基础上该如何提升性能?
在不改变机器配置的情况下,把传统的 SQL
类数据库替换为性能更好的 NoSQL
类数据存储试试。是不是有一个性能又好,同时又能够满足扣减多个 SQL
具有原子性的 NoSQL
数据库了?答案显然是可以的。
Redis 做缓存
Redis
作为最近几年非常流行的 NoSQL
数据库,它的原始版本或者改造版本基本上已经被国内所有互联网公司或者云厂商所采