该文基于《性能之巅:洞悉系统、企业与云计算》的1.9.1 缓慢的磁盘章节调整而来
Scott 是一家中型公司里的系统管理员。数据库团队报告了一个支持ticket(工单),抱怨他们有一台数据库服务器“磁盘缓慢”。
Scott 首要的任务是多了解问题的情况,收集信息形成完整的问题陈述。ticket 中抱怨磁盘慢,但是并没解释这是否是由数据库引发的。Scott 的回复问了以下这些问题:
当前是否存在数据库性能问题?如何度量它?(圈定问题表征及指标)
问题出现至今多长时间了?(圈定时间范围)
最近数据库有任何变动吗?(圈定影响因素,如数据库版本变动)
为什么怀疑是磁盘?(获取用户得出结论的例证)
数据库团队回复:“我们的日志显示有查询的延时超过了1000ms,这并不常见,就在过去的一周这类查询的数目达到了每小时几十个。AcmeMon 显示磁盘在那段时间很繁忙。”
可以肯定确实存在数据库的问题,但是也可以看出关于磁盘的问题更多的是一种猜测。Scott需要检查磁盘,同时他也要快速地检查一下其他资源,以免这个猜测是错误的。
AcmeMon 是公司服务器的基础监控系统,基于mpstat(1)、iostat(1)等其他的系统工具,提供性能的历史图表。Scott 登录到AcmeMon 上自己查看问题。
一开始,Scott 使用了一种叫做USE(utilization(资源利用率)、saturation(资源饱和度)、errors(发生错误的次数)) 的方法来快速检查系统瓶颈。正如数据库团队所报告的一样,磁盘的使用率很高,在80%左右,同时其他资源(CPU、网络)的使用率却低得多。历史数据显示磁盘的使用率在过去的一周内稳步上升,而CPU的使用率则持平。AcmeMon 不提供磁盘饱和(或错误)的统计数据,所以为了使用USE 方法,Scott 必须登录到服务器上并运行几条命令。[确定分析问题的方法USE]
他在**/proc 目录里检查磁盘错误数**,显示是零。他以一秒钟作为间隔运行iostat,对使用率和饱和率观察了一段时间。AcmeMon 报告80%的使用率是以一分钟作为间隔的。在一秒钟的粒度下,Scott 看到磁盘使用率在波动,并且常常达到100%,造成了饱和,加大了磁盘I/O 的延时。
为了进一步确定这是阻塞数据库的原因——延时相对于数据库的查询不是异步的——他利用动态跟踪脚本来捕捉时间戳和每次数据库被内核取消调度时数据库的栈跟踪。他发现数据库在查询过程中常常被一个文件系统读操作阻塞,一阻塞就是好几毫秒。对于Scott 来说,这些证据已经足够了。
接下来的问题是为什么。磁盘性能统计显示负载持续很高。Scott 对负载进行了特征归纳以便做更多了解,使用iostat(1)来测量IOPS、吞吐量、平均磁盘I/O 延时和读写比。从这些结果,他计算出了平均I/O 的大小并对访问模式做了估计:随机或者连续。Scott 可以通过I/O级别的跟踪来获得更多的信息,然而,他觉得这些已经足够表明这个问题是一个磁盘高负载的情况,而非磁盘本身的问题。
Scott 在ticket 中添加了更多的信息,陈述了自己检查的内容并上传了检查磁盘所用到的命令截屏。他目前总结的结果是由于磁盘处于高负载状态,从而使得I/O 延时增加,进而延缓了查询。但是,这些磁盘看起来对于这些负载工作得很正常。因此他问道,难道有一个更简单的解释:数据库的负载增加了?(数据库负载增加了,导致磁盘负载增加)
数据库团队的回答是没有,并且数据库查询率(AcmeMon 并没有显示这个)始终是持平的。这看起来和最初的发现是一致的,CPU 的使用率也是持平的(相互交叉验证)。
Scott 思考着还会有什么因素会导致磁盘的高I/O 负载而又不引起CPU 可见的使用率提升,他和同事简单讨论了一下这个问题。一个同事推测可能是文件系统碎片,碎片预计会在文件系统空间使用接近100%时出现。Scott 查了一下发现,磁盘空间使用率仅仅为30%。
Scott 知道他可以进行更为深入的分析来了解磁盘I/O 问题的根源,但这样做太耗时。基于自己对内核I/O 栈的了解,他试图想出其他简单的分析,以此来做快速的检查。他想到这次的磁盘I/O 是由文件系统缓存(页缓存)未命中导致的。【提出新的猜测】
Scott 进而检查了文件系统缓存的命中率(cachestat、cachetop),发现当前是91%。这看起来还是很高的(很好),但是他没有历史数据可与之比较。他登录到其他有相似工作负载的数据库服务器上,发现它们的缓存命中率超过了97%。他同时发现问题服务器上的文件系统缓存大小要比其他服务器大得多。
于是他把注意力转移到了文件系统缓存大小和服务器内存使用情况上,发现了一些之前忽视的事情:一个开发项目的原型应用程序不断地消耗内存,虽然它并不处于生产负载之下。这些被占用的内存原本可以用作文件系统缓存,这使得缓存命中率降低,让磁盘I/O 负载升高,损害了生产数据库服务器的性能。
Scott 联系了应用程序开发团队,让他们关闭该应用程序,并将其放到另一台服务器上,作为数据库问题的参照。随后在AcmeMon 上Scott 看到了磁盘使用率的缓慢下降,同时文件系统缓存恢复到了它原先的水平。被拖慢的数据库查询数目变成了零,他关闭了ticket 并将它置为“已解决”。
导致数据库查询变慢的真凶是“与数据库同机部署的应用程序,该应用程序不停的消耗内存,使得文件缓存命中率降低,让I/O负载升高”。解决策略是“数据库服务独占一台机器,移除应用程序,减少资源竞争”。
寻找正凶的过程采用了“提出新的猜测-》确定判定指标–》收集指标数据–》分析指标数据–》验证猜测”的心动的研究方法。整体流程如下:
1、用户反馈的问题(有一台数据库服务器“磁盘缓慢”)
2、获取完成问题陈述(问题表征评判指标、问题开始时间、用户为什么猜测证据、确定问题表征近期变动)
3、验证用户猜测(收集信息链–》确定问题研究方法USE–》确定判定指标–》收集指标数据–》分析指标数据–》验证猜测–》提出新的猜测-》确定判定指标–》收集指标数据–》分析指标数据–》验证猜测)