并发读和并发写解决方案

并发有几种

  1. 高并发读取
  2. 高并发写入

一、高并发读取策略

1、加入实体缓存
这个就是我们经常使用的一种方案,采用本地缓存或者分布式缓存来实现。这些是非常成熟的方案。

问题:但是对于缓存,我们需要考虑一下几点:缓存雪崩,缓存穿透,缓存大量的热点key过期。
解决:上面几个问题本质上来说都是缓存回源问题,可以采用不回源策略来解决这些问题,只查缓存,但是这些就需要主动更新缓存,如果采用回源呢?

2、数据库主从分离
上面的实体缓存虽然可以帮助我们解决很多问题,但是面对一些很复杂的业务场景的时候,单纯的key,value并不能满足我们的需求,后台的运营系统需要更加复杂的业务逻辑及业务数据,如果此时我们只有一个数据库,所有的业务查询都是走同一个数据库,会影响C端用户的高并发访问。

解决方案:直接加上一个或者多个Slave,从而减轻主数据库的压力。

3、动静分离
现在基本上都是BS的天下,那内容基本上就分为静态内容与动态内容。

  1. 静态内容基本上啥都不变,图片、HTML、JS、CSS文件等,对用户来说几乎不变,此时我们可以把这些内容采用CDN策略来实现从而实现高速访问。
  2. 动态内容接口方式返回给用户。

4、重写轻读策略
这里是一个非常重要的拓展,按照一定的业务规则把关联数据计算完成,在读取的时候直接去这个地方读取就行,这是聚合存储的概念,可以采用缓存,数据库,ES等。有兴趣的同学可以了解一下微博的Feeds流

二、高并发写策略

描述:以下列举高并发的情况下,用户领取优惠券,优惠券数量有限,领取成功减库存

  1. 使用redis的分布式锁。缺点:锁住的地方相当于串行执行,降低服务性能。
  2. 通过DB的版本号当锁,完成数据更新。缺点:大量并发会修改相同的记录。导致就算有预算,也会导致领取失败,如果使用轮训就会给服务带来很多的性能损耗。
  3. 使用redis的incr, decr的原子性更新缓存中的数据,然后通过异步MQ的形式去更新表中的数据。
  4. 不做更行操作,只做查询操作,领取成功后新增一条数据。每次查询通过表中的数据count计算剩余数据。

下面针对上面总结点详细介绍下:

1、分布式锁方案

实现原理:在领取券的时候,通过分布式锁锁住:先查询库存,在校验用户是否满足领取条件,领取卡券库存减一。
1、实现简单:通过第三方的原子操作锁(redis, zookeeper)在业务开始之前加锁,业务结束后释放锁来完成。
2、性能低:在分布式锁的这个阶段中,需要相同锁的资源相当于串行执行。锁中间的业务耗时多,或者锁的粒度大会严重降低服务性能。

2、关键点数据校验DB乐观锁方案

这个方式在业务逻辑上,区分上一种方式,将校验数据部分区分开,找出关键点数据的校验。关键点数据或者叫做易变数据,是指经常变化的,一般每次写操作都会导致这个数据发生变化。
找出这个关键点数据,将关键点数据的校验和更新操作合并为一个数据库原子操作,例如库存检查操作

update table set count = count-1 where count-1 > 0 and item=?

将这个检验更新操作,在数据库层面添加乐观锁方式实现,如果执行更新成功,再执行后续操作,如果失败表示校验失败,不通过检查。业务实现不复杂,关键是找出可以合并更新为一个的原子数据库操作。找不出的话就不适合这个方案。性能瓶颈点在于更新操作,一般是大量并发,修改相同的记录,例如大量用户领取相同的一种优惠券,关键点合并检查更新在数据库里面都会串行等待这个记录的写锁。

3、通过redis原子操作校验关键点数据方案

该方案是通过redis高性能incr, decr原子操作实现关键点数据检查的方式实现。在数据创建时候将关键点数据保存到redis中,处理业务时候,执行到检查易变数据时,直接更新通过redis.decr操作校验数据,通过后将后续操作通过可靠MQ异步处理。MQ的消费端在更新关键点数据时候,将多条记录合并一次更新,比如50条扣减数量,一次update更新,提高数据库的写性能。后续的其他数据库操作也都批量操作。

特点:

  1. 数据可靠性依赖redis, mq,要保证redis可靠稳定。
  2. 数据库层面不需要扩展,业务相对简单些。
4、无关键点数据检查更新合并操作的业务

这个情况,不能将关键点数据的检查和更新使用同一个数据库原子操作完成,咱们现在coupon服务就是这种情况,每个coupon的已经发放数量在 coupon表里面没有记录,而是通过每次count关联表来计算出来的,这个关键点数据检查就是每次绑定前都count关联表数量,然后对比发放最大人群数量。这种情况都是在获取数量前加锁,领取完成后释放锁,性能很低。

该方案是上面方案的简化方式,通过在数据创建阶段,将初始数据更新到redis中,每次有领取coupon的请求过来,在关键点数据检查时候,redis.incr/decr方式,判断数据是否检查通过。通过之后执行后续数据库操作,这种情况不存在高并发修改少量数据情况,性能不受写锁限制。

特点:

  1. 数据可靠性依赖redis,要保证redis可靠稳定。
  2. 查询数据略慢,需要每次count关联表数量。

摘至:https://www.cnblogs.com/liuqingsha3/p/11960154.html

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

信仰_273993243

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值