MySQL 高并发场景实战|学习笔记

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 快速学习 MySQL 高并发场景实战。

开发者学堂课程【MySQL 实战进阶MySQL 高并发场景实战】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/852/detail/14060


MySQL 高并发场景实战

 

内容介绍:

一、问题和挑战

二、系统调优

三、流程管理和生态工具

 

一、问题和挑战

阿里巴巴 CEO 逍遥子说双11是商业界的奥林匹克”。

image.png 

双11从2009年开始举办,从图中可以看到每一年的交易额、支付笔数和订单创建几乎都是翻倍增长的,不但给商业界提供了大炼金的机会,相应的给后端的技术、架构,以及各个模块等等都是比较好的技术沉淀。

在双11面临哪些问题和挑战呢?今天的主题是 MySQL 高并发场景的问题和挑战,这个并发不仅是高并发,而且是洪峰般地并发。

1、洪峰般地并发

根据市场部部门的推广和引流、历年双11的经验,大促的起始时刻呈现接近90度上升趋势。在这么大访问流量下,所有的核心链路的增删改查都是在数据库上操作,对数据库有比较大的冲击,在大量线程并发工作时线程调度工作过多、大量缓存失效、资源竞争加剧、锁冲突严重,如果有复杂 SQL 或大事务的话还可能导致系统资源耗尽,整个数据库服务不可用,进而导致大促受到影响,甚至失败,比如:下单失败、网页无法打开、无法支付等。此外此类场景也会发生在在线教育、直播电商、在线协同办公等。

2、热点行更新

库存扣减场景是一-个典型的热点问题,当多个用户去争抢扣减同一个商品的库存(对数据库来说,一个商品的库存就是数据库内的一行记录),数据库内对同一行的更新由行锁来控制并发。当单线程(排队)去更新一行记录时,性能非常高,但是当非常多的线程去并发更新一行记录时,整个数据库的性能会跌到趋近于零。

3、突发 SQL 访问

当缓存穿透或异常调用、有数据倾斜 SQL、未创建索引 SQL 等情况发生时,在高并发场景下很容易导致数据库压力过大,响应过慢,导致应用链接释放慢,导致整个系统不可用。

4、智能化运维

双十一期间这些实例的水位管控,机器水位管控,高风险实例识别,高风险实例优化,在流量高峰期从收到报警、识别问题、解决问题至少需要十多分钟,如果处理不及时峰值已经过去,导致大促失败。

此外还有商品超卖、资源的挑战等等。

 

二、系统调优

1、容量评估

(1)经验评估

预估压力/单机性能=服务器数量

根据服务器的数量和应用机器的数量、deb 机器的数量,可以得出整个数据库的连接池的设置、扩充的实例、扩充的应用机器等等,这些配置也会相应出来。

(2)单元压测

需要针对对单个实例、单个单元、单个应用模块进行压测,单元压测的主要功能是完成单元内的验证,不光是验证整个双11的流量,还要验证在单元内这个容量是否充足,以及单个系统的容量,比如是压测某一个模块(交易模块、优惠模块等等)。

(3)全链路压测

基于场景化的仿真测试,这是最接近业务的系统值的,针对全链路压测可以借助压测来验证整个分布式系统容量是否充足。

2、性能评测

(1)压测目的

发现基础设施瓶颈、中间件瓶颈系统容量瓶颈是否充足

发现分布式系统短板

(2)压测用途

保障大促容量充足,保障业务正常运转

保障核心功能、保证用户体验

评估大促成本

(3)难点

真实业务场景压测

真实 SQL 模拟

(4)基准测试

image.png

基准测试可以用 sysbenchmysqlslap 等等,官网上有基于通用场景的测试,每一个实例所达到的容量在不同的业务场景下是不一样的,通过基准测试可以预估实例所能达到的最大值、极限值,通常情况下真实的业务场景不大可能超过基准业务的值的,所以针对每一个实例所能达到的瓶颈做到心中有数。

(5)全链路压测——大促备战核武器

