数据库消耗内存大还是cpu大

数据库消耗内存大还是cpu大,第1张

作者 王文安,腾讯CSIG数据库专项的数据库工程师,主要负责腾讯云数据库 MySQL 的相关的工作,热爱技术,欢迎留言进行交流。文章首发于腾讯云+社区的腾讯云数据库专家服务专栏。

在日常工作中,发现 MySQL 的状态不太对劲的时候,一般都会看看监控指标,很多时候会看到熟悉的一幕:CPU 使用率又爆了。本文将给大家介绍 MySQL 和 CPU 之间的关系,对此有一定的了解之后可以更准确的判断出问题的原因,也能够提前发现一些引发 CPU 问题的隐患。

怎么看懂CPU使用率

以 Linux 的 top 命令为例,效果如下:

Top 命令

在 %CPU 这一列就展示了 CPU 的使用情况,百分比指代的是总体上占用的时间百分比:

%us:表示用户进程的 CPU 使用时间(没有通过 nice 调度)

%sy:表示系统进程的 CPU 使用时间,主要是内核使用。

%ni:表示用户进程中,通过 CPU 调度(nice)过的使用时间。

%id:空闲的 CPU 时间

%wa:CPU 运行时在等待 IO 的时间

%hi:CPU 处理硬中断花费的时间

%si:CPU 处理软中断花费的时间

%st:被虚拟机偷走的 CPU 时间

通常情况下,我们讨论的 CPU 使用率过高,指的是 %us 这个指标,监控里面的 CPU 使用率通常也是这个值(也有用其他的方法计算出来的,不过简单起见,不考虑其他的情况 )。其他几个指标过高也代表出 MySQL 的状态异常,简单起见,这里主要还是指 %us 过高的场景。

MySQL和线程

MySQL 是单进程多线程的结构,意味着独占的 MySQL 服务器里面,只能用 top 命令看到一行数据。

TOP 命令效果

这里能看到的是 MySQL 的进程 ID,如果要看到线程的情况,需要用top -H

TOP 命令效果

在这里能看到的是 MySQL 各个线程的 ID,可以看到 MySQL 在启动之后,会创建非常多的内部线程来工作。

这些内部线程包括 MySQL 自己用来刷脏,读写数据等 *** 作的系统线程,也包括处理用户 SQL 的线程,姑且叫做用户线程吧。用户线程有一个特殊的地方:程序端发送到 MySQL 端的 SQL,只会由一个用户线程来执行(one-thread-per-connection),所以 MySQL 在处理复杂查询的时候,会出现“一核有难,多核围观”的尴尬现象。

参考 %us 的定义,对于 Linux 系统来说,MySQL 进程和它启动的所有线程都不算内核进程,因此 MySQL 的系统线程和用户线程在繁忙的时候,都会体现在 CPU 使用率的 %us 指标上。

什么时候CPU会100%

MySQL 干什么的时候,CPU 会 100%?从前文的分析来看,MySQL 主要是两类线程占用 CPU:系统线程和用户线程。因此 MySQL 独占的服务器上,只需要留意一下这两类线程的情况,就能 Cover 住绝大部分的问题场景。

系统线程

在实际的环境中,系统线程遇到问题的情况会比较少,一般来说,多个系统线程很少会同时跑满,只要服务器的可用核心数大于等于 4 的话,一般也不会遇到 CPU 100%,当然有一些 bug 可能会有影响,比如这个:

MySQL BUG

虽然情况比较少,但是在面对问题的常规排查过程中,系统线程的问题也是需要关注的。

用户线程

提到用户线程繁忙,很多时候肯定会第一时间凭经验想到慢查询。确实 90% 以上的时候都是“慢查询”引起的,不过作为方法论,还是要根据分析再去得出结论的~

参考 us% 的定义,是指用户线程占用 CPU 的时间多少,这代表着用户线程占用了大量的时间。

