(一)高并发压力测试调优篇——MYSQL数据库的调优

news2024/9/23 11:22:03

前言

在实际项目开发中,很多业务场景下都需要考虑接口的性能要求,追求高并发、高吞吐量。那么对于此类问题如何入手呢?关注作者,不迷路。本节内容主要介绍在数据库db方面的优化,以mysql数据库为例。

关于db的优化,主要有以下几个方面的优化:

db数据库优化
db优化的层面db优化说明
查询优化①使用EXPLAIN: 分析查询执行计划,找出瓶颈。
②避免直接使用SELECT *: 明确指定需要的列,减少数据传输量。
③使用JOIN替代子查询: JOIN通常比子查询更高效。
④减少全表扫描: 尽可能使用索引。
⑤优化子查询: 使用JOIN或存在子句(EXISTS)替换嵌套子查询。
⑥避免使用LIKE 'prefix%': 这种形式的LIKE语句会导致全表扫描,除非前缀索引可用。
索引优化①创建合适的索引: 索引应基于查询中最常使用的列。
②使用覆盖索引: 索引中包含所有需要查询的列,避免回表查询。
③避免过多索引: 过多索引会增加写操作的成本。
④定期分析和优化索引: 使用ANALYZE TABLE和OPTIMIZE TABLE命令。
 配置优化①调整my.cnf/my.ini配置文件: 根据服务器硬件调整参数。
②InnoDB Buffer Pool: 设置为物理内存的60%-80%。
③Query Cache: MySQL 8.0已弃用,但在之前的版本中,合理配置可以提高性能。
④Max Connections: 设置合理的连接数,避免资源浪费。
⑤Thread Cache Size: 减少线程创建和销毁的开销。
存储引擎选择①InnoDB: 支持事务,行级锁定,适合写密集型应用。
②MyISAM: 不支持事务,但读取速度快,适合读密集型应用。
③MEMORY: 用于临时表和小数据集的快速存储。
硬件优化①足够的CPU: 处理复杂的查询和并发请求。
②充足的内存: 特别是用于InnoDB的Buffer Pool。
③高速存储: SSD比HDD快得多,减少I/O延迟。
④网络优化: 高速网络接口,减少网络延迟。
架构优化①读写分离: 主从复制,将读操作分散到从服务器。
②分区: 将大表分割成更小的部分,提高查询效率。
③集群: 使用MySQL Cluster或Galera Cluster提供高可用性和负载均衡。
定期维护①定期检查表: 使用CHECK TABLE命令检测表损坏。
②定期优化表: 使用OPTIMIZE TABLE命令整理碎片。
③定期备份: 避免数据丢失
监控与调整①性能监控: 使用slow query log,performance_schema等工具监控性能。
②定期调整: 根据监控结果调整配置和策略。
应用层优化①减少不必要的查询: 缓存结果,避免重复查询。
②优化应用程序代码: 减少数据库交互次数,使用批处理。
安全与合规①数据加密: 保护敏感数据。
②权限管理: 最小权限原则,限制不必要的数据库访问。

本节内容我们主要针对的是单个mysql数据库的优化配置,主要从数据库缓存池的大小设置、数据库最大连接数的设置、数据库表索引的设置着手。以上几个方面的优化配置能够明显提升数据库的性能。通过配合jemeter压测工具来观察优化的结果。本地服务器是14核40G,使用的数据库是mysql8.0。

正文

  • 压测前准备

①创建一个数据库,一张用户表tps_user

CREATE TABLE `tps_user` (
  `id` bigint NOT NULL COMMENT '主键',
  `username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '用户名',
  `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '密码',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='tps-用户表';

②使用springboot工程创建一个压测接口,根据用户名查询用户信息

③数据库的默认参数配置

# 默认缓冲池大小: 128M
SHOW VARIABLES LIKE 'innodb_buffer_pool_size';
# 默认最大线程连接数: 200
SHOW VARIABLES LIKE 'max_connections';
# 活跃的连接数
SHOW STATUS LIKE 'Threads_connected';
# 查看所有的线程
SHOW PROCESSLIST;

  • 压测默认缓冲池大小128M,默认数据库连接数200,用户数据一条,应用的数据库连接池最小10,最大设置为50。并发数500、1000、5000、10000

- 500并发

- 1000并发

- 2000并发

- 5000并发

结论:单条数据压测,吞吐量4000左右,不具有参考价值,因为一条数据,默认查询的是缓冲池的数据,查询会走数据库缓存,吞吐量会很高。同时我们也可以看到,随着并发数据的上升,吞吐量基本差别不大,但是响应时间明显会增大。

压力测试结果
并发数吞吐率QPS平均响应时间
5004756.1/sec103ms
10004374.9/sec224ms
20004512.6/sec429ms
50003925.9/sec1237ms
  • 压测默认缓冲池大小128M,默认数据库连接数200,用户数据100万,应用的数据库连接池最小10,最大设置为50。并发数500、1000、5000、10000

- 生成100万用户测试数据

- 500并发:随着压测时间的增长,吞吐量基本稳定在11.4左右,响应时间逐渐变大

- 1000并发:随着压测时间的增长,吞吐量基本稳定在11.4左右,响应时间逐渐变大

- 2000并发:随着压测时间的增长,吞吐量基本稳定在11.4左右,响应时间逐渐变大

- 5000并发:随着压测时间的增长,吞吐量基本稳定在11.2左右,响应时间逐渐变大

结论:100万用户数据压测,吞吐量只有11左右,可以明显的看到吞吐量急剧下降,而且随着压测时间持续时间的增长,响应时间也在逐渐变大。随着并发数的增大,吞吐率和平均响应时间差别不大,数据基本不会走缓冲,基本都要经过数据库的IO读写操作。数据库此时遇到了瓶颈。

压力测试结果
并发数吞吐率QPS平均响应时间
50011.4/sec28157ms
100011.4/sec36718ms
200011.4/sec31768ms
500011.4/sec33850ms
  • 优化一:将用户的查询字段增加索引,压测的默认配置保持不变。压测默认缓冲池大小128M,默认数据库连接数200,用户数据100万,应用的数据库连接池最小10,最大设置为50。并发数500、1000、5000、10000

- 增加查询字段的索引

- 500并发:吞吐量4416,平均响应时间111ms

-1000并发:吞吐量4671,平均响应时间210ms

-2000并发:吞吐量4615,平均响应时间401ms

-5000并发:吞吐量4204,平均响应时间1145ms

结论:100万用户数据压测,增加索引后,吞吐量达到4500左右,与不创建索引天差地别,平均响应时间也变为毫秒级,且随着并发访问增大而平均响应时间也增大。为什么吞吐量会变大是因为创建索引后,数据不用全表逐行扫描,能够很快的定位数据的位置,减少数据库IO操作。如果缓存中存在索引数据,则可以完全不用IO操作,直接内存中查询;如果缓存中不存在,且是覆盖索引,则需要一次IO操作;如果缓存中不存在,且不是覆盖索引,则需要俩次IO,一次索引查询,一次用于回表读取数据行;如果是范围查询,则可能需要多次IO操作。由此可见,对于查询操作而言,对于合理的索引创建能够大幅度提高数据库的访问性能。

压力测试结果
并发数吞吐率QPS平均响应时间
5004416/sec111ms
10004671/sec210ms
20004615/sec401ms
50004204/sec1145ms
  • 优化二:增加数据库最大连接数以及应用的数据库连接池个数。将用户的查询字段索引去掉(尽量排除缓存干扰),压测的默认配置保持不变。压测默认缓冲池大小128M,默认数据库连接数改为1000,用户数据100万,应用的数据库连接池最小10,最大设置改为200。并发数500、1000、5000、10000

- 准备工作1,设置数据库最大连接个数为1000

SET GLOBAL max_connections=1000;

- 准备工作1,配置应用的数据库连接池个数最大为200

- 500并发:吞吐量14.8,平均响应时间25159ms

- 1000并发:吞吐量17.4,平均响应时间28160ms

- 2000并发:吞吐量17.6,平均响应时间32575ms

- 5000并发:吞吐量43.2,平均响应时间7423,开始出现报错

结论:100万用户数据压测,不加索引,只通过增加数据库连接数,从结果来看增大数据库连接数,以及数据库连接池的个数,并不能提升数据库的吞吐能力,而且随着并发的提高,出现了错误。

压力测试结果
并发数吞吐率QPS平均响应时间
50014.8/sec25159ms
100017.4/sec28160ms
200017.6/sec32575ms
500043.2/sec7423ms
  • 优化三:在优化二的基础上增加数据库缓冲池的大小为10G。将用户的查询字段索引去掉(尽量排除缓存干扰),压测的默认配置保持不变。数据库连接数改为1000,用户数据100万,应用的数据库连接池最小10,最大设置改为200。并发数500、1000、5000、10000

- 准备工作1,设置数据库的缓冲池大小为10G

- 500并发:吞吐量13.9,平均响应时间23497ms

- 1000并发:吞吐量17.3,,平均响应时间22212ms

- 2000并发:吞吐量17.3,,平均响应时间20856ms

- 5000并发:吞吐量230,,平均响应时间1196ms,开始报错

结论:100万用户数据压测,不加索引,只通过增加数据库连接数和缓冲池的大小。从结果来看增大数据库连接数、缓冲池大小以及数据库连接池的个数,并不能提升数据库的吞吐能力,而且随着并发的提高,出现了错误。这是因为数据库的查询操作还是会走大量的IO操作,导致吞吐量基本没什么变化。

压力测试结果
并发数吞吐率QPS平均响应时间
50013.9/sec23497ms
100017.3/sec22212ms
200017.3/sec20856ms
5000230/sec1196ms
  • 终极优化:数据库查询字段添加索引,缓冲池大小设置为10G,数据库连接数设置为1000,应用连接池个数设置为200,并发数500、1000、5000、10000压测

- 500并发:吞吐量4455,平均响应时间109

- 1000并发:吞吐量4524,平均响应时间222

- 2000并发:吞吐量4463,平均响应时间421

- 5000并发:吞吐量4397,平均响应时间1170

结论:100万用户数据压测,吞吐量能达到4000左右,响应时间基本1秒以内,随着并发请求增大,响应时间也变慢。

压力测试结果
并发数吞吐率QPS平均响应时间
5004455/sec109ms
10004524/sec222ms
20004463/sec421ms
50004397/sec1170ms

结语

通过压测实验,我们可以明确的一点是,数据库的性能瓶颈主要来源于数据库的IO操作,有效的减少数据库的IO操作次数是优化数据库访问性能的关键,有效的创建索引、增加缓冲池大小、以及设置一定比例的数据库连接,能够有效的减少数据库的IO操作,从而提高数据库的访问性能。一般的建议,数据库的缓冲池大小innodb_buffer_pool_size设置为总内存的0.75,数据库最大连接数据设置为内存/12582080个。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1921248.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python库(11):Box库简化字典和对象之间的转换

1Box库简介 Box是一个Python库,它提供了一种将数据封装在字典和列表中的方式,同时提供了一些额外的功能,比如数据验证、默认值设置等。这使得Box库非常适合用于配置管理、数据传输对象(DTO)的创建,以及任何…

PDF 中图表的解析探究

PDF 中图表的解析探究 0. 引言1. 开源方案探究 0. 引言 一直以来,对文档中的图片和表格处理都非常有挑战性。这篇文章记录一下最近工作上在这块的探究。图表分为图片和表格,这篇文章主要记录了对表格的探究。还有,我个人主要做日本项目&…

[C++]——同步异步日志系统(4)

同步异步日志系统 一、日志等级模块设计二、日志消息类设计 一、日志等级模块设计 定义出日志系统所包含的所有日志等级分别为:(7个等级) UNKNOW0,未知等级的日志DRBUG ,调试等级的日志INFO ,提示等级的日…

前端调试技巧(npm Link,vscode调试,浏览器调试等)

Npm Link 功能: 在本地开发npm模块的时候,我们可以使用npm link命令,将npm 模块链接到对应的运行项目中去,方便地对模块进行调试和测试 断点调试 vscode调试 Debug Vue2 Project 目标:在VSCode中调试项目代码…

docker拉取镜像-配置阿里云镜像加速

1、配置阿里云镜像&#xff08;用于拉取镜像加速&#xff09; sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-EOF {"registry-mirrors": ["https://xxxxxxxx.mirror.aliyuncs.com"] } EOF sudo systemctl daemon-reload sudo syst…

论文阅读【时间序列】TimeMixer (ICLR2024)

【时间序列】TimeMixer (ICLR2024) 原文链接&#xff1a;TIMEMIXER: DECOMPOSABLE MULTISCALE MIXING FOR TIME SERIES FORECASTING 代码仓库&#xff1a;https://github.com/kwuking/TimeMixer 符号定义 符号含义P用于预测的历史序列长度&#xff08;seq_len&#xff09;F预测…

debian 12 Install

debian 前言 Debian是一个基于Linux内核的自由和开放源代码操作系统&#xff0c;由全球志愿者组成的Debian项目维护和开发。该项目始于1993年&#xff0c;由Ian Murdock发起&#xff0c;旨在创建一个完整的、基于Linux的自由软件操作系统。 debian download debian 百度网盘…

LangChain之工具Tools(下)

LangChain之工具Tools SQLDatabase工具准备数据初始化数据库光标查询​字符串查询带参数查询​使用SQLAlchemy查询​使用自然语言查询数据库 使用其他工具Tavily Search工具Dall-E图像生成工具ArXiv工具 SQLDatabase工具 在 LangChain 中,SQLDatabase工具可以用来与SQL数据库进…

和Bug较劲的第n天:[Error: Unable to open snapshot file: No such file or directory]

问题描述 最近做了一个小demo&#xff0c;基于parcel的&#xff0c;在迁移仓库的时候发生了一个报错 [Error: Unable to open snapshot file: No such file or directory] 原因分析&#xff1a; 在迁移仓库的时候&#xff0c;我将项目放入了一个以中文命名的文件夹里&#xf…

在生产环境中部署Elasticsearch:最佳实践和故障排除技巧——安装篇(一)

#在生产环境中部署Elasticsearch&#xff1a;最佳实践和故障排除技巧——安装篇&#xff08;一&#xff09; 前言 关键字&#xff1a; 机器学习 人工智能 AI chatGPT 学习 实现 使用 搭建 深度 python 事件 远程 docker mysql安全 技术 部署 技术 自动化 代码 文章目录 - -…

【斯坦福因果推断课程全集】2_无混淆和倾向分1

目录 Beyond a single randomized controlled trial Aggregating difference-in-means estimators Continuous X and the propensity score 随机试验的一个最简单的扩展是无约束下的干预效果估计。从定性上讲&#xff0c;当我们想估计一种并非随机的治疗效果&#xff0c;但一…

python-小理与他的画(赛氪OJ)

[题目描述] 小理是个画家&#xff0c;他希望有一天他的画能让心仪的她看到。 只是后来她有了他&#xff0c;他却只有他的画&#xff0c;他望着他的画&#xff0c;默默的发呆。 可惜做题的你&#xff0c;画不出他画的她&#xff0c;所以&#xff0c;我们只好画点简单的画&#x…

MFC扩展库BCGControlBar Pro v35.0 - 可视化管理主题等全新升级

BCGControlBar库拥有500多个经过全面设计、测试和充分记录的MFC扩展类。 我们的组件可以轻松地集成到您的应用程序中&#xff0c;并为您节省数百个开发和调试时间。 BCGControlBar专业版 v35.0已全新发布了&#xff0c;这个版本改进类Visual Studio 2022的视觉主题、增强对多个…

土壤分析仪:解密土壤之奥秘的科技先锋

在农业生产和生态保护的道路上&#xff0c;土壤的质量与状况一直是我们关注的焦点。土壤分析仪&#xff0c;作为现代科技在农业和环保领域的杰出代表&#xff0c;以其高效、精准的分析能力&#xff0c;为我们揭示了土壤的奥秘&#xff0c;为农业生产提供了科学指导&#xff0c;…

只为拿证,软考中级哪个科目比较简单?

在探讨软考中级哪个最容易过时&#xff0c;我们首先需要了解软考的类别和具体的中级证书种类。软考全称为计算机技术与软件专业技术资格水平考试&#xff0c;是全国统一的考试&#xff0c;其证书由人力资源和社会保障部和国家工业和信息化部门联合颁发&#xff0c;具有很高的证…

cuda缓存示意图

一、定义 cuda 缓存示意图gpu 架构示意图gpu 内存访问示意图 二、实现 cuda 缓存示意图 DRAM: 通常指的是GPU的显存&#xff0c;位于GPU芯片外部&#xff0c;通过某种接口&#xff08;如PCIE&#xff09;与GPU芯片相连。它是GPU访问的主要数据存储区域&#xff0c;用于存储…

Git 详解(原理、使用)

git 快速上手请看这篇博客 Git 快速上手 1. 什么是 Git Git 是目前最主流的一个版本控制器&#xff0c;并且是分布式版本控制系统&#xff0c;可以控制电脑上所有格式的文档 版本控制器&#xff1a;记录每次修改以及版本迭代的管理系统 对于文本文件&#xff0c;可以记录每次…

AI就业指导机器人,你的专属职业导航灯!

本文由 ChatMoney团队出品 介绍说明 Hey&#xff01;亲爱的小伙伴们&#xff0c;今天我要给大家带来一个职场利器——AI就业指导机器人&#xff01;&#x1f916; 在这个充满变数的职场江湖&#xff0c;找到一份既能养家糊口又能实现自我价值的工作是多么重要。但是&#xff…

springCloud整合Dubbo案例

前言&#xff1a; 好久没有使用dubbo了&#xff0c;温习一下。 一、先搭建一个SpringCloud框架 整体框架如下图 1. 先创建一个父工程&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4…

【Qt 初识】QPushButton 的详解以及 Qt 中的坐标

文章目录 1. Qt 中的信号槽机制 &#x1f34e;2. 通过图形化界面的方式实现 &#x1f34e;3. 通过纯代码的方式实现按钮版的HelloWorld &#x1f34e;4. 设置坐标 &#x1f34e; 1. Qt 中的信号槽机制 &#x1f34e; 》&#x1f427; 本质就是给按钮的点击操作&#xff0c;关联…