mysql数据库IO高问题排查
最近压测了一个项目发现数据库IO很高;
相关命令:iostat ,iotop, top, ps -ef ,perf
执行压测时使用iostat -x 1命令监控发现util%占用很高
针对iostat命令中的util%, 可以利用gnuplot生成一系列的图
先安装gnuplot :https://www.jianshu.com/p/8087e2fd7835(具体下载地址百度去官网吧,我没找到上传文件的入口)
然后,安装字体,
其中有iostat的shell脚本,有具体的使用方法
生成的图像:
下面讲一下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瓶颈
上面对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