一方面是在进行长时间的计算,例如:order by,group by,临时表,join 等。这一类问题可能是查询效率不高,导致单个 SQL 语句长时间占用 CPU 时间,也有可能是单纯的数据量比较多,导致计算量巨大。另一方面是单纯的 QPS 压力高,所以 CPU 的时间被用满了,比如 4 核的服务器用来支撑 20k 到 30k 的点查询,每个 SQL 占用的 CPU 时间并不多,但是因为整体的 QPS 很高,所以 CPU 的时间被占满了。

问题的定位

分析完之后,就要开始实战了,这里根据前文的分析给出一些经典的 CPU 100% 场景,并给出简要的定位方法作为参考。

PS:系统线程的 bug 的场景 skip,以后有机会再作为详细的案例来分析。

慢查询

在 CPU 100% 这个问题已经发生之后,真实的慢查询和因为 CPU 100% 导致被影响的普通查询会混在一起,难以直观的看 processlist 或者 slowlog 来发现尊敬的大船,这时候就需要一些比较明确的特征来进行甄别。

从前文的简单分析可以看出来,查询效率不高的慢查询通常有以下几种情况:

全表扫描:Handler_read_rnd_next 这个值会大幅度突增,且这一类查询在 slowlog 中 row_examined 的值也会非常高。

索引效率不高,索引选错了:Handler_read_next 这个值会大幅度的突增,不过要注意这种情况也有可能是业务量突增引起的,需要结合 QPS/TPS 一起看。这一类查询在 slowlog 中找起来会比较麻烦,row_examined 的值一般在故障前后会有比较明显的不同,或者是不合理的偏高。

比如数据倾斜的场景,一个小范围的 range 查询在某个特定的范围内 row_examined 非常高,而其他的范围时 row_examined 比较低,那么就可能是这个索引效率不高。

排序比较多:order by,group by 这一类查询通常不太好从 Handler 的指标直接判断,如果没有索引或者索引不好,导致排序 *** 作没有消除的话,那么在 processlist 和 slowlog 通常能看到这一类查询语句出现的比较多。

当然,不想详细的分析 MySQL 指标或者是情况比较紧急的话,可以直接在 slowlog 里面用 rows_sent 和 row_examined 做个简单的除法,比如 row_examined/rows_sent >1000 的都可以拿出来作为“嫌疑人”处理。这类问题一般在索引方面做好优化就能解决。

PS:1000 只是个经验值,具体要根据实际业务情况来定。

计算量大

这一类问题通常是因为数据量比较大,即使索引没什么问题,执行计划也 OK,也会导致 CPU 100%,而且结合 MySQL one-thread-per-connection 的特性,并不需要太多的并发就能把 CPU 使用率跑满。这一类查询其实是是比较好查的,因为执行时间一般会比较久,在 processlist 里面就会非常显眼,反而是 slowlog 里面可能找不到,因为没有执行完的语句是不会记录的。

这一类问题一般来说有三种比较常规的解决方案:

读写分离,把这一类查询放到平时业务不怎么用的只读从库去。

在程序段拆分 SQL,把单个大查询拆分成多个小查询。

使用 HBASE,Spark 等 OLAP 的方案来支持。

高 QPS

这一类问题单纯的就是硬件资源的瓶颈,不论是 row_examined/rows_sent 的比值,还是 SQL 的索引、执行计划,或者是 SQL 的计算量都不会有什么明显问题,只是 QPS 指标会比较高,而且 processlist 里面可能什么内容都看不到,例如:

processlist

总结

实际上 CPU 100% 的问题其实不仅仅是单纯的 %us,还会有 %io,%sys 等,这些会涉及到 MySQL 与 Linux 相关联的一部分内容,展开来就会比较多了。本文仅从 %us 出发尝试梳理一下排查&定位的思路和方法,在分析 %io,%sys 等方面的问题时,也可以用类似的思路,从这些指标的意义开始,结合 MySQL 的一些特性或者特点,逐步理清楚表象背后的原因。

被面试官经常问到之前开发的系统接口 QPS 能达到多少,经常给不出一个数值,支支吾吾,导致整体面试效果降低?

