再现理想 发表于 2015-1-14 21:14:47

给大家带来Centos下的IO监控与剖析

欢迎大家来到仓酷云论坛!近期要在公司外部做个LinuxIO方面的培训,收拾动手头的材料给人人分享下

各类IO监督工具在LinuxIO系统布局中的地位
源自LinuxPerformanceandTuningGuidelines.pdf
1体系级IO监控

iostat

  iostat-xdm1#团体习气

%util代表磁盘忙碌水平。100%暗示磁盘忙碌,0%暗示磁盘余暇。可是注重,磁盘忙碌不代表磁盘(带宽)使用率高
argrq-sz提交给驱动层的IO哀求巨细,一样平常不小于4K,不年夜于max(readahead_kb,max_sectors_kb)
可用于判别以后的IO形式,一样平常情形下,特别是磁盘忙碌时,越年夜代表按次,越小代表随机
svctm一次IO哀求的办事工夫,关于单块盘,完整随机读时,基础在7ms摆布,既寻道+扭转提早工夫


注:各统计量之间干系
=======================================
%util=(r/s+w/s)*svctm/1000#行列长度=抵达率*均匀办事工夫
avgrq-sz=(rMB/s+wMB/s)*2048/(r/s+w/s)#2048为1M/512
=======================================
总结:
iostat统计的是通用块层经由兼并(rrqm/s,wrqm/s)后,间接向设备提交的IO数据,能够反应体系全体的IO情况,可是有以下2个弱点:
1间隔营业层对照悠远,跟代码中的write,read不合错误应(因为体系预读+pagecache+IO调剂算法等要素,也很难对应)
2是体系级,没举措准确到历程,好比只能告知你如今磁盘很忙,可是没举措告知你是谁在忙,在忙甚么?
2历程级IO监控

iotop和pidstat(仅rhel6u系列)

iotop望文生义,io版的top
pidstat望文生义,统计历程(pid)的stat,历程的stat天然包含历程的IO情况
这两个下令,都能够按历程统计IO情况,因而能够回覆你以下二个成绩

[*]
[*]以后体系哪些历程在占用IO,百分比是几?
[*]占用IO的历程是在读?仍是在写?读写量是几?

pidstat参数良多,仅给出几个团体习气
pidstat-d1#只显现IO

pidstat-u-r-d-t1#-dIO信息,
#-r缺页及内存信息
#-uCPU利用率
#-t以线程为统计单元
#11秒统计一次
iotop,很复杂,间接敲下令



block_dump,iodump

iotop和pidstat用着很爽,但二者都依附于/proc/pid/io文件导出的统计信息,这个关于老一些的内核是没有的,好比rhel5u2
因而只好用以上2个穷汉版下令来替换:
echo1>/proc/sys/vm/block_dump#开启block_dump,此时会把io信息输出到dmesg中
#源码:submit_bio@ll_rw_blk.c:3213
watch-n1"dmesg-c|grep-oP"w+(d+):(WRITE|READ)"|sort|uniq-c"
#一直的dmesg-c
echo0>/proc/sys/vm/block_dump#不必时封闭


也能够利用现成的剧本iodump,详细拜见http://code.google.com/p/maatkit/source/browse/trunk/util/iodump?r=5389


iotop.stp

systemtap剧本,一看就晓得是iotop下令的穷汉复制版,必要安装Systemtap,默许每隔5秒输入一次信息
stapiotop.stp#examples/io/iotop.stp
总结
历程级IO监控,

[*]能够回覆体系级IO监控不克不及回覆的2个成绩
[*]间隔营业层绝对较近(比方,能够统计历程的读写量)
可是也没有举措跟营业层的read,write接洽在一同,同时颗粒度较粗,没有举措告知你,以后历程读写了哪些文件?耗时?巨细?
3营业级IO监控

ioprofile

ioprofile下令实质上是lsof+strace,详细下载可见http://code.google.com/p/maatkit/
ioprofile能够回覆你以下三个成绩:
1以后历程某工夫内,在营业层面读写了哪些文件(read,write)?
2读写次数是几?(read,write的挪用次数)
3读写数据量几?(read,write的byte数)
假定某个举动会触发步伐一次IO举措,比方:"一个页面点击,招致背景读取A,B,C文件"
============================================
./io_event#假定摹拟一次IO举动,读取A文件一次,B文件500次,C文件500次
ioprofile-p`pidofio_event`-ccount#读写次数

