您的位置:首页 > 其它

应对单条高频的数据修改方案

2019-08-27 18:20 603 查看

写在前面

在高并发场景下,某些业务场景可能存在对于单条数据高频修改的需求,举个简单的场景:

在MQ消费时,对账户进行加减操作,保证账户(较少账户)的总金额和流水的总金额相等,中间可能存在对于账户进行频繁update的操作,如果直接用DB接高频修改,瓶颈会出现在行级锁占用较长时间,导致消费能力不足,导致MQ消息积压严重。

对于这个场景我们有如下要求:

  1. 数据可靠,不允许丢失
  2. 减少锁时间,提升消费能力

以业务场景来说,我们要求应对100qps。

问题拆解

作为有经验的RD,需要避免一上来就进入方案设计和编码阶段的毛病,首先以产品需求角度分析整个需求场景的合理性。

100qps高频修改,是什么场景呢?上文知道了是账户加减操作。

解决方案

很多人想到的第一个解决方案就是批量处理,这种方案也是高并发高性能系统中常用到的解决方案,面向高并发大数据量场景的kafka在高性能设计上的一个重要方式就是批量处理写请求,所以我们首先可以考虑借助于快照形式,搞成批量修改,避免一次次修改造成的资源浪费和压力,这样可以将100qps降低到50qps或者20qps。

接下来就是考虑通过何种方案实现批量修改了。

首先考虑引入缓存方式,批量修改操作收敛到缓存中,但是缓存的往往面对的问题是数据可能丢失,当然可以依赖于具体缓存介质的特性实现数据不丢失。

另一个想到的解决方案还是拆分,拆分是高并发场景下经典的解决方案,我们可以考虑将目标账户进行拆解,拆分成多个子账户做操作,这样可以将热点操作分散。

还可以考虑CQRS方案,将操作以流水方式进行记录,拆分组合一次次流水,可以保证数据不丢失,在某个时间点进行数据聚合,类似于快照,同时流水数据可以解决聚合查询问题。

需求中一个问题是围绕行级锁展开的,针对于锁,我们可以考虑试试乐观锁,在失败后进行重试,可能相对于悲观锁性能好一些。

另一种方案是引入MQ,MQ是削峰填谷神器,高峰期可以将更新请求写入MQ,之后慢慢更新,降低对于DB的压力,同时通过MQ可以操作缓存修改,mq消费方在批量更新落库。但是引入MQ这种异步处理方式,同时MQ在高峰期可能积压严重,可能会对业务有一定影响,需要考虑业务场景是否对于延迟敏感。

而且需求中其实是有MQ方案的,只不过瓶颈在于对单个账户的高频修改。这种方式又回到了最初的单次转批量的解决方案上了,可以考虑内存合并MQ操作变更,一次落库降低更新频率。

交易系统高频修改场景

将方案扩展下需求场景,我们之前做交易系统,需要做到高频且数据一致性要求。类似的高频操作场景一般依赖于3张表:账户表,流水表,日志表。 整体方案上需要满足事务,且对账户操作修改增加悲观锁。整体方案难度在于记录流水和合并日志消息。

整体方案依赖于账户水平拆分,解决读写瓶颈,缓存持久兜底保护DB,引入异步化处理流水,更新缓存,合并多次操作日志。

在整合了MQ异步,DB更新,缓存兜底,还需要做好应用层排队,和引擎层排队。

批量操作,流水表加批次号,按照批次号进行批次合并,异步更新账户信息。

如果对于金融场景来说,对于持久化存储和数据一致性还是又要求的,缓存可能丢数据,账户金额这种可能无法接受。

所以一般是持久化队列,消费异步消费,消费时批量更新,减少频繁更新锁占用。

在进行账户拆分之后,对于MQ使用来说可以按照账户建立partition,不异步消费不需要担心一个账户的并发更新,场景上避免不了并发处理,并发就拆分partition吧,当然拆的不够细热点问题可能就严重了。

最后

今天我又YY了一个高并发场景需求,最近准备就高频交易系统场景下方案做一些梳理,因为某些方案和背景可能涉及到公司核心系统,所以采用这种YY需求的方式进行讨论。未来考虑做一套课程将高频交易系统的架构和难题进行拆解和总结,准备叫《那些年我们拆解的高频交易系统解决方案》吧。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Kafka
相关文章推荐