真实业务场景的压测往往比基准测试要复杂,阿里在双11的场景下是如何压测的呢?整个过程大概可以分为4个步骤。

首先,针对基础的涉及到的业务模块进行梳理,相应也会梳理技术架构模块以及容量预估是否充足。梳理完成之后需要造数据,准备服务器、压测流量、业务请求。

第三步进入正式压测阶段,通过压测发现短板,验证容量是否充足,验证预案。验证压测执行完成后需要针对发现的短板问题、容量问题、架构问题进行针对性的优化。

这个过程不是一蹴而就的,而是要经过很多轮的压测,阿里巴巴集团及各 BU 每年压测4000+次,每一年通过全链路发现几百个线上在以前的测试过程中没有发现的问题,所以这个真实的业务场景压测已经成为双11的必备阶段,是大促准备的备战核武器

(6)工具

PTS(Performance Testing Service)是面向所有技术背景人员的云化测试工具。有别于传统工具的繁复,PTS 以互联网化的交互,提供性能测试、API 调试和监测等多种能力。自研和适配开源的功能都可以轻松模拟任意体量的用户访问业务的场景,任务随时发起,免去繁琐的搭建和维护成本。

更是紧密结合监控、流控等兄弟产品提供站式高可用能力高效检验和管理业务性能。

DAS(Database Autonomy Service)智能压测主要应用在以下两种场景

●为应对即将到来的短期业务高峰验证当前的 RDS MySQL 规格是否需要扩容。

●数据库迁移上云前,验证目标 RDS MySQL 的规格是否满足业务需求。

(7)注意

●参数的对齐

如果想对比两个参数,在打开和关闭之后,以及设置不同的值对性能的影响,可以单独做测试。一旦测试出来最优,在压缩之前最好把参数调到最优值,不要等到压缩出来有问题了再来调参数

●网络

一般情况下,购买实例的时候 ECS  RDS 是在同一个 VBC的,但是排除用户拿线下的用的机器链接本地的数据库,然后拿本地的应用机器链接 RDS 来做性能对比,这种就是不合适的,一个主要的原因就是压测机 RDS 的网络延迟和到本地数据库的延迟差异很大

●规格

不同 RDS 的规格,它的性能差别比较大的,如果想测试 CPU 的性能,物理 IO要少,数据在内存里,但是大多数业务场景都是涉及到物理 IO 的,所以到测试数据的时候,数据量要大于内存的大小

●ECS 的网络带宽

阿里云的 ECS 限制网络带宽,以往有用户做测试的时候,RDS 资源都没有用满,但是压力也上不去,后来经过定位使 ECS 的网络带宽打满了,所以在准备整个压测的环境时,要把这些内容调好。

3、架构调优

针对数据库来说,如果所有业务的访问都用数据库来支撑,这个成本太高了

首先是缓存,它可以代替一部分关系型数据库在读方面的请求,此外,基于原理的设计以及成本方面来考虑缓存的独特性能是要比关系型数据库要好的,在成本方面也是性价比是比较高的

到数据库层面,如果要是读多写少,针对单个实例很难支撑,还可以借助于只读实例只读实例可以实现在线性的扩展读能力读的业务请求可以实现隔离,比如说可以把轻分析型拖数据型在只读实例内完成

此外,每一个只读实例都有一个单独的链接地址,如果想把某一类的业务和其他的业务区分开严格的隔离,比如说让拖数据类的场景,或者是某一类的只读的场景,某一个实例上面来访问,就可以单独的链接那个只读实例的链接串,但是如果想从整个层面来控制主实和只读实例的访问,可以借助于负载均衡独享代理来完成

独享代理可以缓解大量的短链接的场景,使用代理后不用反复的变更用内的链接地址,减少维护成本,可以对线上的资源实现扩展,承受更高的流量如果 RDS 的实例规格以及只读实例都已经升到最大,但仍然不能支撑业务的发展,可以考虑把 RDS 升级到 Polar MySQL,或者是 PolarX 2.0这种方式来完成读写容量上面的扩展

