百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分类 > 正文

解决磁盘IO读取慢全过程(磁盘io过高的原因)

ztj100 2024-11-09 15:19 15 浏览 0 评论

在两台型号相同的机器上(snap1 和snap3)测试磁盘的读取速度,发现两台机器的读取速度差的很大:

#dd if=/dev/dm-93 of=/dev/null bs=4M count=1024
711MB/s on snap1.
178MB/s on snap3.

接下来比较snap1和snap3两台机器上关于dm-93磁盘(raid)的以下字段输出都是一样

/sys/block/<device>/queue/max_sectors_kb
/sys/block/<device>/queue/nomerges
/sys/block/<device>/queue/rq_affinity
/sys/block/<device>/queue/scheduler

字段解释可以参考:
https://www.kernel.org/doc/Documentation/block/queue-sysfs.txt 

然后用blktrace监控一下磁盘IO处理过程:

#blktrace /dev/dm-93

使用blkparse查看blktrace收集的日志:

253,108  1        1     7.263881407 21072  Q   R 128 + 128 [dd]
在snap3上请求读取一页(64k每页)

253,108  1        2     7.263883907 21072  G   R 128 + 128 [dd]
253,108  1        3     7.263885017 21072  I   R 128 + 128 [dd]
253,108  1        4     7.263886077 21072  D   R 128 + 128 [dd]
提交IO到磁盘

253,108  0        1     7.264883548     3  C   R 128 + 128 [0]
大约1ms之后IO处理完成

253,108  1        5     7.264907601 21072  Q   R 256 + 128 [dd]
磁盘处理IO完成之后,dd才开始处理下一个IO

253,108  1        6     7.264908587 21072  G   R 256 + 128 [dd]
253,108  1        7     7.264908937 21072  I   R 256 + 128 [dd]
253,108  1        8     7.264909470 21072  D   R 256 + 128 [dd]
253,108  0        2     7.265757903     3  C   R 256 + 128 [0]

但是在snap1上则完全不同,上一个IO没有完成的情况下,dd紧接着处理下一个IO
253,108 17        1     5.020623706 23837  Q   R 128 + 128 [dd]
253,108 17        2     5.020625075 23837  G   R 128 + 128 [dd]
253,108 17        3     5.020625309 23837  P   N [dd]
253,108 17        4     5.020626991 23837  Q   R 256 + 128 [dd]
253,108 17        5     5.020627454 23837  M   R 256 + 128 [dd]
253,108 17        6     5.020628526 23837  Q   R 384 + 128 [dd]
253,108 17        7     5.020628704 23837  M   R 384 + 128 [dd]

现在怀疑是snap3上读取磁盘数据时没有预读,但是检查两台机器上read_ahead_kb的值都是一样的,都是512.

#/sys/block/<device>/queue/read_ahead_kb    
512

没办法了,发绝招:用kprobe探测一下相关函数参数:

#ra_trace.sh

#!/bin/bash

if [ "$#" != 1 ]; then
    echo "Usage: ra_trace.sh <device>"
    exit
fi
echo 'p:do_readahead __do_page_cache_readahead mapping=%di offset=%dx pages=%cx' >/sys/kernel/debug/tracing/kprobe_events
echo 'p:submit_ra ra_submit mapping=%si ra=%di rastart=+0(%di) rasize=+8(%di):u32 rapages=+16(%di):u32' >>/sys/kernel/debug/tracing/kprobe_events
echo 'p:sync_ra page_cache_sync_readahead mapping=%di ra=%si rastart=+0(%si) rasize=+8(%si):u32 rapages=+16(%si):u32' >>/sys/kernel/debug/tracing/kprobe_events
echo 'p:async_ra page_cache_async_readahead mapping=%di ra=%si rastart=+0(%si) rasize=+8(%si):u32 rapages=+16(%si):u32' >>/sys/kernel/debug/tracing/kprobe_events
echo 1 >/sys/kernel/debug/tracing/events/kprobes/enable
dd if=$1 of=/dev/null bs=4M count=1024
echo 0 >/sys/kernel/debug/tracing/events/kprobes/enable
cat /sys/kernel/debug/tracing/trace_pipe&
CATPID=$!
sleep 3
kill $CATPID

发现在snap3上预读磁盘的时候,rasize=0,确实在读数据时没有预读数据。

      <...>-35748 [009] 2507549.022375: submit_ra: (.ra_submit+0x0/0x38) mapping=c0000001bbd17728 ra=c000000191a261f0 rastart=df0b rasize=0 rapages=8
           <...>-35748 [009] 2507549.022376: do_readahead: (.__do_page_cache_readahead+0x0/0x208) mapping=c0000001bbd17728 offset=df0b pages=0
           <...>-35748 [009] 2507549.022694: sync_ra: (.page_cache_sync_readahead+0x0/0x50) mapping=c0000001bbd17728 ra=c000000191a261f0 rastart=df0b rasize=0 rapages=8
           <...>-35748 [009] 2507549.022695: submit_ra: (.ra_submit+0x0/0x38) mapping=c0000001bbd17728 ra=c000000191a261f0 rastart=df0c rasize=0 rapages=8

