【系统架构】如何解决热点数据更新问题

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: 一 背景     某个业务线 商品开放开用户申请免费试用,当某个商品特别吸引人时,比如iPhone6 。肯定有一大波人为了少卖一个肾 疯狂去抢申请资格。有甚者利用机器人申请注册,于是简单的申请操作变成了秒杀行为. 大量请求同时更新数据库中的同一个商品的申请次数,update 操作给表加上行锁,导致后面的请求全部排队等待前面一个update完成,释放行锁后才能处理下一个请求。
一 背景
     某个业务线 商品开放开用户申请免费试用,当某个商品特别吸引人时,比如iPhone6 。肯定有一大波人为了少卖一个肾 疯狂去抢申请资格。有甚者利用机器人申请注册,于是简单的申请操作变成了秒杀行为. 大量请求同时更新数据库中的同一个商品的申请次数,update 操作给表加上行锁,导致后面的请求全部排队等待前面一个update完成,释放行锁后才能处理下一个请求。大量后来请求等待,占用了数据库的连接。一旦数据库连接数被占满,就会导致后来的全部请求因拿不到连接而超时,业务请求出现无法及时处理的情况,数据库系统的RT会异常飙高,业务层由于等待出现超时,app 层的连接耗尽,一系列的雪崩效应!

二 解决方案
     从上面的背景分析,解决热点数据并发更新需要注意核心问题: 减少直接对db层数据热点的并发更新,本文从业务和数据库的设计层面来规划.同时也希望大家提更好的解决思路。
1 前端层面
   前端是整个流量的入口, 正常业务访问时系统表现平稳,但是当有人恶意请求时,需要加上流控措施,比如常见的
   a 需要用户回答问题,填写验证码,移动图像等等,防止或者减少有机器人来恶意请求。
   b 页面上采用防止机器人的判断 两秒以内的成功请求一律拒绝。
   c 通过设置nginx ,对同一个ip源的请求次数做限制,防止机器人来申请。
  优点 有效减少或者防止有人利用机器人恶意请求
  缺点 存在一定的误杀率,错杀了正常的请求。

2 应用层
    应用程序接收前端前端请求,进行一系列的数据库操作,在我们规避了恶意请求之后如果还是有大量的数据库写访问请求,我们需要
    a 对业务做降级
限制接口的调用次数,降低对数据库的请求压力。
选择不更新请求次数,弱化该商品申请次数的展现。类似于阅读次数,申请次数 ,与金额,库存无关的功能点。

    b 通过异步更新来避免直接写数据库 。
      应用使用分布式缓存(比如tair)来存储某项商品的申请次数或者某人的申请次数,以商品id/user_id 或者将where 条件作为key,申请试用人数为value/符合某项具体条件的 count结果为value, 有用户申请成功则更新申请试用人数。不需要查询和实时写数据库,每隔一定时间/次数将结果写入数据库。
      优点:该方法完全依赖于缓存,读写速度快,不需要实时更新数据库,减轻数据库并发写的压力;
      缺点:缓存不是100%稳定,很容易丢,即使采用持久化的缓存,在高并发下有时也可能会出现异常,穿透缓存到db ,导致前端业务展现问题。
    
3 数据库层
    a 将热点数据拆分,分在不同的库不同的表中,分散热点数据,减轻数据库并发更新热点带来的RT升高和应用连接等待时能保证业务能够正常访问其他商品表,损失局部可用性。
    优点:实时读写数据库,前端展示数据的准确性。
    缺点:业务逻辑稍显复杂。
  b 限流补丁
     针对某些特定的sql语句 从MySQL 层面加以限制,当系统thread_running达到一定值或者某个sql执行时间超过一定阈值则拒绝该sql的执行。(阿里内部已经实现限流版本)
   c 使用MySQL的 thread pool 功能。在并发较大时,one to one的模式 会引起Innodb的mutex锁争用。当前解决方法是通过innodb_thread_concurrency参数,但是该参数自身也存在锁争用,同样影响了MySQL的性能。
优点:thread pool主要从四个方面考虑:减少SQL并发,使得有足够的资源:使用线程组,独立管理:使用优先级队列,限制并发执行的事务:避免死锁。
缺点:在测试过程中发现,会有大量的连接等待kernel mutex锁,但是持续的压力会导致MySQL的thread running飙高,最终导致MySQL不可用。
三 小结
     在电商类业务中数据库的热点/单点更新 一直是DBA和业务方比较关心的问题,它最直观的影响用户体验,比如商品的超卖,系统的可用性。需要不断的细化解决思路和具体实现比如 热点商品的属性是否实时更新 ,库存数量需要实时展示,访问次数,请求次数可以异步延迟展示。本文只是简单阐述了 对热点更新的解决思路,还有不完善的地方,欢迎给位提供更好的建议。
相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
3月前
|
存储 缓存 NoSQL
Redis缓存设计典型问题
缓存穿透 缓存穿透是指查询一个根本不存在的数据, 缓存层和存储层都不会命中, 通常出于容错的考虑, 如果从存储层查不到数据则不写入缓存层。缓存穿透将导致不存在的数据每次请求都要到存储层去查询, 失去了缓存保护后端存储的意义。
|
2月前
|
SQL 安全 算法
在高并发情况下,如何做到安全的修改同一行数据?
在高并发情况下,如何做到安全的修改同一行数据?
|
8月前
|
存储 缓存 NoSQL
Redis缓存应用与最佳实践:优化性能与处理挑战
本篇深入探讨了Redis在缓存应用中的最佳实践,旨在优化性能并处理常见的缓存挑战。我们首先介绍了设计高效缓存架构的基本原则,展示了如何使用Redis作为缓存存储来提升应用性能。进一步地,我们讨论了缓存更新策略,演示了如何在源数据更新时同时更新缓存,以确保数据的一致性。
375 0
|
4月前
|
NoSQL 关系型数据库 MySQL
热点数据更新导致CPU100%的解决方案
热点数据更新导致CPU100%的解决方案
40 0
|
7月前
|
存储 缓存 应用服务中间件
|
7月前
|
存储 缓存 NoSQL
如何解决数据热点问题
如何解决数据热点问题
|
9月前
|
存储 缓存 JSON
聊聊方案中心性能优化中做的缓存设计
总结国际站方案中心物流运费计算性能优化过程中面临问题、问题分析、解决思路以及整体解决方案
聊聊方案中心性能优化中做的缓存设计
|
10月前
|
消息中间件 canal 缓存
缓存数据一致性探究
缓存是一种较低成本提升系统性能的方式,自它面世第一天起就备受广大开发者的喜爱。然而正如《人月神话》中的那句经典的“没有银弹”中所说,软件工程的设计没有银弹。 就像每一次发布上线修复问题的同时,也极易引入新的问题,自缓存诞生的第一天起,缓存与数据库的数据一致性问题就深深困扰着开发者们。 关键词:原子性、事务性、数据一致性、双写一致性
6497 1
缓存数据一致性探究
|
存储 消息中间件 缓存
失效问题处理:业务分析以及资料介绍| 学习笔记
快速学习失效问题处理:业务分析以及资料介绍。
120 0
失效问题处理:业务分析以及资料介绍| 学习笔记
|
存储 缓存 Java
分库分表如何做到不迁移数据?避免热点数据?(下)
分库分表如何做到不迁移数据?避免热点数据?
151 0
分库分表如何做到不迁移数据?避免热点数据?(下)