mysql数据库IO高问题排查

最近压测了一个项目发现数据库IO很高;

相关命令:iostat  ,iotop, top, ps -ef ,perf

执行压测时使用iostat -x 1命令监控发现util%占用很高

mysql数据库IO高问题排查

针对iostat命令中的util%, 可以利用gnuplot生成一系列的图

先安装gnuplot :https://www.jianshu.com/p/8087e2fd7835(具体下载地址百度去官网吧,我没找到上传文件的入口)

mysql数据库IO高问题排查

然后,安装字体,

mysql数据库IO高问题排查

mysql数据库IO高问题排查

其中有iostat的shell脚本,有具体的使用方法

mysql数据库IO高问题排查

生成的图像:

mysql数据库IO高问题排查

下面讲一下perf的用法(就是一个监控插件,类似vmstat那种的)

先安装一下这个perf yum instsall -y perf

采集命令 perf record -a -g -v sleep 30

生成火焰图 # git clone https://github.com/brendangregg/FlameGraph

# mv perf.data FlameGraph/

# cd FlameGraph

# perf script | ./stackcollapse-perf.pl > out.perf-folded

# cat out.perf-folded | ./flamegraph.pl > perf-kernel.svg

perf可以生成火焰图,会更直观一些。

iotop也可以更直观的看到是哪些进程造成了io瓶颈

mysql数据库IO高问题排查

上面对IO高的一些排查告一段落,我们简单说一下数据库这块的优化

有人说了,数据库优化无非就是分库分表,读写分离,静态动态,索引什么的,没错,是这样,可针对一些数据库还要定点分析,比如说用什么版本啊最合适,对吧!不废话,简单阐述下

-一、提到IO,就肯定先要了解下IO出现的问题的各种可能,一些常见话术:

1,阻塞I/O
解释:
相当于到一个饭店点菜,服务员拿着菜单到厨房交给厨师,然后就在出菜口等着,直到厨师做完后交给服务员;其中服务员在出菜口等待的过程就叫阻塞IO;
运行原理:
应用程序调用一个IO函数,导致应用程序阻塞,(例如浏览器请求时上面一直转圈)等待数据准备好,如果数据没有准备好,就一直等待,直至准备好,从内核拷贝到用户空间,IO函数返回成功指示
2,非阻塞I/O
解释:
相当于服务员把菜单交给厨师后就去干别的了,一定时间内就去查看是否准备好了,如果准备好了就调用系统copy资源信息到自己的缓冲区内
运行原理:
我们先把套接字设置为非阻塞告诉内核,当所有请求的IO操作无法完成时,不要将程序睡眠,而是返回一个错误,这样我们的IO操作函数将不断的测试数据是否准备好,如果没有准备好,继续测试,直至准备好位置,在这个不断测试的过程中,会大量暂用CPU的时间。一般web服务器都不适用这种IO模型
3,复用I/O
解释:
相当于多个服务员把菜单交给多个厨师后,开始等待,等待的对象是一个机器,当厨师做完后,按下机器,机器告诉服务员,好了,可以上菜了,跟阻塞IO的区别是中间多了一个机器,这个机器可以同时让多个服务员等待
运行原理:
IO复用模型会用到select、poll跟epoll函数,这两个函数也会使进程阻塞,不同的是这几个函数可以同时阻塞多个IO操作。而且同时第多个读操作,多个写操作进行检测。直到有数据可读或可写的时候才真正调用IO操作函数
4,信号I/O
解释:
相当于服务员把菜单交给厨师后,就去干别的了,厨师这边做好后叫服务员传菜
运行原理:
我们允许套接口进行信号渠道IO,并安装一个信号处理函数,进程继续运行,并不阻塞,当数据准备好了,会响应给进程一个SIGIO信息,可以在信号处理函数中调用IO操作函数处理数据
5,异步I/O
解释:
相当于服务员把菜单交给厨师后,告诉厨师,你做好了交给XXX服务员就行,就去干别的了,厨师做好后就交给XXX服务员
运行原理:
当一个异步过程调用发出后,调用者不用立即得到结果,时间处理这个调用的部分在完成后,通过状态,通知和回调来通知调用者的输入输出操作
(例如:ajax的异步,总是有一个函数接收成功或失败的数据,其他参数发送后就不管了)
其中同步IO为:
阻塞IO,非阻塞IO,复用IO
   异步IO为:
信号IO(半异步),异步IO

IO的类型有哪些

IO有四种类型:连续读,随机读,随机写和连续写,连续读写的IO size通常比较大(128KB-1MB),主要衡量吞吐量,而随机读写的IO size比较小(小于8KB),主要衡量IOPS和响应时间。数据库中的全表扫描是连续读IO,索引访问则是典型的随机读IO,日志文件是连续写IO,而数据文件则是随机写IO。

这里对于数据库的优化我们选用SSD RAID10来做分库分表,为什么呢,简单阐述下;

SSD的IO特点分析

  • 随机读能力非常好,连续读性能一般,但比普通SAS磁盘好。
  • 不存在磁盘寻道的延迟时间,随机写和连续写的响应延迟差异不大。
  • erase-before-write特性,造成写入放大,影响写入的性能。
  • 写磨损特性,采用wear leveling算法延长寿命,但同时会影响读的性能。
  • 读和写的IO响应延迟不对等(读要大大好于写),而普通磁盘读和写的IO响应延迟差异很小。
  • 连续写比随机写性能好,比如1M顺序写比128个8K的随即写要好很多,因为随即写会带来大量的擦除。

那么如果用SSD也出现问题怎么做处理呢

基于SSD的数据库优化法则:

  基于SSD的优化就是解决erase-before-write产生的写入放大的问题,不同类型的IO分离,减少写操作带来的性能影响。

  • 将sequential logging修改为In-page logging,避免对相同位置的反复擦写。
  • 通过缓存写入的方式将大量的in-place update随机写入合并为少量顺序写入。
  • 利用SSD随机读写能力高的特点,减少写增加读,从而达到整体性能的提升。

RAID级别划分:

RAID-0 等级 
Striped Disk Array without Fault Tolerance( 没有容错设计的条带磁盘阵列)

RAID-1 等级 
Mirroring and Duplexing (相互镜像)

RAID-5 等级 
Independent Data disks with distributed parity blocks (独立的数据磁盘与分布式校验块)

RAID-10 等级 
Very High Reliability combined with High Performance (高可靠性与高性能的组合)

我们选择RAID10,原因是它可以做到高可用,安全性高,空间利用率较于其他级别会低很多,而且它的离散写也优与其他级别。

 

以上所言有自诉有摘自其他博主的,感谢三位博主分享

https://blog.****.net/kevinsqlserver/article/details/7757730

https://blog.****.net/jiajiren11/article/details/80113311

https://blog.****.net/huaminghui/article/details/78065810