io.util周期性抖动的问题排查

线上有服务器每隔差不多15分钟io.util就会飙升一下,使用率>40%,RD反馈影响线上服务一直没找到原因。服务器操作系统为centos6.7版本,配置挺高,用iotop抓出飙升时执行的程序是jbd2。它是负责写脏页,机器上log-agent刷日志脏页比较多的话jbd2会来处理,影响应该不大,查看机器已经启动快4年没重启了,重启了一下机器,释放下脏页问题解决,彻底解决要更改磁盘的写入方式。

# 打出io.util使用大于10%的程序
iotop -b | awk -F'%' '{if($(NF-1) > 10 && $(NF-1) ~ /[0-9]/ && $0 !~ /DISK/)printf "TIME: %s,PID:%s,IO:%s%,COMMAND:%s\n",strftime("%F %T"),$1,$(NF-1),$NF}'

/dev/sda3 on / type ext4 (rw,relatime,data=ordered)
/dev/sda2 on /boot type ext4 (rw,relatime,data=ordered)

The Journaling Block Device (JBD) provides a filesystem-independent interface for filesystem journaling. ext3, ext4 and OCFS2 are known to use JBD. OCFS2 starting from Linux 2.6.28 and ext4 use a fork of JBD called JBD2.[JBD-wikipedia]

jbd全称是journaling block driver,设计逻辑就是为了损失掉性能保证文件完整性。Jbd2是系统上配置的是order模式,每个事物提交前,jbd2也负责刷脏数据,系统内脏页,要么bdi来回写,要么jbd来刷,如果正好赶上jdb来干,就是这样了。Jdb是一个文件系统一个线程,bdi提交可以多线程。所以jbd来弄会有点问题,比较慢点。

◎https://blog.csdn.net/luckyapple1028/article/details/61413724

这个进程实现的是文件系统的日志功能,磁盘使用日志功能来保证数据的完整性。这个需要评估一下安全和性能哪个更重要,对于一个应用服务器来说,并不保存重要的用户数据,只是实现业务逻辑。如果是数据库的话,就需要考虑启动磁盘写入的完整性检查。但是现在大部分系统在业务和架构层面已经考虑了业务完整性。所以为性能计,这里并不是非常有必须启动日志功能。

另外,说到这里不得不说一下挂载磁盘时的barries参数默认这个值是1,启动状态。这个参数从语义上来解释就是一个栅栏,一个分界线。当启动时,在这个分界线之前要全部写数据到存储介质上,从而保证了数据的完整性。

内核版本 3.0 和 3.4.35 (不同内核版本的回写机制不同哦~)

Linux内核里负责回写脏页的线程称为flusher线程,它们以“flush-”+“设备名”来命名,例如”[flush-8:64]”(这里设备名是指用设备号拼接的字符串)。

在BDI(即backing device info)模块初始化(default_bdi_init())时会创建”[sync_supers]”和”[bdi_default]”两个线程。其中,“[sync_supers]”线程用来周期性(间隔同flusher线程)地同步系统中所有的superblocks(遍历全局super_blocks链表)。“[bdi_default]”线程则用来在必要时创建、启动和停止flusher线程。

系统中每新增一个bdi设备(例如硬盘)就会通过bdi_register()注册到全局的bdi_list链表中,每个bdi设备都会有自己的flusher线程,在某个设备需要回写脏页时,bdi_default线程就会为其创建”[flush-devname]”线程(bdi_forker_thread())并运行,如”[flush-8:64]”。flusher线程的处理函数为bdi_writeback_thread(),负责周期性地回写脏页,实际回写操作由wb_do_writeback()函数完成(其第二个参数为1会等IO完成才返回,为0则立即返回)。

# 检查是否存在jbd2进程

dumpe2fs /dev/sda3 | grep has_journal

◎https://www.testwo.com/article/1359

# 那如何关闭JBD2呢?

首先用 dumpe2fs /dev/sda3 | more 查看Filesystem Feature下有木有has_journal。如果没有就不用看了 -_-

tune2fs -o journal_data_writeback /dev/sda3
tune2fs -O "^has_journal" /dev/sda3
e2fsck -f /dev/sda3

同时在fstab下重新设定一下,在defaults之后增加

defaults,data=writeback,noatime,nodiratime

重启之后,在使用dumpe2fs查看,若没有了,那说明已经把jbd关闭了。

如果使用tune2fs时候,提示disk正在mount,如果是非系统盘下,你可以使用

fuser -km /home #杀死所有使用/home下的进程

umount /dev/sda6 #umount

之后在使用上面的命令进行移除has_journal

You don't have to reboot the system for the changes to take effect - the following command will do:

mount -o remount /

That's it. You can run

mount

# 系统io问题的一般思路:

查看系统总体IO性能------->找到占用高的进程-------->查看进程对应的IO操作-------->结合场景分析,根据场景优化

查看操作系统对脏页的回写行为

sysctl -a 2>/dev/null | grep dirty
echo 15 > /proc/sys/vm/dirty_background_ratio
vm.dirty_background_bytes = 0
vm.dirty_background_ratio = 15
vm.dirty_bytes = 0
vm.dirty_expire_centisecs = 3000
vm.dirty_ratio = 20
vm.dirty_writeback_centisecs = 500

dirty_background_ratio这个阈值后,pdflush线程会异步执行脏页回写,而当达到dirty_ratio阈值时,当时执行写操作的进程会被强制同步执行脏页回写操作,此时所有进程的写操作都会被阻塞,直到脏页占比降低到dirty_ratio之下,如果此时的脏页率仍然在dirty_backgroud_radio之上,将调用pdflush执行异步刷新。

默认的dirty_ratio的值应该设置得比dirty_background_ratio大。

anzhihe安志合个人博客,版权所有丨 如未注明,均为原创 丨转载请注明转自:https://chegva.com/3798.html | ☆★★每天进步一点点,加油!★★☆

您可能还感兴趣的文章!

发表评论

电子邮件地址不会被公开。 必填项已用*标注