ioprofile-p`pidofio_event`-ctimes#读写耗时


ioprofile-p`pidofio_event`-csizes#读写巨细



注:ioprofile仅撑持多线程步伐,对单线程步伐不撑持.关于单线程步伐的IO营业级剖析,strace足以。
总结:
ioprofile实质上是strace,因而能够看到read,write的挪用轨迹,能够做营业层的io剖析(mmap体例力所不及)
4文件级IO监控

文件级IO监控能够共同/增补"营业级和历程级"IO剖析
文件级IO剖析,次要针对单个文件,回覆以后哪些历程正在对某个文件举行读写操纵.
1lsof大概ls/proc/pid/fd
2inodewatch.stp
lsof告知你以后文件由哪些历程翻开
lsof../io#io目次以后由bash和lsof两个历程翻开

lsof下令只能回覆静态的信息,而且"翻开"其实不必定"读取",关于cat,echo如许的下令,翻开和读取都是刹时的,lsof很难捕获
能够用inodewatch.stp来填补
stapinodewatch.stpmajorminorinode#主设备号,辅设备号,文件inode节点号
stapinodewatch.stp0xfd0x00523170#主设备号,辅设备号,inode号,能够经由过程stat下令取得

5IO摹拟器

iotest.py#见附录
开辟职员能够使用ioprofile(大概strace)做具体剖析体系的IO路径,然后在步伐层面做响应的优化。
可是一样平常情形下调剂步伐,价值对照年夜,特别是当不断定修正计划究竟能不克不及无效时,最好有某种摹拟路子以疾速考证。
觉得我们的营业为例,发明某次查询时,体系的IO会见形式以下:
会见了A文件一次
会见了B文件500次,每次16字节,均匀距离502K
会见了C文件500次,每次200字节,均匀距离4M
这里B,C文件是交织会见的,既
1先会见B,读16字节,
2再会见C,读200字节,
3回到B,跳502K后再读16字节,
4回到C,跳4M后,再读200字节
5反复500次
strace文件以下:

一个复杂朴实的设法,将B,C交织读,改成先批量读B,再批量读C,因而调剂strace文件以下:

将调剂后的strace文件,作为输出交给iotest.py,iotest.py依照strace文件中的会见形式,摹拟响应的IO
iotest.py-sio.strace-ffmap
fmap为映照文件,将strace中的222,333等fd,映照到实践的文件中
===========================
111=/opt/work/io/A.data
222=/opt/work/io/B.data
333=/opt/work/io/C.data
===========================
6磁盘碎片收拾

一句话:只需磁盘容量不终年坚持80%以上,基础上不必忧虑碎片成绩。
假如其实忧虑,能够用defrag剧本
7其他IO相干下令

blockdev系列
=======================================
blockdev--getbsz/dev/sdc1#检察sdc1盘的块巨细
blockblockdev--getra/dev/sdc1#检察sdc1盘的预读(readahead_kb)巨细
blockdev--setra256/dev/sdc1#设置sdc1盘的预读(readahead_kb)巨细,低版的内核经由过程/sys设置,偶然会失利,不如blockdev靠谱
=======================================
附录iotest.py