原因基本是一些公司中,做完功能测试就完了,压根不会有性能测试这一步,或者说并发量较少,没有必要进行性能测试,亦或者,交给测试人员后,只要整体问题不大,测试报告一般也是不会再给后端人员看的,这就导致我们在面试的时候,场面一度尴尬 !!!

其实,不单单是针对面试,作为一名后端开发者,我们在完成一个接口开发后,在交给测试工程师之前,经常也会想知道,自己写的这个接口的性能如何呢?吞吐量能达到多少?QPS(Query per second 每秒处理完的请求数) 能达到多少呢?

这个时候,我们就需要借助一些常用的性能测试工具,如 Apache ab, Apache JMeter (互联网公司用的较多),LoadRunner 等。

我们今天主要说一说轻量级性能测试工具 wrk

一、什么是 wrk

二、 wrk 的优势&劣势

三、wrk 安装

四、如何使用

五、总结

六、参考文档

七、赠送面试&学习福利资源

摘自官方 GitHub 上的英文介绍:

翻译一下:

wrk 是一款针对 Http 协议的基准测试工具,它能够在单机多核 CPU 的条件下,使用系统自带的高性能 I/O 机制,如 epoll,kqueue 等,通过多线程和事件模式,对目标机器产生大量的负载。

在说 wrk 的优势之前,瞅一下 wrk 的 GitHub Star 数,也能侧面反映下它的可靠性:

Wow ! 截止笔者截图为止, Star 数已经达到了 19742 !!!

再来说说 wrk 的优势:

wrk 目前仅支持单机压测,后续也不太可能支持多机器对目标机压测,因为它本身的定位,并不是用来取代 JMeter, LoadRunner 等专业的测试工具,wrk 提供的功能,对我们后端开发人员来说,应付日常接口性能验证还是比较友好的。

wrk 只能被安装在类 Unix 系统上,所以我们需要一个 Linux 或者 MacOS 环境。Windows 10 安装需要开启自带的 Ubuntu 子系统。

依次执行如下命令:

依次执行如下命令:

Mac 系统也可以通过先编译的方式来安装,但是更推荐使用 brew 的方式来安装, 步骤如下:

Windown 10 需要在 Windows 功能 里勾选 适用于 Linux 的 Windows 子系统 , 然后通过 bash 命令切换到 Ubuntu 子系统。接下来,参考 3.1.1 Ubuntu 的 *** 作系通中,安装 wrk 的步骤。

命令行中输入命令:

输出如上信息,说明安装成功了!

安装成功了,要如何使用呢?

这条命令表示,利用 wrk 对 www.baidu.com 发起压力测试,线程数为 12,模拟 400 个并发请求,持续 30 秒。

除了上面简单示例中使用到的子命令参数, wrk 还有其他更丰富的功能,命令行中输入 wrk --help , 可以看到支持以下子命令:

翻译一下:

执行压测命令:

执行上面的压测命令,30 秒压测过后,生成如下压测报告:

我们来具体说一说,报告中各项指标都代表什么意思:

可以看到,压测报告还是非常直观的!

您可能有疑问了,你这种进行 GET 请求还凑合,我想进行 POST 请求咋办?而且我想每次的请求参数都不一样,用来模拟用户使用的实际场景,又要怎么弄呢?

对于这种需求,我们可以通过编写 Lua 脚本的方式,在运行压测命令时,通过参数 --script 来指定 Lua 脚本,来满足个性化需求。

wrk 支持在三个阶段对压测进行个性化,分别是启动阶段、运行阶段和结束阶段。每个测试线程,都拥有独立的Lua 运行环境。

启动阶段:

在脚本文件中实现 setup 方法,wrk 就会在测试线程已经初始化,但还没有启动的时候调用该方法。wrk会为每一个测试线程调用一次 setup 方法,并传入代表测试线程的对象 thread 作为参数。setup 方法中可 *** 作该 thread 对象,获取信息、存储信息、甚至关闭该线程。

运行阶段:

结束阶段:

done() 方法在整个测试过程中只会被调用一次,我们可以从给定的参数中,获取压测结果,生成定制化的测试报告。

