日期:2014-05-16  浏览次数:20421 次

概谈“应用反应某些操作或查询慢”的处理方法(从MySQL DBA角度)

        作为一个运维人员或多或少都会从应用开发那边得到类似“为什么用户反应很多操作慢?或者为什么我这里统计的日志里面出现了较多的查询较慢?”。那么遇到此问题我们该怎么来解决呢?我今天就利用自己的工作经验从MySQL DBA的角度来简单分析一下这个问题。

        首先我们得区分这种查询慢或者操作慢发生的频率怎么样。按理来说这种状况不会经常发生,一个产品上线前都有专门的QA团队对其进行功能测试/压力测试等等,所以绝大部分的时候是偶尔出现或者有规律的出现(比如是某一类操作相应时间特长),因为测试路径是不可能被全部覆盖的,总会存在遗漏的地方。那么当这种小概率事件发生以后我们该怎么做呢?在说具体的方法之前我们得大概知道一点,发生响应慢这种状况绝大部分情况都是由于整个系统(不光止OS)肯定某些地方存在瓶颈需要我们去消除,比如从MySQL DBA的角度来看我就会去关注网络/IO/内存/CPU/数据库内部状态(比如锁争用,锁等待,buffer 太小等等)。下面我就具体介绍一下我自己平常怎么去查看这些方面的状态。

        网络,这是一个很泛,内容也很多的东西。在我的工作中我主要关注两方面的内容网络延迟和网卡流量。网络延迟最简单也绝大部分时候能解决问题的工具是ping,比如从app server上ping一下db server看一下两者之间大概网络延迟有没有丢包等等信息。那么你可能有疑问(也包括我)多少的延迟才算合理的,也就是延迟有没有一个基本的比较通用的参考数据呢?我从网友 @yzsind-叶正盛 的微博上有看到(不知参考性怎样,有待确认):

“内部网络我经常用的快速估算公式是:同交换机≈0.1ms,同机房≈0.2ms,同城机房≈0.5~1ms,远距离≈(两地线路距离/100) ms”

那么网卡流量该怎么查看呢?首先得知道自己是千兆网卡或者万兆网卡,查看方式:

repls@repls-tp:~$ lspci | grep Ethernet
00:19.0 Ethernet controller: Intel Corporation 82579LM GigabitNetwork Connection (rev 04)

红色部分显示了当前网卡是千兆网卡,但是我们还得注意一点,平常说千兆网卡那么它到底可以跑满多少流量呢?你可千万注意千兆网卡跑完流量只有1024M/8左右的流量,因为我们平时说的千兆不是以byte计算而是bit,所以还要除8。我们可以通过sar(号称linux系统管理监控里面的瑞士军队)来观察网卡流量:

repls@repls-tp:~$ sar -n DEV 2
Linux 3.5.0-17-generic (repls-tp) 2013年01月14日_x86_64_ (4 CPU)


14时36分04秒     IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s
14时36分06秒      eth0      0.00      0.00      0.00      0.00      0.00      0.00      0.00
14时36分06秒        lo      1.00      1.00      0.15      0.15      0.00      0.00      0.00
14时36分06秒     wlan0      3.50      4.00      0.55      1.04      0.00      0.00      0.00

对于sar的用法远远不止这么简单,你还可以查看道丢包之类更丰富的信息,详情可以man sar或者google查看。


        IO,存储对于数据库来说是很重要的一点,很多时候瓶颈都会是IO能力不足导致。那么有什么方法大概可以判断出是由于系统IO能力不足呢?(术语应该称为IO-bound吧)最简单也是最常用的工具就是iostat,我一般会加-x选项(表示显示更多详情):

repls@repls-tp:~$ iostat -x 2
Linux 3.5.0-17-generic (repls-tp) 2013年01月14日_x86_64_ (4 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          12.42    0.00    4.36    0.53    0.00   82.69
Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda               0.15     1.14    0.78    2.04    18.62    30.05    34.48     0.11   37.73   20.70   44.28   5.01   1.41

这里主要解释Device这行中几个平常关注得多的列。

r/s,w/s:每秒写,每秒读的次数加起来也就是常说的iops。

rrqm/s,wrqm/s:每秒merge读,merge写的次数,这个主要是IO调度器来完成的事。

await:响应时间,这个主要是指的硬件层面一个IO的响应时间,这个值一般多少合理?看应用需求吧,我也没多少经验有人说20ms以内,有人说10ms以内。

r_await,w_await:这个是哪个sysstat新增的?貌似之前用公司机器没有这两列,看意思应该就是读延迟,写延迟吧。

svctm:IO请求的服务时间,这个值肯定会比await小。

<