#!/usr/bin/envpython#-*-coding:gbk-*-importosimportreimporttimeitfromctypesimportCDLL,create_string_buffer,c_ulong,c_longlongfromoptparseimportOptionParserusage=%prog-sstrace.log-ffileno.map_glibc=None_glibc_pread=None_c_char_buf=None_open_file=[]defgetlines(filename):_lines=[]withopen(filename,r)as_f:forlinein_f:ifline.strip()!="":_lines.append(line.strip())return_linesdefparsecmdline():parser=OptionParser(usage)parser.add_option("-s","--strace",dest="strace_filename",help="stracefile",metavar="FILE")parser.add_option("-f","--fileno",dest="fileno_filename",help="filenofile",metavar="FILE")(options,args)=parser.parse_args()ifoptions.strace_filenameisNone:parser.error("straceisnotspecified.")ifnotos.path.exists(options.strace_filename):parser.error("stracefiledoesnotexist.")ifoptions.fileno_filenameisNone:parser.error("filenoisnotspecified.")ifnotos.path.exists(options.strace_filename):parser.error("filenofiledoesnotexist.")returnoptions.strace_filename,options.fileno_filename###pread(15,"",4348,140156928)defparse_strace(filename):lines=getlines(filename)action=[]_regex_str=r(pread|pread64)[^d]*(d+),s*[^,]*,s*(*),s*(*)foriinlines:_match=re.match(_regex_str,i)if_matchisNone:continue#跳过有效行_type,_fn,_count,_off=_match.group(1),_match.group(2),_match.group(3),_match.group(4)_off=_off.replace(k,"*1024").replace(K,"*1024").replace(m,"*1048576").replace(M,"*1048576")_count=_count.replace(k,"*1024").replace(K,"*1024").replace(m,"*1048576").replace(M,"*1048576")#print_offaction.append()returnactiondefparse_fileno(filename):lines=getlines(filename)fmap={}foriinlines:ifi.strip().startswith("#"):continue#正文行_split=iflen(_split)!=2:continue#有效行fno,fname=_split,_splitfmap=fnamereturnfmapdefsimulate_before(strace,fmap):global_open_file,_c_char_bufrfmap={}foriinfmap.values():_f=open(i,"r+b")#print"open{0}:{1}".format(_f.fileno(),i)_open_file.append(_f)rfmap=str(_f.fileno())#反向映照to_read=4*1024#默许4Kbufforiinstrace:i=rfmap]]#fid->fname->fid映照转换to_read=max(to_read,int(i))#print"readbufferlen:%dByte"%to_read_c_char_buf=create_string_buffer(to_read)defsimulate_after():global_open_filefor_fin_open_file:_f.close()defsimulate(actions):#timeit.time.sleep(10)#歇息2秒钟,以便IO距离start=timeit.time.time()foractinactions:__simulate__(act)finish=timeit.time.time()returnfinish-startdef__simulate__(act):global_glibc,_glibc_pread,_c_char_bufif"pread"inact:_fno=int(act)_buf=_c_char_buf_count=c_ulong(int(act))_off=c_longlong(int(act))_glibc_pread(_fno,_buf,_count,_off)#print_glibc.time(None)else:passpassdefloadlibc():global_glibc,_glibc_pread_glibc=CDLL("libc.so.6")_glibc_pread=_glibc.pread64if__name__=="__main__":_strace,_fileno=parsecmdline()#剖析下令行参数loadlibc()#加载静态库_action=parse_strace(_strace)#剖析action文件_fmap=parse_fileno(_fileno)#剖析文件名映照文件simulate_before(_action,_fmap)#预处置#print"totaliooperate:%d"%(len(_action))#foractin_action:print"".join(act)print"%f"%simulate(_action)


欢迎大家来到仓酷云论坛!

若相依 发表于 2015-1-17 09:04:33

我学习Linux的心得体会,希望对大家的学习有所帮助,由于水平有限,本文难免有所欠缺,望请指正。

再见西城 发表于 2015-1-24 16:47:21

最好先搜寻一下论坛是否有您需要的文章。这样可以获得事半功倍的效果。

飘飘悠悠 发表于 2015-2-2 11:44:35

一定要学好命令,shell是命令语言,命令解释程序及程序设计语言的统称,shell也负责用户和操作系统之间的沟通。

不帅 发表于 2015-2-7 20:40:54

即便是非英语国家的人发布技术文档,Linux也都首先翻译成英语在国际学术杂志和网络上发表。

精灵巫婆 发表于 2015-2-23 18:40:25

其实当你安装了一个完整的Linux系统后其中已经包含了一个强大的帮助,只是可能你还没有发现和使用它们的技巧。

海妖 发表于 2015-3-7 10:38:20

和私有操作系统不同,各个Linux的发行版本的技术支持时间都较短,这对于Linux初学者是往往不够的。

深爱那片海 发表于 2015-3-15 04:52:33

另外Linux上也有很多的应用软件,安装运行了这些软件后,你就可以在Linux上编辑文档、图?片,玩游戏、上网、播放多媒体文件等。

飘灵儿 发表于 2015-3-21 21:50:04

熟读Linux系统有关知识,如系统目录树,有关内容可购书阅读或搜索论坛。
页: [1]
查看完整版本: 给大家带来Centos下的IO监控与剖析