自定义 Lua 脚本中可访问的变量以及方法:

变量:wrk

以上定义了一个 table 类型的全局变量,修改该 wrk 变量,会影响所有请求。

方法:

上面三个方法解释如下:

调用 POST 接口:

注意: wrk 是个全局变量,这里对其做了修改,使得所有请求都使用 POST 的方式,并指定了 body 和 Content-Type头。

自定义每次请求的参数:

在 request 方法中,随机生成 1~10000000 之间的 uid,并动态生成请求 URL.

每次请求前,延迟 10ms:

请求的接口需要先进行认证,获取 token 后,才能发起请求,咋办?

上面的脚本表示,在 token 为空的情况下,先请求 /auth 接口来认证,获取 token, 拿到 token 以后,将 token 放置到请求头中,再请求真正需要压测的 /test 接口。

压测支持 HTTP pipeline 的服务:

通过在 init 方法中将三个 HTTP请求拼接在一起,实现每次发送三个请求,以使用 HTTP pipeline。

本文中,我们学习了轻量级性能测试工具 wrk, 如何安装,以及具体的使用方法,包括通过 Lua 脚本来个性化定制请求等。希望读完本文,能对您有所帮助哦!

 你要的全在下面:数据库已经有4代了产品很多。

DBA课程更新内容大纲:

序章 DBA职业体系与数据库产品趋势

What is DBA?

DBA成长体系与职业方向(0-30W-50W-100W-???)

数据库发展历史,产品迭代趋势与职业学习方向

第一部分 OLTP数据库-MySQL(约1天)

MySQL基础入门

MySQL数据库简介

什么是数据库?什么是OLTP?

为什么学习MySQL?MySQL产品迭代

一二线大厂MySQL主流版本功能使用与特性介绍(5.1,5.6,5.7,8.0)**独家**

MySQL部署与管理体系

5.7,8.0版本企业规范部署,启动

MySQL管理体系讲解

MySQL产品架构分析与基础管理

MySQL基础架构解析(一条SQL是如何执行的)

MySQL启动过程

MySQL连接的生命与使命

MySQL表结构实现原理

MySQL开发应用(约1.5天)

MySQL       SQL基础应用

声明式式语言与SQL语言

SQL语言应用场景与sqlmode

MySQL开发工具选择与使用

MySQL字符串类型与字符集

MySQL语句类型介绍(DDL,DCL,DML,DQL)

SQL之查询基础

SQL之聚合与排序

SQL之数据更新

SQL之复杂查询

SQL之集合运算

MySQL       SQL高级处理与开发

函数开发与应用

存储过程,触发器,事件

表分区管理及企业级应用场景

Online DDL解析与开源生态OPS

窗口函数讲解及应用场景

MySQL JSON开发及应用

一二线大厂MySQL企业级开发规范详解**独家**

MySQL核心技术

MySQL       InnoDB索引实现原理及执行计划分析(约0.5天)

索引介绍

1.      索引的由来

2.      表和索引结构

3.      表聚簇与索引行

4.      表行与索引组织表

MySQL索引介绍

InnoDB索引B+ tree的索引设计

聚簇索引与二级索引

InnDB索引插入过程

数据类型对索引应用的使用影响

执行计划介绍及结果剖析

索引优化基础实战演练

企业级索引优化实战案例(亿万级QPS的索引优化与索引上线)**独家**

MySQL InnoDB存储引擎技术内幕与深入讲解(约1天)

Mysql存储引擎介绍与功能特性

InnoDB引擎源代码目录结构与存储引擎文件组织

InnoDB存储引擎核心架构介绍及解析

InnoDB数据存储结构

InnoDB事务详解及ACID特性解析

InnoDB 日志管理机制Undo与Redo

InnoDB事务与隔离级别

InnoDB MVCC及锁机制

MySQL日志管理与实战(0.5)

General log详解

Error log详解

企业级Binary log with Data pipeline **独家**

企业级Slowlog场景应用**独家**