刚才提到只读实例,其实大家最关心的一个问题就是主实例和只读实例的数据一致性,比如说有延迟以及中断的这一类的场景的延迟是最多的,针对线上的延迟的问题,我们做了一个分析,主要原因包括5个方面:

●主实例的 DDL

占40%,如 alterdrop 等。需要 kill DDL 语句或用 DMS 的无锁变更等。

●主实例的大事务

占20%,如大批量导入、删除、更新数据。需要将大事务拆分成为小事务进行批量提交这样只读节点就可以迅速的完成事务的执行,不会造成数据的延迟。

●主实例写入压力过大

占20%,如主实例规格较小压力过大。这种情况需要升级主实例和只读实例的规格。

●只读节点规格过小

占10%,这种情况升级只读实例规格。

●其他(无主键)

占10%,RDS目前已经支持对表添加隐式主键,但是对于以前历史创建的表需要进行重建才能支持隐式主键。

刚才提到缓存,在高并发场景下,写入压力过大,怎样提升缓存命中率?根据以往的经验,有4种更新方式:Cache aside,Read through,Write through,Write behind caching。缓存的更新、应用可以从 Cache 里读取数据,取到后返回,或者没有取,从数据库里取,成功后再返回缓存中。Read through 是没有读到后更新缓存。Write through 是在数据更新时,发现缓存里没有,就更新缓存。Write back 类似于底层的操作系统的机制,它可以合并同一个数据的多次操作以上几种方式都不能保证版权命中率那如何保证版权命中率呢?做核心系统的时候,有一个小巧思,

image.png

就是应用程序把写请求到 RDS,读请求到 Redis,RDS 的变更数据底层是通过数据变更的这种方式,拿到增量数据后,更新 Redis,这是一个小巧思。它的好处是:

更新路径短,延迟低

缓存失效为异步流程,业务更新 DB 完成后直接返回,不需要关心缓存失效流程,整个更新路径短,更新延迟低。

应用简单可靠

应用无需实现复杂双写逻辑,只需启动异步线程监听增量数据,更新缓存数据即

可。

应用更新无额外性能消耗

因为数据订阅是通过解析 DB 的增量日志来获取增量数据,获取数据的过程对业务、DB 性能无损。

4、实例调优

(1)弹性扩容

 image.png

(2)参数调优

影响性能的几个主要参数:

●和连接相关的几个参数

back_ log  标记 MySQL 的并发链接数

table_ open_ cache  所有线程打开表的数量

thread_ cache_ size  

loose_ thread_ pool_ enabled

●和 IO 相关的几个参数

sync_ binlog

innodb_ fush_ logs_ at _trx _ commit

innodb_ io_ capacity

innodb_ io_ capacity_ max

●和内存相关的几个参数

innodb_ buffer _pool_ instances

join_ buffer_ size

tmp_ table_ size

我们把我们认为是对性的影响比较大的参数调整到高性能模板里面,应用时就可以找到对应的参数,应用到对应的实例。下图是根据普通模板以及高性能模板做的一个对比,我们可以看到普通模板相比高性能模板要低25%左右的性能。

image.png

5、内核调优

(1)版本升级

image.png

从版本上来讲,现在官方维护的是5.65.7和8.0,每一个版本的升级会带来一些新的特性,同时,它的性能也会上升,从表里可以看到8.0的性能是最强的,但是升级时也会一些坑,比如执行计划有些和原来的版本不太兼容。

(2)AliSQL 特性

最开始讲了高并发场景下面临的挑战,也会针对这些挑战提供解决方案,针对高并发的场景以及热点库存的场景,AliSQL 提供了四个补丁,其中三个补丁针对热点库存更新,其中一个补丁是库存注释。