接下来仔细研读一下预读相关的代码,发现预读页与node上的内存相关:

unsigned long max_sane_readahead(unsigned long nr) 
{
        return min(nr, (node_page_state(numa_node_id(), NR_INACTIVE_FILE)
                + node_page_state(numa_node_id(), NR_FREE_PAGES)) / 2); 
}

比较一下snap1与snap3上node上的内存情况,发现snap3上node0上的内存和空闲内存都为0 ( 根因找到 :-)

snap1:
# /usr/bin/numactl --hardware
available: 1 nodes (0)
node 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
node 0 size: 8192 MB
node 0 free: 529 MB
node distances:
node   0
  0:  10

snap3:
# /usr/bin/numactl --hardware
available: 2 nodes (0,2)
node 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
node 0 size: 0 MB
node 0 free: 0 MB
node 2 cpus:
node 2 size: 8192 MB
node 2 free: 888 MB
node distances:
node   0   2
  0:  10  40
  2:  40  10

发现内核中有两个patch解决了这个问题,IO的预读不再以当前cpu上node上的内存情况来判断:

commit:6d2be915e589
mm/readahead.c: fix readahead failure for memoryless NUMA nodes and limit readahead pages

+#define MAX_READAHEAD   ((512*4096)/PAGE_CACHE_SIZE)
 /*
  * Given a desired number of PAGE_CACHE_SIZE readahead pages, return a
  * sensible upper limit.
  */
 unsigned long max_sane_readahead(unsigned long nr)
 {
-       return min(nr, (node_page_state(numa_node_id(), NR_INACTIVE_FILE)
-               + node_page_state(numa_node_id(), NR_FREE_PAGES)) / 2);
+       return min(nr, MAX_READAHEAD);
 }


commit:600e19afc5f8
mm: use only per-device readahead limit

Note: 以上内核代码基于Linux内核主线代码 Linux3.0

相关推荐

再说圆的面积-蒙特卡洛(蒙特卡洛方法求圆周率的matlab程序)

在微积分-圆的面积和周长(1)介绍微积分方法求解圆的面积,本文使用蒙特卡洛方法求解圆面积。...

python编程:如何使用python代码绘制出哪些常见的机器学习图像?

专栏推荐...

python创建分类器小结(pytorch分类数据集创建)

简介:分类是指利用数据的特性将其分成若干类型的过程。监督学习分类器就是用带标记的训练数据建立一个模型,然后对未知数据进行分类。...

matplotlib——绘制散点图(matplotlib散点图颜色和图例)

绘制散点图不同条件(维度)之间的内在关联关系观察数据的离散聚合程度...

python实现实时绘制数据(python如何绘制)

方法一importmatplotlib.pyplotaspltimportnumpyasnpimporttimefrommathimport*plt.ion()#...

简单学Python——matplotlib库3——绘制散点图

前面我们学习了用matplotlib绘制折线图,今天我们学习绘制散点图。其实简单的散点图与折线图的语法基本相同,只是作图函数由plot()变成了scatter()。下面就绘制一个散点图:import...

数据分析-相关性分析可视化(相关性分析数据处理)

前面介绍了相关性分析的原理、流程和常用的皮尔逊相关系数和斯皮尔曼相关系数,具体可以参考...

免费Python机器学习课程一:线性回归算法

学习线性回归的概念并从头开始在python中开发完整的线性回归算法最基本的机器学习算法必须是具有单个变量的线性回归算法。如今,可用的高级机器学习算法,库和技术如此之多,以至于线性回归似乎并不重要。但是...

用Python进行机器学习(2)之逻辑回归

前面介绍了线性回归,本次介绍的是逻辑回归。逻辑回归虽然名字里面带有“回归”两个字,但是它是一种分类算法,通常用于解决二分类问题,比如某个邮件是否是广告邮件,比如某个评价是否为正向的评价。逻辑回归也可以...

【Python机器学习系列】拟合和回归傻傻分不清?一文带你彻底搞懂

一、拟合和回归的区别拟合...

推荐2个十分好用的pandas数据探索分析神器

作者:俊欣来源:关于数据分析与可视化...

向量数据库:解锁大模型记忆的关键!选型指南+实战案例全解析

本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在...

用Python进行机器学习(11)-主成分分析PCA

我们在机器学习中有时候需要处理很多个参数,但是这些参数有时候彼此之间是有着各种关系的,这个时候我们就会想:是否可以找到一种方式来降低参数的个数呢?这就是今天我们要介绍的主成分分析,英文是Princip...

神经网络基础深度解析:从感知机到反向传播

本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在...

Python实现基于机器学习的RFM模型

CDA数据分析师出品作者:CDALevelⅠ持证人岗位:数据分析师行业:大数据...

取消回复欢迎 发表评论: