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

前言

在实际项目开发中,很多业务场景下都需要考虑接口的性能要求,追求高并发、高吞吐量。那么对于此类问题如何入手呢?关注作者,不迷路。本节内容主要介绍在数据库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.mzph.cn/news/871274.shtml

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

相关文章

7、matlab实现SGM/BM/SAD立体匹配算法计算视差图

1、matlab实现SGM/BM/SAD立体匹配算法计算视差图简介 SGM(Semi-Global Matching)、BM(Block Matching)和SAD(Sum of Absolute Differences)都是用于计算立体匹配(Stereo Matching)的…

远程帮客户解决“应用程序无法正常启动0xc000007b,请单击确定关闭应用程序”的问题

今天收到反馈,SmartPipe软件,在客户机器上报错,无法正常运行,采用远程控制软件进入客户电脑,发现电脑报错如下: 因为客户的电脑是win7,而之前发生过win7电脑上无法运行OCC编写的软件的情况&…

termux 安装 rockylinux

centos已经被“招安”了,取而代之的是rockylinux,本文记录我自己的配置,主要需求是使用termux安装rockylinux文件系统,并使用supervisor自启动code-server 安装termux 从https://github.com/termux/termux-app/releases/获取最新…

常用视觉分类、目标检测模型性能测试

说明 测试常用CV模型在单张图像上的识别速度,不包含图像读取时间,但包含图像预处理。可以在以后的应用中根据硬件配置选取合适的模型,达到最佳效果。其中推理速度为正常推理的速度,加速CPU使用openvino加速,GPU使用te…

产品经理-一份标准需求文档的8个模块(14)

一份标准优秀的产品需求文档包括: ❑ 封面; ❑ 文档修订记录表; ❑ 目录; ❑ 引言; ❑ 产品概述:产品结构图 ❑ 详细需求说明:产品逻辑图、功能与特性简述列表、交互/视觉设计、需求详细描述&am…

docker运行nginx挂载前端html页面步骤

1.常用docker命令 1.docker ps -a 查看所有容器 2.docker ps查看存活的容器 3.docker rm 删除容器 4.docker stop 停止容器运行 5.docker logs 容器id 查看容器日志 6.docker images 查看镜像 7.docker rmi 删除镜像 8.docker exec nginx nginx -s reload 重新加载conf文件…

H3C MSR2600路由器IPv6地址显示TENTATIVE的故障

有一MSR2600路由器,系统软件版本为5.2 R2516P28,使用电信PON PPPoE拨号上网。 在全局启用IPv6,并在Dialer接口上配置了如下IPv6命令: ipv6 address auto ipv6 address auto link-local 使用display ipv6 interface brief命令查看…

Java中的volatile关键字有什么作用?

Java中的volatile关键字是一种轻量级的同步机制,它主要有两个作用: 保证可见性(Visibility): 当多个线程访问某个类的共享变量时,如果没有适当的同步机制,一个线程对变量的修改可能对其他线程不…

闲来无事,论茴香豆的茴有几种写法

一、引言 以下是几行浅薄而简洁的代码,聊聊add函数有哪几种写法。抛砖引玉,也许在你实际的项目中会带来些许的收益。 二、知识点 知识点比较简单: 左值和右值引用,std::move 的移动语义,模版等 三、代码&#xff0…

Java实现数据结构——双链表

目录 一、前言 二、实现 2.1 类的创建 三、对链表操作实现 3.1 打印链表 3.2 插入数据 3.2.1 申请新节点 3.2.2 头插 ​编辑 3.2.3 尾插 3.2.4 链表长度 3.2.5 任意位置插入 3.3 删除数据 3.3.1 头删 3.3.2 尾删 3.3.3 删除指定位置数据 3.3.4 删除指定数据 3…

C++ PImpl模式、指向实现的指针、PImpl Idiom、隐藏实现细节

C PImpl模式、指向实现的指针、PImpl Idiom、隐藏实现细节 flyfish PImpl 全称是 “Pointer to Implementation”,在中文中通常翻译为“指向实现的指针”或者“指向实现”。PImpl 是一种编程技巧,通常用于 C 中,通过这种技术,可…

涉案财物管理系统|八大模块可视化展示

涉案财物管理系统DW-S405系统基于物联网技术规范涉案财物管理流程,确保涉案财物的安全性、完整性和合法性;可以提高办案效率,减少办案成本,实现资源共享。 涉案财物管理系统DW-S405主要分为 8 大模块数据展示。 1、案件信息&…

Linux C | 管道open打开方式

Linux C | 管道open打开方式 1.参考 1. 管道 2.现象 是的,这段代码在调用 open(AUDIOIN_FIFO, O_RDONLY) 时可能会被阻塞。原因是 FIFO(命名管道)在以只读模式打开时,如果没有其他进程以写模式打开该 FIFO,open 调用将…

防火墙综合实验二

目录 实验要求 IP地址配置 需求七 需求八 需求九 需求十 需求十一 实验要求 接防火墙综合实验一! 7,办公区设备可以通过电信链路和移动链路上网(多对多的NAT,并且需要保留一个公网IP不能用来转换)。 8,分公司设备可以通过…

美无定论,娜扎亦菲各自绽放你更爱哪一款?

娜扎亦菲各自绽放你更爱哪一款? 哎呀,这个问题可真是让我头疼呢, 就像让我在两个糖果店里选择最甜的那一颗一样难! 古力娜扎和刘亦菲,两位都是娱乐圈里璀璨的明珠, 美得各有千秋,让人怎么舍得…

python爬虫js逆向入门

js基础 在 JavaScript 逆向工程中,常常会遇到一些复杂的代码结构,这些代码可能包含各种函数定义、对象操作、异步调用等。 ### 1. 函数声明和调用function generateSignature(uri, params) { // 将 uri 和参数对象转换为字符串 var data uri ? Objec…

C++基础入门(上)

个人主页:C忠实粉丝 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C忠实粉丝 原创 C基础入门(上) 收录于专栏【C语法基础】 本专栏旨在分享学习C的一点学习笔记,欢迎大家在评论区交流讨论💌 目录 1. C发展历史 2. C版本…

如何在SpringCloud项目中实现断路器模式?

在Spring Cloud项目中实现断路器(Circuit Breaker)模式可以通过几种不同的库实现,如Netflix Hystrix、Resilience4j或Spring Cloud Circuit Breaker。断路器模式允许您的应用在遇到服务故障时快速失败,防止故障的蔓延和系统过载&a…

ffmpeg 找到编解码器,和编解码器上下文后,是如何初始化具体的编解码器的?aac 初始化流程大致如下

1.当使用 avcodec_find_encoder_by_name找到编码器的时候, const AVCodec * aacencoder avcodec_find_encoder_by_name("libx264"); 编码器 有值的是: id AV_CODEC_ID_H264 (27) long_name libx264 H.264…

read paper and make summer (Image enhancement)

read paper and make summer ==标题==:图像==标题==:低级视觉方法==标题==:颜色直方图==标题==:颜色空间变换==标题==:亮度通道==标题==:色度通道==标题==:图像滤波==标题==:方盒滤波==标题==:均值滤波==标题==:高斯滤波(去噪)==标题==:中值滤波(去噪)==标题==:…