库存注释在秒杀业务场景中,减库存场景包含两个从业务逻辑上来讲,包括拍下减库存和付款减库存。拍下减库存就是在客户拍下的时候把库存减掉,业务逻辑比较简单。付款减库存的业务逻辑比较复杂,在用户付完款后才减库存,因为复杂所以一条语句不能完成,是在事务里完成的,行锁冲突本来就比较严重,如何才能提升事务里的性能,通常情况下,开启和结束事务都是由应用来完成,如果应用处理的过慢或者网络交互的时间过慢、网络拥堵,它会增加它所持有的时间。

库存注释把持有行锁的时间、行锁释放交给数据库自己来做,AliSQL 使用排队和事务性 hint 成功就提交,失败就回滚,把控制权交给 MySQL 内核,这样可以减少行锁持有的时间,快速结束事务,进而提高减库存的吞吐能力

在减库存场景里,MySQL 分为引擎层和 server ,在高并发场景下,同一行的行锁会在 server 、引擎层来回切换,InnoDB 中事务锁的最细粒度是行级锁,如果语句针对相同行进行并发操作,会导致冲突比较严重,所以 AliSQL 把这个冲突放在 server 进行排队,对于相同行的冲突在一个桶内,可以减少冲突检测的开销,进而减少引擎层、server 来回切换带来的消耗。

第三个是语句返回,这个特性在 PG 里有,更新完后直接将结果返回,但是 MySQL 是没有的,AliSQL 把这个特性吸纳进来后也带有这个特性,如果在一个事务里更新完一行记录后,应用再发起 select,这条结果再返回给应用,可以看到它会多一次网络交互。

如果直接把 abdata 的结果返回就可以减少这次网络交互,有多次的时候性能提升可以节省多次的网络交互和应用判断的时间,也可以带来事务的性能提升以及应用性能的提升。

对于高并发场景下,AliSQL 是用线程池解决的,线程池在有大量线程来并发访问的时候,线程池会自动调节并发的线程数量在合理的范围内,避免线程池过多造成的大量缓存失效。

还有在高并发场景下,线程池会语句和事务分为不同的优先级,分别控制语句和事务的并发数量,减少资源竞争,线程池也会根据不同语句的复杂性来控制它的优先级,所以使用线程池可以将不同的 SQL 控制在合理的连接数的范围,使数据库在大的场景下保持高性能

下图是用库存注释、语句队列做的性能对比:

image.png

和原生的相比,已经翻了40倍。

6、监控报警

系统调优必不可少监控,有 RDS 自带的监控资源层的监控、引擎层的监控,还有日志的监控

对于收费来说,包括审计日志以及自服务会基于上面的 RDS 自带的以及审计日志会做一些分析,在这个基础上做的一些报警,此外,还有分布式的监控可以监控在不同的组件里面,它的瓶颈在哪里 

 

三、流程管理和生态工具

基于生态工具的保障可以从变更的流程、稳定性和数据恢复三方面来管理、介绍。

1、变更流程
image.png 

在大促期间,可以有很好的流程来提升稳定性,这个是增加在审批环节来增加审批的流程,稳定性相关的不要因为人为的因素给系统造成压力,可以设置通过 DMS 来执行的 SQL,不要让它超过一定的时间,也可以针对某一类的 DDL 或者是 DML 不允许执行,可以设置安全规则。

image.png

内核的特性,有的用户他会在业务高峰的时候会进行大文件的删除,会造成文件系统的 hint进而影响数据库的稳定性,可能会造成数据库的抖动

针对这个特性特点,阿里 SQL 提供这样的一个补丁,可以提供小批量的异步删除,慢慢的删,来减少、降低,甚至没有,取决于每一次设置的清理大小。

 image.png

还有并发的 SQL 访问,当有缓存失效或者是有数据倾斜,或者是未创建索引 SQL 的时候,会造成数据库压力过大。

阿里 SQL 针对这一类的 SQL 做了并发控制的补丁,根据关键词识别出来之后可以控制这一类 SQL 的并发度并发执行,最多允许执行多少,防止某一类的 SQL 把系统打卡的风险。

2、数据恢复

image.png

image.png