MySQL备份恢复与迁移(0.5)

备份工具介绍与使用场景解析

一二线大厂过万数据节点备份策略**独家**

一二线大厂Mysqldump核心原理与企业级实战演练**独家**

一二线大厂Xtrabackup核心原理与企业级实战演练**独家**

Enterprise Backup企业级生态工具介绍与应用

MySQL主从复制深入(约1天)

主从复制简介与简单搭建

主从复制工作原理解析

主从数据一致性方案讲解(半同步,全同步)

MySQL主从复制实战

1.      延时复制

2.      过滤复制

3.      多源复制

MySQL GTID复制

企业级主从复制故障分析与处理方案

亿级QPS MySQL节点故障转移实战案例**独家**

MySQL高可用架构(1天)

一二线大厂过万集群规模高可用架构MHA+BLB企业级实战**独家**

Mycat,DBLE企业级实战

MySQL企业级优化与实战(约1天)

打造高性能MySQL

企业级MySQL参数优化实战**独家**

企业级T0级别故障案例解析**独家**

阿里云数据库产品(RDS与PolarDB)(选修二选一) (1天)

企业级RDS介绍,使用与故障案例(百度云RDS 运维DBA分享或交流)**独家**

企业级PolarDB业务场景解析(阿里团队PolarDB P7交付架构师分享或交流)**独家**

第二部分 NoSQL

Redis核心技术(2天)

Redis产品介绍与应用场景简析

Redis安装,部署,使用

Redis数据类型详解与应用

Redis集群架构讲解与实战(哨兵,cluster)

千亿级Redis集群参数优化实战**独家**

千亿级企业级Redis核心案例讲解与业务场景解析**独家**

MongoDB核心技术(2天)

MongoDB产品介绍与应用场景简析

MongoDB安装,部署及架构解析

MongoDB数据类型与运维管理

MongoDB集群架构讲解与实战

企业级MongoDB参数优化实战**独家**

BAT千万元级别故障案例分享**独家**

ES核心技术(2天)

ES产品介绍与应用场景简析

ES安装,部署及架构解析

ES日常运维管理

第三部分 NewSQL(4天)

NewSQL-TiDB(仅学此一个+MySQL至少20K起步) TUG核心成员-PingCAP官方认证讲师 **独家**

TiDB产品介绍与分布式数据库技术应用讲解

TiDB集群部署与日常管理

TiDB集群监控详解与指标应用

TiDB核心架构深入讲解与Raft协议深入浅出**独家*

企业级TiDB-DM理解与应用**独家*

1.      58同城亿级流量Mysql热迁移TiDB**独家**

2.      DM集群多源同步复制场景最佳实践(官方认证,业界唯二)**独家**

TiDB企业级业务开发最佳实践**独家**

TiFllash核心架构讲解与实战**独家**

TiDB打造HTAP实时数仓平台架构设计**独家**

Cloud TiDB(K8S上云实战)**独家**

TiDB4.0热升级5.0集群(简介:我司与Pingcap官方{开发30人,交付专家7人,项目经理4人}封闭测试与在线升级全案例解析6.23日项目完结,官方认证业界目前第一的业务场景与投入)

NewSQL-TDengine(1天 选修)

TDengine产品介绍

TDengine单机版与集群部署与管理

TDengine架构体系详解

TDengine企业级参数优化与实战

TDengine业务开发规范与业务场景实战

第四部分 企业级大规模数据库集群运维开发实战(35W+年薪提升)**独家**

数据运维产品架构设计思路(0.5天)

什么是数据运维平台

企业级数据运维平台架构解析

数据运维平台企业级原型设计实战(0.5天)

数据库运维自动化工具开发(Shell,Python)(2天5选2,下期轮换)

MySQL亿万级流量运维平台开发

Redis亿万级流量运维平台开发

ES亿万级流量运维平台开发

MongoDB亿万级流量运维平台开发

TiDB亿万级流量运维平台开发


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/7286205.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-03
下一篇 2023-04-03

发表评论

登录后才能评论

评论列表(0条)

保存