31丨案例:当磁盘参数导致I/O高的时候,应该怎么办?
下载APP
关闭
渠道合作
推荐作者
31丨案例:当磁盘参数导致I/O高的时候,应该怎么办?
2020-03-02 高楼 来自北京
《性能测试实战30讲》
课程介绍
讲述:高楼
时长16:49大小15.40M
在大部分的性能项目中,当系统调优到一定程度的时候,性能的瓶颈往往会体现在两类计数器上:一个是 CPU,另一个就是磁盘 I/O 了。所以我们也经常会在一些性能优化的文章中看到两个分类,分别是 CPU 密集型和磁盘 I/O 密集型。
有人说为什么不说内存呢?内存是那么重要。不是说内存不会成为瓶颈,只不过内存的瓶颈基本上都可以转嫁给 CPU 和磁盘 I/O。当内存不够的时候,大不了就是清理得快一点。内存能表现出来的,就是满不满,而谁去清理呢?那就是 CPU 了。清理得快就得 CPU 转得快。
我们经常会听到有人说什么性能优化到最后就是“空间转时间、时间转空间的优化”。如此带有禅意的一句话,其实意思就是,CPU 不够用,就扩大内存;内存不够,就让 CPU 计算得更快一些。
举个例子,当我们需要在内存中使用很多变量时,如果内存不够,就会导致 CPU 不断清理内存中没被引用的变量来释放内存,这就导致了释放内存的动作会消耗更多的 CPU。而这时,我们就可以用增加内存的方式,让 CPU 不那么繁忙。
但这个“空间、时间转化”的论点并不会在所有的场景下成立。比如说一个应用并不需要多大内存,就是纯计算型的,那你加内存也没啥用。另外这里提到的“空间”也不是硬盘,因为如果 CPU 不够用,拿再多磁盘补也无济于事。
所以这句话只能是做为高深谒语让初入性能的小白们仰望,实际上适用的场景非常少。
而磁盘 I/O 和内存有很大的区别。只要系统需要保存运行过程中留下的数据,那就必然会用到磁盘 I/O。分析磁盘 I/O 的时候,相对于其他的分析环节还是要复杂一些,因为磁盘 I/O 栈是比较长的。有了 Direct I/O 技术之后,磁盘 I/O 栈短了一段,速度快了,但是同样也没有给性能测试分析人员带来什么福音,因为从分析的角度来说,我们看计数器并没有减少什么。
在性能分析过程中,操作系统是绕不过去的一个环节。在当前的技术栈中,我们仍然要把操作系统当成一个非常重要的环节。
现在对于 I/O 的分析和判断,大部分还停留在磁盘百分比、队列、磁盘延时之类上。可是这样的计数器的值多了,少了,你要干什么呢?怎么解决它呢?是磁盘参数有问题,还是应用有问题?还是磁盘硬件能力就那样了?
这是性能分析人员应该给出的答案, 可是有很多性能测试工程师还真的给不出来这样的答案,甚至有些人连哪个线程导致的 I/O 高都判断不出来。至少现在的状态说明了,性能测试行业还远远不够成熟,我们还有很多的机会。
现在我们所说的 I/O,基本上把 File I/O 和 Disk I/O 都说进去了,所以在分析上,层级更是非常模糊。如下图所示的一个 I/O 栈:
在这个图中,我们可以明确看到磁盘 I/O 栈有多长。从应用层开始,产生系统调用,再通过 visual FS Layer → FS Layer → Block Layer 这样一层一层地调用下去,最后才写到了硬件存储里。
当然还有一层,我们需要关注的就是从系统的全局状态到具体的线程,这个我在操作系统那一篇的 I/O 部分已经描述过。
下面我们来看一个 I/O 高的分析案例。
案例现象
在这个项目的压力测试过程当中,发现了经典的现象:
TPS 上不去;
硬件资源用不上。
应该说,性能分析要是分类比较宽泛,基本上是两种。
第一种是资源用不上,TPS 上不去,响应时间随压力而增加,如下图所示:
第二种是资源用得上,TPS 上不去,响应时间随压力而增加。如下图所示:
这样的划分方式看似有调侃味道,却是很多人疑惑的起点。为什么这么说呢?
我们在开始做性能分析的时候,经常会面对这种情况,那就是资源用不上去。也就是路不够宽,硬件资源才用不上的。我们要解决的,就是把路扩宽一些。
但是,当我们面对一些客户或领导的时候,如果去汇报某资源使用率达到 100% 这样高的值的时候,有可能得到的一个反馈是,能不能把资源使用率降下来,因为资源使用率高会让人有种不安全感,而 TPS 反而不是关注的重点。这就让我们很疑惑:TPS 上去了,资源必然用得多呀,难道让资源使用率稳定保持在 50%,而 TPS 蹭蹭往上涨吗?这不现实呀。
我的建议是,不用怕资源使用率高,做为专业性能分析人员,更应该怕的是资源使用率不高!
在这个例子中,一开始同事跟我描述的时候,说资源怎么也用不上去,TPS 也上不去。这样的描述很常见。
还是看看压力结果,如下所示:
(场景开始时报了少量的错,不过这不是我们这个案例要分析的部分,请看官忽略。)
像这种描述,基本上没办法让人分析,因为信息太少了。特别是有些人直接给一个固定线程数的压力结果,用来描述资源上不去的情况,这就更得不到有用的信息了,所以问性能问题的人一定要注意收集足够的信息,不然只能让人从头查一遍。
分析过程
因为没有什么具体的信息,所以我只能让同事把压力再压起来。
我登录到服务器上之后,顺手执行了一个 top 命令:
这里给个小提醒,执行 top 的时候一定要习惯性地点一下数字 1,这样可以把所有的 CPU 都列出来,因为我要看到每个 CPU 的各个计数器的使用率。别看这个动作不起眼,就算是这一个小小的操作,也是工作经验的积累。
果不其然,看到了一个问题,那就是上图中 CPU0 的 wa 达到了 72%。像这样的问题,如果不看每个 CPU 的每个计数器,是发现不了的。
看到这样的东西,我们要有个基本的判断,对于一般的 Java 应用来说,I/O 线程数基本上不会是 1 个,除非是特别的理由,所以这种情况还是很少的。
不过既然是 I/O 的问题导致了 wa CPU 使用率高,那么我来看一下 CPU 的热点在哪个层面。这是我在工作中经常执行的一个动作,因为我不想在后面的分析过程中偏离方向,而看 CPU 热点可以让我记得这个方向。
如下图所示:
有人说,即然 wa CPU 使用率已经高了,接下去直接看磁盘 I/O 不就行了,看不看 CPU 热点还重要吗?我要说,当然重要!看到前面的磁盘 I/O 栈了吗?那么长,怎么知道是在哪一层呢?
这是定向细化分析过程中的经验之一。
在 CPU 热点中我们看到了,是内核模块中的 blk_queue_bio 消耗的 CPU 大。blk_queue_bio 是用来做 I/O 调度合并的,可以对 I/O 请求进入后向、前向合并操作,互斥方式就是加锁。
根据它我们就可以知道,这是一个有 queue 的调度过程,再接着看它下面的几个函数也可以看出,都是 kernel 级的调用,并没有 user 级的调用,这几个函数基本上也说明了当前系统忙于 journal 写。
接着执行 iotop,看是哪个进程在做这个动作。这里可以看到 jbd2,和上面 CPU 热点的函数也是对应得上的。
那么 jbd2 是个啥玩意呢?jbd2 英文名是这样的:Journaling Block Device 2。
它是跟着 ext4 格式来的,当然它也可以在其他磁盘格式下工作。这个进程的工作原理是这样的:文件系统写入数据,要提交给驱动程序,而 jbd2 就是在文件系统调用驱动之前工作的。文件系统要先调用 jbd2,然后 jbd2 会根据系统的设置(设置有 writeback、ordered、journal),进行数据的备份,然后再让文件系统提交数据。当文件系统将数据写入了块设备之后,jbd2 就会把备份的数据删除。如果文件系统写块设备时出了问题(比如说可悲的断电),那 jbd2 这里还有一个备份,在进行完整性检查时就会把数据补全,所以数据不会丢。
jbd2 就是这样保证数据的完整性的。
但是!对嘛,我就喜欢说但是。jbd2 保证的数据完整性也只是一个原子操作的完整性,即一个原子操作如果操作了 2M 的数据,它就只能保证这 2M 的数据不会丢失。如果你一下子操作了 1T 的数据,jbd2 也不能保证完整性。
jbd2 有一个参数 barrier,它用来开启磁盘屏障。就是设置一个栅栏,要先把 barrier 之前的数据全都写到磁盘设备之后,才会写 barrier 之后的数据,也就是说它是用来保证原子操作中数据的完整性的。当然了,开启 barrier 的一个后果就是性能下降。
了解了这些内容之后,我们就要判断一下了。这个应用有没有必要用这个功能来保证原子操作的完整性?我考虑了一下之后,觉得这个应用就是写日志而已,也没有其他什么重要的东西是要写日志的,重要的业务数据都写到数据库去了。
所以,没必要保证数据写入的完整性,就算丢了一些日志数据又怎么样呢?如果真的就那么寸,应用出现大 bug,恰好块设备也出问题,或者断电,那真的只有烧香拜佛了。
于是我觉得这个功能不用也罢,把原理说明白之后,和架构组、开发组、运维组以及领导层们沟通了一圈,告诉了他们原理,实在是没有打开的必要。
最后大家一致同意:关掉!
我们再回过头来看下这个参数:
上面的这个 barrier=1,就是我们要找的目标。想关了它,就是挂载磁盘的时候使用挂载选项 -o barrier=0 或者 nobarrier。我这里是直接设置为 0 的。
你也可以直接关掉 journal 功能:
问题解决之后
我们再来看下问题解决后的压力工具结果:
从压力结果来看,同样的压力之下,TPS 增加了一倍,响应时间快了一倍。
top 如下所示:
集中的 wa CPU 也消失不见了,现在使用的也挺均衡的了。
iotop:
在 I/O top 的结果中,也看不到 I/O 非常高的 jbd2 了。
问题得到了完美地解决。
总结
不管是什么样的性能问题,其实从分析思路上仍然逃不开我一直提到的思路——那就是一个分析的完整链路。当你一层一层往下找问题时,只要抓住了重点,思路不断,找到根本原因就可以解决问题。
在这个 I/O 的问题中,难点在于怎么能知道 jbd2 的原理和参数。应该说,不管是谁,都不能保证自己的知识体系是完整的,那怎么办呢?查资料,各种学习,看源码,看逻辑。实在看不懂,那也没办法,接着修炼基础内功呗。
所以说性能测试行业中,经常只测不分析,也是因为做性能分析需要的背景知识量有点大,还要不断分析各种新的知识点。不过也就是因为如此,性能测试和性能分析才真的有价值。只测不调只是做了一半工作,价值完全体现不出来。
思考题
最后问你两个问题吧:为什么 TPS 上不去时,资源用不上才是更让人着急的问题?以及为什么要在 CPU 高时查看 CPU 热点函数呢?
欢迎你在评论区写下你的思考,我会和你一起交流。也欢迎你把这篇文章分享给你的朋友或者同事,一起交流一下。
分享给需要的人,Ta购买本课程,你将得18元
生成海报并分享
赞 3
提建议
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
上一篇
30丨案例:为什么参数化数据会导致TPS突然下降?
下一篇
32丨当Postgres磁盘读引起I/O高的时候,应该怎么办?
精选留言(12)
- 夏商周2020-05-14这个jdb2,占用80%的io使用率,却没有输入输出。是不是有点奇怪啊。 我遇到的io问题。找到热点cpu,iotop找到线程。strace,查看系统调用,lsof看线程打开的文件。
作者回复: 你可以看下jdb2的工作原理,它工作在bi、bo之上。
6 - Geek_65c0a22020-03-02这段时间每天都呆在家里,越发感觉生活无比的枯燥、人生多么的无趣。是什么让我感觉人生还有所期待的?是什么在支撑我一天天的就这么的过日子?是每周的一三五就有高老师的文章看。
作者回复: 这才是真爱!😀😀😀
共 2 条评论6 - Geek_6a9aeb2021-01-17老师,第一这里不明白热点函数是用什么命令去看,能完整的说下? 第二,top命令是看到某一个cpu wa使用率高,但是我经常听到开发反馈跟我说不要一个cpu,要多看多个核平均下来的使用率。开发说平均下来压力不大啊,因为不清楚究竟多核是怎么分配工作的,因此无法说服开发
作者回复: 1. perf命令。通常我是执行perf top -g。 2. 如果你有这样的场景,可以拿我来给你分析。对于wa来说,cpu均衡是肯定的。平均下来压力大不大,也不是开发说了说,而是系统说了算。
4 - NightClown2020-03-03问题一:为什么 TPS 上不去时,资源用不上才是更让人着急的问题? 资源以及TPS上不去,说明压力的流量没有完整的打到服务器上,资源没有能够有效的利用,可能存在很多种原因导致的这个问题,也不知道我们系统到底能支持什么量级。举个例子就像我们有一个电视,但是一年下来只看了几个小时,那么这个电视是没有什么用的,白花了钱。 问题二:为什么要在 CPU 高时查看 CPU 热点函数呢? 因为通过CPU热点函数可以看到系统哪个模块的CPU利用率高,也就是全局-定向的分析思路,逐步分析,找到问题并且解决问题展开
作者回复: 得到真传。可以出师了。😀😀
共 2 条评论3 - Geek61982021-11-30案例的分析过程 1. 看top ,注意点:看每个cpu的数值,而非仅总计值:发现CPU总值低,但有一项异常的高 2. 用perf 看CPU 热点 3. 根据上一块,可以知道cpu是在忙碌 哪个内核模块,再检查 该内核模块主要负责什么; 4. 再用iotop;找到忙碌的进程,同时可以看到该进程的执行内容 5. 综合 上述三项“cpu什么数字高”,“内核忙碌模块是什么”,“进程的忙碌内容是什么”;可以推断瓶颈的所在展开
作者回复: 逻辑描述得很清晰呀,就差上手实践了。
2 - Geek_454a8f2021-05-19CPU热点怎么查
作者回复: perf
共 2 条评论2 - Geek_6a9aeb2021-01-18也有一种 压力线程 增大,但是资源也上不去,tps也上不去 ,tps就稳定在那?
作者回复: 那响应时间一定会增长。
1 - 月亮和六便士2020-03-02看到你时不时的就会祭出perf ,但是perf出来的结果看不懂,怎么办?
作者回复: 哪里看不懂?可以找man手册。还有perf官方说明。 或者......问我。哈哈。
共 2 条评论1 - Geek_611de62022-11-15 来自广东linux不熟悉,看着挺吃力,我去学习一下linux
作者回复: 所有的技术在性能分析时遇到时都要学习。
- Geek_若水2021-12-21老师好,我有一个小小的疑问:看一下 CPU 的热点在哪个层面。 这个具体是怎么操作的呀
作者回复: 就是统计syscall,有很多工具可以做到,我常用的就是perf。
- Geek61982021-11-29“接着执行 iotop,看是哪个进程在做这个动作。这里可以看到 jbd2,和上面 CPU 热点的函数也是对应得上的。”这个“对的上”是指什么?哪个参数跟哪个参数对上了?
作者回复: 这里对应得上是指iotop中看到的IO%高和热点函数中的blk_queue_bio可以对得上。 进程的名字jbd2和热点函数jbd2_journal_commit_transaction也能对得上。
- rainbowzhouj2020-04-05高老师,您好,以下是我的思考: 第一个问题:为什么 TPS 上不去时,资源用不上才是更让人着急的问题? 该问题我从正面角度思考假设TPS上去了,资源使用也上去了,此时资源情况与TPS正相关,符合常理。但若TPS上不去时,肯定是有多方面原因导致,通常资源的使用是一个定位问题的好方向。根据文章中所述,要进行一次完整的链路分析,要有充足的知识储备量。若此时资源也用不上,那么肯定会导致排查难度极度增大,不宜分析与定位问题。 第二个问题:为什么要在 CPU 高时查看 CPU 热点函数呢? 在CPU高时,查看CPU热点函数,能使我们深究原因时的整体方向不会偏离。在宏观方向不出错的前提下,找到根本原因及提出相应的解决方案才能真正的解决CPU高的问题。展开
作者回复: 非常正确。
共 2 条评论