项目经验_之_数据库指标如何监控
前言
Github:https://github.com/HealerJean
1、问题出现和解决
1.1、问题1:应用连接被打满
### Error updating database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is com.alibaba.druid.pool.GetConnectionTimeoutException: wait millis 5000, active 10, maxActive 10, creating 0
1.1.1、问题出现
在一次JD预发环境验证保险保单的时候,只有一台服务,数据库连接配置为:maxWait: 5000
,maxActive: 10
,initialSize: 5
。很高流量的运费险到达之后,就出现了上面的报错信息。报错信息说明,已经把数据库连接池打满了,并且等待了 5s
还是不能获取连接,所以报错了。
1.1.2、问题解决
查询总连接数,增大连接,后来设置成100了解决了
2、监控指标分析
2.1、磁盘性能指标
IOPS
和 数据吞吐量适用于不同的场合:追求
IOPS
:读取 10000个 1KB 文件,用时10秒Throught
(吞吐量)=1MB/s ,IOPS=1000追求吞吐量:读取1个10MB文件,用时0.2秒
Throught
(吞吐量)=50MB/s, IOPS=5
2.1.1、IO Thruput(KB)
:IO
读写吞吐量
read:
磁盘读吞吐量
write
: 磁盘写吞吐量
2.1.2、IOPS
:磁盘的读/写操作次数
read
: 每秒磁盘的读操作次数
write
: 每秒磁盘的写操作次数
2.2、机器性能指标
2.2.1、cpu usage
和 cpu load
⬤
cpu usage
即cpu
利用率,就是程序对CPU
时间片的占用情况⬤
load averag
e 表示的是CPU
的负载,包含的信息不是CPU
的使用率状况,而是在一段时间内CPU
正在处理以及等待CPU
处理的进程数之和的统计信息,也就是是一段时间内正在使用和等待使用CPU的平均任务数。这个数字越小越好,CPU
利用率高,并不意味着负载就一定大。如果
load average
值长期大于系统CPU
的个数则说明CPU
很繁忙,负载很高,可能会影响系统性能,导致系统卡顿响应时间长等等。举例来说:如果我有一个程序它需要一直使用
cpu
的运算功能,那么此时cpu
的使用率可能达到100%
,但是cpu
的工作负载则是趋近于 “1”,因为cpu
仅负责一个工作嘛!如果同时执行这样的程序两个呢?cpu
的使用率还是100%
,但是工作负载则变成2
了。所以也就是说,当cpu
的工作负载越大,代表cpu
必须要在不同的工作之间进行频繁的工作切换。
2.2.1.1、正常值
CPU
利用率参考值:15.30
,最小值10.5
,最大21.75
一般能够被接受的值是
load average
<=CPU核数
*0.7
。
2.1.2、Network Flow(kb)
:网卡出/入口流量
recv
:网卡入口流量
send
:网卡出口流量
2.1.2.1、正常值
2.1.3、IOUTIL
:机器的 IO
使用率
2.3、MYSQL
SQL
相关
2.3.1、SQL
:语句操作数量
ins
:insert
语句操作的数量
upd
:update
语句操作的数量
del
:delete
语句操作的数量
2.3.2、ROWS
:语句影响行
ins
:insert
语句操作的数量
upd
:update
语句操作的数量
del
:delete
语句操作的数量
read
:读取的行数
2.1.3、QPS/TPS
2.4、Innodb
2.4.1、Innodb Buffer Poll Hit Ratio
2.4.2、Thread Connect
:当前已连接线程数
2.4.3、Thread Running
:当前活跃连接数
2.4.4、Thead Other Status
:线程其他状态
thead_create
:新创建线程数
thread_cache
:thread_cache
中已缓存的线程数
2.4.5、Innodb Buffer Poll Status(MB)
pages_data
:Innodb
缓存池数据页占用量
pages_free
:Innodb
缓存池空闲页占用量
pages_dirty
:Innodb
缓存池脏页占用量
2.4.6、Inodb Pages Flush
pages_flush: Innodb
缓存池每秒flush
操作请求数
2.4.7、Innodb IOPS
data_reads: Innodb
数据每秒物理读请求数
data_writes: Innodb
数据每秒物理写请求数
2.4.8、Innodb IO Thruput
data_read: Innodb
数据每秒物理读取量
data_written: Innodb
数据每秒物理写入量
2.4.9、Innodb Main Thread
read_view
: 当前打开read view
个数
query_queue
: 当前Innodb
等待队列中的线程数
query_inside
: 当前Innodb
内核线程数
2.4.10、Undo History List Length
his_list
: 当前undo
表空间中还未purge
的事务个数
2.4.11、Innodb ReDo Log(byte)
log_unflush: Innodb当前还未flush的redo日志大小
log_unchkpt: Innodb当前还未checkpoint的redo日志大小
3、数据源信息
3.1、连接相关
3.1.1、max_connections
**
max_connections
**MYSQL
服务端允许的最大连接会话数量; (maxAcvie
以它为主)默认值是
15
,MySQL
允许的最大连接数上限是16384
mysql> show variables like 'max_connections';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| max_connections | 3100 |
+-----------------+-------+
3.1.2、Thread
Threads_connected
: 这个数值指的是打开的连接数,跟show processlist
结果相同,表示当前连接数。
Threads_running
:是代表当前并发数,这个数值指的是激活的连接数,这个数值一般远低于connected
数值。
mysql> show status like 'Threads%';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| Threads_cached | 429 |
| Threads_connected | 102 |
| Threads_created | 1915 |
| Threads_running | 3 |
+-------------------+-------+
3.1.3、Max_used_connections
max_user_connections这
:MySQL
服务器过去的最大连接数是245,没有达到最大连接数的上限理想:
max_used_connections
/max_connections
*100%
≈85%
mysql>show global status like 'Max_used_connections';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| Max_used_connections | 762 |
+-------------------+-------+
3.1.3.1、查看上次 MYSQL
启动后的最大连接数
mysql> show global status like 'Max_used_connections';
+-----------------------------------+---------------------+
| Variable_name | Value |
+-----------------------------------+---------------------+
| Max_used_connections | 762 |
| Max_used_connections_time | 2021-04-29 17:36:51 |
3.1.4、innodb_thread_concurrency
支持的最大并发执行的线程数:这个是
innodb
内核的并发线程处理参数,即同一时刻能够进入innodb
层次并发执行的线程数(「注意是并发不是并行」)。比如前端有100
个连接,发来1000
个sql
,如果这个参数被设置成2
。那么这1000
个sql
中,最多只有2
个sql
在innodb
内核运行。其它都得等。(事实上,处理过程很复杂,可以先这么理解,不是所有sql
都需要放在Innodb
内核处理的)。
3.1.4、取值
3.1.4.1、默认 0
默认
0
,则表示没有并发线程数限制,所有请求都会直接请求线程执行。注意:当innodb_thread_concurrency
设置为0
时,则innodb_thread_sleep_delay
的设置将会被忽略,不起作用。如果数据库没出现性能问题时,使用默认值即可。
3.1.4.2、大于 0
当 >
0
,则表示有并发数限制1、 当一个新的请求发起时,会检查当前并发线程数是否达到了
innodb_thread_concurrency
的限制值,如果有,则需要sleep
一段时间,然后再再次请求2、如果再次请求时,当前并发数还是达到限制值,那么就会进入
FIFO
队列等待执行。3、当进入到内核执行时,会得到一个消费凭证 ` ticket
,则这个线程,在后面的多次进入
innodb执行操作是都不需要重复上面的检查步骤,当把次数消费完,那么这个线程就会被驱逐,等待下次再次进入
Innodb,再重新分配
ticket`。4、那些等待获取锁的线程则不会被计入到并发执行线程
innodb_thread_concurrency
的数量中。
3.1.5、建议配置
⬤ 当并发用户线程数量小于
64
,建议设置innodb_thread_concurrency
=0
;⬤ 如果负载不稳定,时而低,时而高到峰值,建议先设置
innodb_thread_concurrency
=128
,并通过不断的降低这个参数,96
,80
,64
等等,直到发现能够提供最佳性能的线程数,例如,假设系统通常有40
到50
个用户,但定期的数量增加至60
,70
,甚至200
。你会发现,性能在80
个并发用户设置时表现稳定,如果高于这个数,性能反而下降。在这种情况下,建议设置innodb_thread_concurrency
参数为80,以避免影响性能;
注意:
⬤ 如果
DB
服务器上还允许其他应用,需要限制mysql
的线程使用情况,则可以设置可分配给DB
的线程数,但是不建议DB
上跑其他应用,也不建议这么设置,因为这样可能导致数据库没有对硬件最优使用;⬤ 设置过高值,可能会因为系统资源内部争夺导致性能下降「在大多数情况下,最佳的值是小于并接近虚拟CPU的个数;」
⬤ 定期监控和分析
DB
,因为随着数据库负载的变化,业务的增加,innodb_thread_concurrency
也需要动态的调整