从数据恢复上来说,有的用户一般在大促的时候甚至在高峰的时候人肉来做一些数据的变更万一数据变更条件写错,也可以通过数据追踪来恢复

image.png

数据恢复还可以通过备份来恢复,备份可以分为克隆实例、整个实例级别的恢复以及库/表级别的恢复,还可以通过 DBS 数据库备份来恢复

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
2月前
|
缓存 关系型数据库 MySQL
MySQL索引策略与查询性能调优实战
在实际应用中,需要根据具体的业务需求和查询模式,综合运用索引策略和查询性能调优方法,不断地测试和优化,以提高MySQL数据库的查询性能。
208 66
|
3月前
|
存储 关系型数据库 MySQL
MySQL在企业内部应用场景有哪些
【10月更文挑战第17天】MySQL在企业内部应用场景有哪些
136 0
|
3月前
|
存储 关系型数据库 MySQL
介绍一下MySQL的一些应用场景
【10月更文挑战第17天】介绍一下MySQL的一些应用场景
500 0
|
25天前
|
缓存 NoSQL Java
高并发场景秒杀抢购超卖Bug实战重现
在电商平台的秒杀活动中,高并发场景下的抢购超卖Bug是一个常见且棘手的问题。一旦处理不当,不仅会引发用户投诉,还会对商家的信誉和利益造成严重损害。本文将详细介绍秒杀抢购超卖Bug的背景历史、业务场景、底层原理以及Java代码实现,旨在帮助开发者更好地理解和解决这一问题。
60 12
|
3月前
|
SQL 关系型数据库 MySQL
Mysql学习笔记(三):fetchone(), fetchmany(), fetchall()详细总结
MySQL中用于数据检索的`fetchone()`, `fetchmany()`, `fetchall()`函数的功能、SQL语句示例和应用场景。
99 3
Mysql学习笔记(三):fetchone(), fetchmany(), fetchall()详细总结
|
2月前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第27天】本文深入探讨了MySQL的索引策略和查询性能调优技巧。通过介绍B-Tree索引、哈希索引和全文索引等不同类型,以及如何创建和维护索引,结合实战案例分析查询执行计划,帮助读者掌握提升查询性能的方法。定期优化索引和调整查询语句是提高数据库性能的关键。
385 1
|
3月前
|
NoSQL 关系型数据库 MySQL
MySQL与Redis协同作战:优化百万数据查询的实战经验
【10月更文挑战第13天】 在处理大规模数据集时,传统的关系型数据库如MySQL可能会遇到性能瓶颈。为了提升数据处理的效率,我们可以结合使用MySQL和Redis,利用两者的优势来优化数据查询。本文将分享一次实战经验,探讨如何通过MySQL与Redis的协同工作来优化百万级数据统计。
125 5
|
3月前
|
架构师 关系型数据库 MySQL
MySQL最左前缀优化原则:深入解析与实战应用
【10月更文挑战第12天】在数据库架构设计与优化中,索引的使用是提升查询性能的关键手段之一。其中,MySQL的最左前缀优化原则(Leftmost Prefix Principle)是复合索引(Composite Index)应用中的核心策略。作为资深架构师,深入理解并掌握这一原则,对于平衡数据库性能与维护成本至关重要。本文将详细解读最左前缀优化原则的功能特点、业务场景、优缺点、底层原理,并通过Java示例展示其实现方式。
142 1
|
3月前
|
关系型数据库 MySQL 数据库
Mysql学习笔记(四):Python与Mysql交互--实现增删改查
如何使用Python与MySQL数据库进行交互,实现增删改查等基本操作的教程。
76 1
|
2月前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第26天】数据库作为现代应用系统的核心组件,其性能优化至关重要。本文主要探讨MySQL的索引策略与查询性能调优。通过合理创建索引(如B-Tree、复合索引)和优化查询语句(如使用EXPLAIN、优化分页查询),可以显著提升数据库的响应速度和稳定性。实践中还需定期审查慢查询日志,持续优化性能。
161 0
下一篇
开通oss服务