<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Erlang非业余研究</title>
	<atom:link href="http://blog.yufeng.info/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.yufeng.info</link>
	<description>Erlang系统深度探索和应用</description>
	<lastBuildDate>Tue, 17 Jan 2012 06:05:54 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>MYSQL数据库网卡软中断不平衡问题及解决方案</title>
		<link>http://blog.yufeng.info/archives/2037</link>
		<comments>http://blog.yufeng.info/archives/2037#comments</comments>
		<pubDate>Mon, 16 Jan 2012 13:30:39 +0000</pubDate>
		<dc:creator>Yu Feng</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[工具介绍]]></category>
		<category><![CDATA[网络编程]]></category>
		<category><![CDATA[RPS]]></category>
		<category><![CDATA[softirqd]]></category>
		<category><![CDATA[systemtap]]></category>

		<guid isPermaLink="false">http://blog.yufeng.info/?p=2037</guid>
		<description><![CDATA[原创文章，转载请注明： 转载自Erlang非业余研究 本文链接地址: MYSQL数据库网卡软中断不平衡问题及解决方案 最近公司在MySQL的数据库上由于采用了高速的如PCIe卡以及大内存，去年在压力测试的时候突然发现数据库的流量可以把一个千M网卡压满了。随着数据库的优化，现在流量可以达到150M，所以我们采用了双网卡，在交换机上绑定，做LB的方式，提高系统的吞吐量。 但是在最近压测试的一个数据库中，mpstat发现其中一个核的CPU被软中断耗尽： Mysql QPS 2W左右 &#8212;&#8212;&#8211; &#8212;&#8211;load-avg&#8212;- &#8212;cpu-usage&#8212; &#8212;swap&#8212; -QPS- -TPS- -Hit%- time &#124; 1m 5m 15m &#124;usr sys idl iow&#124; si so&#124; ins upd del sel iud&#124; lor hit&#124; 13:43:46&#124; 0.00 0.00 0.00&#124; 67 27 3 3&#124; 0 0&#124; 0 0 0 0 0&#124; 0 100.00&#124; 13:43:47&#124; 0.00 0.00 0.00&#124; [...]]]></description>
			<content:encoded><![CDATA[<div style="margin-top: 15px; font-style: italic">
<p><strong>原创文章，转载请注明：</strong> 转载自<a href="http://blog.yufeng.info/">Erlang非业余研究</a></p>
<p><strong>本文链接地址:</strong> <a href="http://blog.yufeng.info/archives/2037">MYSQL数据库网卡软中断不平衡问题及解决方案</a></p>
</div>
<p>最近公司在MySQL的数据库上由于采用了高速的如PCIe卡以及大内存，去年在压力测试的时候突然发现数据库的流量可以把一个千M网卡压满了。随着数据库的优化，现在流量可以达到150M，所以我们采用了双网卡，在交换机上绑定，做LB的方式，提高系统的吞吐量。 </p>
<p>但是在最近压测试的一个数据库中，mpstat发现其中一个核的CPU被软中断耗尽：</p>
<p>Mysql QPS 2W左右</p>
<blockquote><p>
&#8212;&#8212;&#8211; &#8212;&#8211;load-avg&#8212;- &#8212;cpu-usage&#8212; &#8212;swap&#8212;                    -QPS- -TPS-         -Hit%-<br />
  time  |  1m    5m   15m |usr sys idl iow|   si   so|  ins   upd   del   sel   iud|     lor    hit|<br />
13:43:46| 0.00  0.00  0.00| 67  27   3   3|    0    0|    0     0     0     0     0|       0 100.00|<br />
13:43:47| 0.00  0.00  0.00| 30  10  60   0|    0    0|    0     0     0 19281     0|  326839 100.00|<br />
13:43:48| 0.00  0.00  0.00| 28  10  63   0|    0    0|    0     0     0 19083     0|  323377 100.00|<br />
13:43:49| 0.00  0.00  0.00| 28  10  63   0|    0    0|    0     0     0 19482     0|  330185 100.00|<br />
13:43:50| 0.00  0.00  0.00| 26   9  65   0|    0    0|    0     0     0 19379     0|  328575 100.00|<br />
13:43:51| 0.00  0.00  0.00| 27   9  64   0|    0    0|    0     0     0 19723     0|  334378 100.00|
</p></blockquote>
<p>mpstat -P ALL 1说：<br />
<a href="http://blog.yufeng.info/wp-content/uploads/2012/01/ms1.jpg"><img src="http://blog.yufeng.info/wp-content/uploads/2012/01/ms1.jpg" alt="" title="软中断调整前" width="712" height="237" class="alignnone size-full wp-image-2039" /></a></p>
<p>针对这个问题，我们利用工具，特别是systemtap, 一步步来调查和解决问题。<br />
<span id="more-2037"></span><br />
首先我们来确认下网卡的设置：</p>
<pre class="brush: bash; title: ; notranslate">
$uname -r
2.6.32-131.21.1.tb399.el6.x86_64

$ lspci -vvvv
01:00.0 Ethernet controller: Broadcom Corporation NetXtreme II BCM5709 Gigabit Ethernet (rev 20)
        Subsystem: Broadcom Corporation NetXtreme II BCM5709 Gigabit Ethernet
        Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
        Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast &gt;TAbort- &lt;TAbort- &lt;MAbort- &gt;SERR- &lt;PERR-
        Latency: 0, Cache Line Size: 256 bytes
        Interrupt: pin A routed to IRQ 114
        Region 0: Memory at f6000000 (64-bit, non-prefetchable) [size=32M]
        Capabilities: &lt;access denied&gt;

01:00.1 Ethernet controller: Broadcom Corporation NetXtreme II BCM5709 Gigabit Ethernet (rev 20)
        Subsystem: Broadcom Corporation NetXtreme II BCM5709 Gigabit Ethernet
        Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
        Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast &gt;TAbort- &lt;TAbort- &lt;MAbort- &gt;SERR- &lt;PERR-
        Latency: 0, Cache Line Size: 256 bytes
        Interrupt: pin B routed to IRQ 122
        Region 0: Memory at f8000000 (64-bit, non-prefetchable) [size=32M]
        Capabilities: &lt;access denied&gt;

$cat /proc/net/bonding/bond0
Ethernet Channel Bonding Driver: v3.6.0 (September 26, 2009)

Bonding Mode: fault-tolerance (active-backup)
Primary Slave: None
Currently Active Slave: em1
MII Status: up
MII Polling Interval (ms): 100
Up Delay (ms): 0
Down Delay (ms): 0

Slave Interface: em1
MII Status: up
Link Failure Count: 0
Permanent HW addr: 78:2b:cb:1f:eb:c9
Slave queue ID: 0

Slave Interface: em2
MII Status: up
Link Failure Count: 0
Permanent HW addr: 78:2b:cb:1f:eb:ca
Slave queue ID: 0
</pre>
<p>从上面的信息我们可以确认二块 Broadcom Corporation NetXtreme II BCM5709 Gigabit Ethernet (rev 20)网卡在做bonding。</p>
<p>我们的系统内核组维护的是RHEL 6.1, 很容易可以从/proc/interrupts和/proc/softirqs得到中断和软中断的信息的信息。<br />
我们特别留意下softirq, 由于CPU太多，信息太乱，我只列出7个核心的情况：</p>
<pre class="brush: bash; title: ; notranslate">
$cat /proc/softirqs|tr -s ' ' '\t'|cut -f 1-8
        CPU0    CPU1    CPU2    CPU3    CPU4    CPU5    CPU6
        HI:     0       0       0       0       0       0
        TIMER:  401626149       366513734       274660062       286091775       252287943       258932438
        NET_TX: 136905  10428   17269   25080   16613   17876
        NET_RX: 1898437808      2857018450      580117978       26443   11820   15545
        BLOCK:  716495491       805780859       113853932       132589667       106297189       104629321
BLOCK_IOPOLL:   0       0       0       0       0       0       0
        TASKLET:        190643874       775861235       0       0       1       0
        SCHED:  61726009        66994763        102590355       83277433        144588168       154635009
        HRTIMER:        1883420 1837160 2316722 2369920 1721755 1666867
        RCU:    391610041       365150626       275741153       287074106       253401636       260389306
</pre>
<p>从上面我们粗粗可以看出网卡的软中断接收和发送都不平衡。<br />
单单这些信息还不够，还是无法区别为什么一个核心被压垮了，因为我们的机器上还有个中断的大户:fusionIO PCIe卡，在过去的测试中该卡也会吃掉大量的CPU，所以目前无法判断就是网卡引起的，因而我们用stap来double check下：</p>
<pre class="brush: bash; title: ; notranslate">
$cat i.stp
global hard, soft, wq

probe irq_handler.entry {
hard[irq, dev_name]++;
}

probe timer.s(1) {
println(&quot;==irq number:dev_name&quot;)
foreach( [irq, dev_name] in hard- limit 5) {
printf(&quot;%d,%s-&gt;%d\n&quot;, irq, kernel_string(dev_name), hard[irq, dev_name]);
}

println(&quot;==softirq cpu:h:vec:action&quot;)
foreach( 1 in soft- limit 5) {
printf(&quot;%d:%x:%x:%s-&gt;%d\n&quot;, c, h, vec, symdata(action), soft1);
}

println(&quot;==workqueue wq_thread:work_func&quot;)
foreach( [wq_thread,work_func] in wq- limit 5) {
printf(&quot;%x:%x-&gt;%d\n&quot;, wq_thread, work_func, wq[wq_thread, work_func]);
}

println(&quot;\n&quot;)
delete hard
delete soft
delete wq
}

probe softirq.entry {
soft[cpu(), h,vec,action]++;
}

probe workqueue.execute {
wq[wq_thread, work_func]++
}

probe begin {
println(&quot;~&quot;)
}

$sudo stap i.stp
==irq number:dev_name
73,em1-6-&gt;7150
50,iodrive-fct0-&gt;7015
71,em1-4-&gt;6985
74,em1-7-&gt;6680
69,em1-2-&gt;6557
==softirq cpu:h:vec:action
1:ffffffff81a23098:ffffffff81a23080:0xffffffff81411110-&gt;36627
1:ffffffff81a230b0:ffffffff81a23080:0xffffffff8106f950-&gt;2169
1:ffffffff81a230a0:ffffffff81a23080:0xffffffff81237100-&gt;1736
0:ffffffff81a230a0:ffffffff81a23080:0xffffffff81237100-&gt;1308
1:ffffffff81a23088:ffffffff81a23080:0xffffffff81079ee0-&gt;941
==workqueue wq_thread:work_func
ffff880c14268a80:ffffffffa026b390-&gt;51
ffff880c1422e0c0:ffffffffa026b390-&gt;30
ffff880c1425f580:ffffffffa026b390-&gt;25
ffff880c1422f540:ffffffffa026b390-&gt;24
ffff880c14268040:ffffffffa026b390-&gt;23

#上面软中断的action的符号信息：
$addr2line -e /usr/lib/debug/lib/modules/2.6.32-131.21.1.tb411.el6.x86_64/vmlinux ffffffff81411110
/home/ads/build22_6u0_x64/workspace/kernel-el6/origin/taobao-kernel-build/kernel-2.6.32-131.21.1.el6/linux-2.6.32-131.21.1.el6.x86_64/net/core/ethtool.c:653

$addr2line -e /usr/lib/debug/lib/modules/2.6.32-131.21.1.tb411.el6.x86_64/vmlinux ffffffff810dc3a0
/home/ads/build22_6u0_x64/workspace/kernel-el6/origin/taobao-kernel-build/kernel-2.6.32-131.21.1.el6/linux-2.6.32-131.21.1.el6.x86_64/kernel/relay.c:466

$addr2line -e /usr/lib/debug/lib/modules/2.6.32-131.21.1.tb411.el6.x86_64/vmlinux ffffffff81079ee0
/home/ads/build22_6u0_x64/workspace/kernel-el6/origin/taobao-kernel-build/kernel-2.6.32-131.21.1.el6/linux-2.6.32-131.21.1.el6.x86_64/include/trace/events/timer.h:118

$addr2line -e /usr/lib/debug/lib/modules/2.6.32-131.21.1.tb411.el6.x86_64/vmlinux ffffffff8105d120
/home/ads/build22_6u0_x64/workspace/kernel-el6/origin/taobao-kernel-build/kernel-2.6.32-131.21.1.el6/linux-2.6.32-131.21.1.el6.x86_64/kernel/sched.c:2460
</pre>
<p>这次我们可以轻松的定位到硬中断基本上是平衡的，软中断都基本压在了1号核心上，再根据符号查找确认是网卡的问题。</p>
<p>好了，现在定位到了，问题解决起来就容易了：<br />
1. 采用多队列万M网卡。<br />
2. 用google的RPS patch来解决软中断平衡的问题, 把软中断分散到不同的核心去，参见<a href="http://lwn.net/Articles/328339/">这里</a>.</p>
<p>我们还是用穷人的方案，写了个shell脚本来做这个事情：</p>
<pre class="brush: bash; title: ; notranslate">
$cat em.sh
#! /bin/bash                                                                                                                                                           

for i in `seq 0 7`
do
  echo f|sudo tee /sys/class/net/em1/queues/rx-$i/rps_cpus &gt;/dev/null
  echo f|sudo tee /sys/class/net/em2/queues/rx-$i/rps_cpus &gt;/dev/null
done

$sudo ./em.sh

$mpstat -P ALL 1
</pre>
<p>就可以看到我们的成果：<br />
<a href="http://blog.yufeng.info/wp-content/uploads/2012/01/ms2.jpg"><img src="http://blog.yufeng.info/wp-content/uploads/2012/01/ms2.jpg" alt="" title="软中断调整后" width="710" height="237" class="alignnone size-full wp-image-2040" /></a></p>
<p>网卡的软中断成功分到二个核心上了，不再把一个核心拖死。</p>
<p>小结：多观察系统是好事。<br />
后记：</p>
<p>有同学留言说:</p>
<blockquote><p>根据我们的测试，BCM5709应该是支持多队列的</p></blockquote>
<p>从中断来看确实是平衡的，也就是说多队列在工作，但是为什么软中断不平衡呢，还有CPU1上还压着什么任务呢？继续调查！<br />
待续～</p>
<p>祝玩得开心！</p>
<div style="margin-top: 0; margin-bottom: 15px; color: #888888; font-size: 80%; font-style: italic">
<p>Post Footer automatically generated by <a href="http://easwy.com/blog/wordpress/wp-posturl/" style="color: #8888FF; text-decoration: underline;">wp-posturl plugin</a> for wordpress.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.yufeng.info/archives/2037/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>systemtap如何跟踪libc.so</title>
		<link>http://blog.yufeng.info/archives/2033</link>
		<comments>http://blog.yufeng.info/archives/2033#comments</comments>
		<pubDate>Thu, 12 Jan 2012 08:29:13 +0000</pubDate>
		<dc:creator>Yu Feng</dc:creator>
				<category><![CDATA[工具介绍]]></category>
		<category><![CDATA[调优]]></category>
		<category><![CDATA[libc.so]]></category>
		<category><![CDATA[systemtap]]></category>

		<guid isPermaLink="false">http://blog.yufeng.info/?p=2033</guid>
		<description><![CDATA[原创文章，转载请注明： 转载自Erlang非业余研究 本文链接地址: systemtap如何跟踪libc.so 下午和周忱同学折腾复杂程序的内存泄漏问题，用了valgrind, gogle perftools等工具都不大好用，很容易把应用程序搞死，于是打算用systemtap来在libc.so层面了解内存的使用情况。主要思路就是看malloc/realloc和free的调用次数的平衡。 首先准备下环境，系统是标准的RHEL 5u4： 内核的符号是OK的，glibc没有安装符号。系统提示用 debuginfo-install glibc-2.5-42.x86_64 命令安装符号信息，但是RHEL 5不交钱不能用这个服务的，只能自己下载包安装。 这次有了glibc的符号了，可以方便的跟踪libc.so中malloc的使用情况。 接着我们来简单的写个c程序调用malloc, 同时写个stap脚本来跟踪malloc的调用堆栈： 现在程序准备好了，那么我们来执行下看内存泄漏在那里： 我们看到在a.out的0x4004a6的地方地方调用了malloc, 但是具体在程序里面是哪行呢？ 用add2line就很容易找出来： 哈哈, 祝大家玩得开心。 Post Footer automatically generated by wp-posturl plugin for wordpress.]]></description>
			<content:encoded><![CDATA[<div style="margin-top: 15px; font-style: italic">
<p><strong>原创文章，转载请注明：</strong> 转载自<a href="http://blog.yufeng.info/">Erlang非业余研究</a></p>
<p><strong>本文链接地址:</strong> <a href="http://blog.yufeng.info/archives/2033">systemtap如何跟踪libc.so</a></p>
</div>
<p>下午和周忱同学折腾复杂程序的内存泄漏问题，用了valgrind, gogle perftools等工具都不大好用，很容易把应用程序搞死，于是打算用systemtap来在libc.so层面了解内存的使用情况。主要思路就是看malloc/realloc和free的调用次数的平衡。</p>
<p>首先准备下环境，系统是标准的RHEL 5u4：</p>
<pre class="brush: bash; title: ; notranslate">
$ uname -r
2.6.18-164.el5

$ stap -V
SystemTap translator/driver (version 1.3/0.137 non-git sources)
Copyright (C) 2005-2010 Red Hat, Inc. and others
This is free software; see the source for copying conditions.
enabled features: LIBRPM LIBSQLITE3 NSS BOOST_SHARED_PTR TR1_UNORDERED_MAP
$stap -L  'kernel.function(&quot;printk&quot;)'
kernel.function(&quot;printk@kernel/printk.c:533&quot;) $fmt:char const* $args:va_list

$ stap -L  'process(&quot;/lib64/libc.so.6&quot;).function(&quot;malloc&quot;)'
Missing separate debuginfos, use: debuginfo-install glibc-2.5-42.x86_64
</pre>
<p>内核的符号是OK的，glibc没有安装符号。系统提示用 debuginfo-install glibc-2.5-42.x86_64 命令安装符号信息，但是RHEL 5不交钱不能用这个服务的，只能自己下载包安装。<br />
<span id="more-2033"></span></p>
<pre class="brush: bash; title: ; notranslate">
$ wget -c ftp.redhat.com/pub/redhat/linux/enterprise/5Server/en/os/x86_64/Debuginfo/glibc-debuginfo-2.5-42.x86_64.rpm
$ sudo rpm -i  glibc-debuginfo-2.5-42.x86_64.rpm
$ stap -L  'process(&quot;/lib64/libc.so.6&quot;).function(&quot;malloc&quot;)'
process(&quot;/lib64/libc-2.5.so&quot;).function(&quot;__libc_malloc@/usr/src/debug/glibc-2.5-20061008T1257/malloc/malloc.c:3560&quot;) $bytes:size_t
</pre>
<p>这次有了glibc的符号了，可以方便的跟踪libc.so中malloc的使用情况。<br />
接着我们来简单的写个c程序调用malloc, 同时写个stap脚本来跟踪malloc的调用堆栈：</p>
<pre class="brush: bash; title: ; notranslate">
$ cat t.c
#include &lt;stdlib.h&gt;

void fun() {
  malloc(1000);
}

int main(int argc, char *argv[]) {
  fun();
  return 0;
}

$cat m.stp
probe process(&quot;/lib64/libc.so.6&quot;).function(&quot;malloc&quot;) {
if (target()== pid()) {
print_ubacktrace();
exit();
}
}
probe begin {
println(&quot;~&quot;);
}

$ gcc  -g t.c

$ stap -L 'process(&quot;./a.out&quot;).function(&quot;*&quot;)'
process(&quot;/home/chuba/a.out&quot;).function(&quot;fun@/home/chuba/t.c:3&quot;)
process(&quot;/home/chuba/a.out&quot;).function(&quot;main@/home/chuba/t.c:7&quot;) $argc:int $argv:char**
</pre>
<p>现在程序准备好了，那么我们来执行下看内存泄漏在那里：</p>
<pre class="brush: bash; title: ; notranslate">
$sudo stap m.stp -c ./a.out
~
 0x33d5e74b96 : malloc+0x16/0x230 [libc-2.5.so]
 0x4004a6 [a.out+0x4a6/0x1000]
</pre>
<p>我们看到在a.out的0x4004a6的地方地方调用了malloc, 但是具体在程序里面是哪行呢？ 用add2line就很容易找出来：</p>
<pre class="brush: bash; title: ; notranslate">
$ addr2line -e ./a.out 0x4004a6
/home/chuba/t.c:5
$ nl t.c
     1  #include &lt;stdlib.h&gt;

     2  void fun() {
     3    malloc(1000);
     4  }

     5  int main(int argc, char *argv[]) {
     6    fun();
     7    return 0;
     8  }
</pre>
<p>哈哈,<br />
祝大家玩得开心。</p>
<div style="margin-top: 0; margin-bottom: 15px; color: #888888; font-size: 80%; font-style: italic">
<p>Post Footer automatically generated by <a href="http://easwy.com/blog/wordpress/wp-posturl/" style="color: #8888FF; text-decoration: underline;">wp-posturl plugin</a> for wordpress.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.yufeng.info/archives/2033/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>给你的Linux系统上点stress</title>
		<link>http://blog.yufeng.info/archives/2023</link>
		<comments>http://blog.yufeng.info/archives/2023#comments</comments>
		<pubDate>Mon, 09 Jan 2012 08:19:02 +0000</pubDate>
		<dc:creator>Yu Feng</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[工具介绍]]></category>
		<category><![CDATA[stress]]></category>

		<guid isPermaLink="false">http://blog.yufeng.info/?p=2023</guid>
		<description><![CDATA[原创文章，转载请注明： 转载自Erlang非业余研究 本文链接地址: 给你的Linux系统上点stress 《debug hacks》 这本书介绍了非常多的调试手段和工具， 其中提到了stress这个简单的压力测试工具，在我们的日常工作中很有用。利用它可以给我们的系统施加CPU，内存,IO和磁盘的压力，在模拟极端场景给应用系统造成的压力方面很有帮助。 主页见这里：http://weather.ou.edu/~apw/projects/stress/ 这里还有一篇介绍如何使用的博客。 stress is a deliberately simple workload generator for POSIX systems. It imposes a configurable amount of CPU, memory, I/O, and disk stress on the system. It is written in C, and is free software licensed under the GPLv2. 这个stress实现非常的简单，所有的功能在一个.c文件里面实现， 系统运行的时候会fork多个子进程，分别进行CPU,内存，IO方面的折磨。 因为简单所以稳定。参考例子： $ stress &#8211;cpu 2 [...]]]></description>
			<content:encoded><![CDATA[<div style="margin-top: 15px; font-style: italic">
<p><strong>原创文章，转载请注明：</strong> 转载自<a href="http://blog.yufeng.info/">Erlang非业余研究</a></p>
<p><strong>本文链接地址:</strong> <a href="http://blog.yufeng.info/archives/2023">给你的Linux系统上点stress</a></p>
</div>
<p>《debug hacks》 这本书介绍了非常多的调试手段和工具， 其中提到了stress这个简单的压力测试工具，在我们的日常工作中很有用。利用它可以给我们的系统施加CPU，内存,IO和磁盘的压力，在模拟极端场景给应用系统造成的压力方面很有帮助。</p>
<p>主页见<a href="http://weather.ou.edu/~apw/projects/stress/">这里</a>：http://weather.ou.edu/~apw/projects/stress/<br />
<a href="http://blog.chinaunix.net/space.php?uid=15007890&#038;do=blog&#038;id=2150052">这里</a>还有一篇介绍如何使用的博客。</p>
<blockquote><p>stress is a deliberately simple workload generator for POSIX systems. It imposes a configurable amount of CPU, memory, I/O, and disk stress on the system. It is written in C, and is free software licensed under the GPLv2.
</p></blockquote>
<p>这个stress实现非常的简单，所有的功能在一个.c文件里面实现， 系统运行的时候会fork多个子进程，分别进行CPU,内存，IO方面的折磨。<br />
<span id="more-2023"></span><br />
因为简单所以稳定。参考例子：</p>
<blockquote><p> $ stress &#8211;cpu 2 &#8211;io 1 &#8211;vm 1 &#8211;vm-bytes 128M &#8211;timeout 10s &#8211;verbose<br />
   stress: info: [9372] dispatching hogs: 2 cpu, 1 io, 1 vm, 0 hdd<br />
   stress: dbug: [9372] (243) using backoff sleep of 12000us<br />
   stress: dbug: [9372] (262) setting timeout to 10s<br />
   stress: dbug: [9372] (285) &#8211;> hogcpu worker 9373 forked<br />
   stress: dbug: [9372] (305) &#8211;> hogio worker 9374 forked<br />
   stress: dbug: [9372] (325) &#8211;> hogvm worker 9375 forked<br />
   stress: dbug: [9372] (243) using backoff sleep of 3000us<br />
   stress: dbug: [9372] (262) setting timeout to 10s<br />
   stress: dbug: [9372] (285) &#8211;> hogcpu worker 9376 forked<br />
   stress: dbug: [9375] (466) hogvm worker malloced 134217728 bytes<br />
   stress: dbug: [9372] (382) <-- worker 9374 signalled normally<br />
   stress: dbug: [9372] (382) <-- worker 9373 signalled normally<br />
   stress: dbug: [9372] (382) <-- worker 9375 signalled normally<br />
   stress: dbug: [9372] (382) <-- worker 9376 signalled normally<br />
   stress: info: [9372] successful run completed in 10s
</p></blockquote>
<p>由于stress支持posix平台，简单的下载，编译和安装就好了,  很顺利！<br />
按照文档默认的运行参数，让系统来点体验：</p>
<pre class="brush: bash; title: ; notranslate">
$stress --cpu 8 --io 4 --vm 2 --vm-bytes 128M --timeout 10d
stress: info: [23176] dispatching hogs: 8 cpu, 4 io, 2 vm, 0 hdd
</pre>
<p>pstree可以看到：<br />
<a href="http://blog.yufeng.info/wp-content/uploads/2012/01/stress1.jpg"><img src="http://blog.yufeng.info/wp-content/uploads/2012/01/stress1.jpg" alt="" title="pstree" width="508" height="187" class="alignnone size-full wp-image-2024" /></a></p>
<p>nmon可以看到：<br />
<a href="http://blog.yufeng.info/wp-content/uploads/2012/01/stress2.jpg"><img src="http://blog.yufeng.info/wp-content/uploads/2012/01/stress2.jpg" alt="" title="nmon" width="678" height="506" class="alignnone size-full wp-image-2025" /></a></p>
<p>具体使用可以参考man stress！</p>
<p>祝大家玩得开心！</p>
<div style="margin-top: 0; margin-bottom: 15px; color: #888888; font-size: 80%; font-style: italic">
<p>Post Footer automatically generated by <a href="http://easwy.com/blog/wordpress/wp-posturl/" style="color: #8888FF; text-decoration: underline;">wp-posturl plugin</a> for wordpress.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.yufeng.info/archives/2023/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>fio配合cgroup测试存储设备IOPS分配</title>
		<link>http://blog.yufeng.info/archives/2001</link>
		<comments>http://blog.yufeng.info/archives/2001#comments</comments>
		<pubDate>Wed, 28 Dec 2011 08:30:59 +0000</pubDate>
		<dc:creator>Yu Feng</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[工具介绍]]></category>
		<category><![CDATA[调优]]></category>
		<category><![CDATA[cgroup]]></category>
		<category><![CDATA[fio]]></category>

		<guid isPermaLink="false">http://blog.yufeng.info/?p=2001</guid>
		<description><![CDATA[原创文章，转载请注明： 转载自Erlang非业余研究 本文链接地址: fio配合cgroup测试存储设备IOPS分配 随着包括存储设备在内服务器的能力越来越高，特别是用上了PCIe存储卡后，IOPS能力通常有10几万，马上过剩。在这种情况下，一台服务器可以干很多事情，在上面跑很多服务。那么如何保证系统的服务质量是个很重要的事情了。 我们在下来的的项目中倾向于用cgroup来做资源的隔离和限制，原因是cgroup的开销很小，而且很易用。cgroup 可以参考这里 我们特别关心cgroup的blkio子模块，他有2种限制模式: 1. throttle，限制每个进程能使用的IOPS或者吞吐量。 2. weight，现在每个进程能使用的IOPS的能力的比例，必须通过CFQ调度器来实现。 文档和具体的参数可以看上面提到的cgroup文档。 要使用blkio的weight限制需要注意几个事情： 1. 必须走directio, 如果buffered io因为最终写IO的进程不是发起IO的进程，结果会有很大的偏差。 2. 调度器必须是CFQ。 3. 测试工具必须支持cgroup的相关限制。 4. 最好是随机的IO。 新版本的支持cgroup的fio可以在这里下载 git clone git://git.kernel.dk/fio.git， 更多参看这里。 man fio下可以看看cgroup相关的文档: cgroup=str Add job to this control group. If it doesn&#8217;t exist, it will be created. The system must have a mounted cgroup blkio mount [...]]]></description>
			<content:encoded><![CDATA[<div style="margin-top: 15px; font-style: italic">
<p><strong>原创文章，转载请注明：</strong> 转载自<a href="http://blog.yufeng.info/">Erlang非业余研究</a></p>
<p><strong>本文链接地址:</strong> <a href="http://blog.yufeng.info/archives/2001">fio配合cgroup测试存储设备IOPS分配</a></p>
</div>
<p>随着包括存储设备在内服务器的能力越来越高，特别是用上了PCIe存储卡后，IOPS能力通常有10几万，马上过剩。在这种情况下，一台服务器可以干很多事情，在上面跑很多服务。那么如何保证系统的服务质量是个很重要的事情了。</p>
<p>我们在下来的的项目中倾向于用cgroup来做资源的隔离和限制，原因是cgroup的开销很小，而且很易用。cgroup 可以参考<a href="http://docs.redhat.com/docs/en-US/Red_Hat_Enterprise_Linux/6/pdf/Resource_Management_Guide/Red_Hat_Enterprise_Linux-6-Resource_Management_Guide-en-US.pdf">这里</a></p>
<p>我们特别关心cgroup的blkio子模块，他有2种限制模式:<br />
1. throttle，限制每个进程能使用的IOPS或者吞吐量。<br />
2. weight，现在每个进程能使用的IOPS的能力的比例，必须通过CFQ调度器来实现。<br />
文档和具体的参数可以看上面提到的cgroup文档。</p>
<p><span id="more-2001"></span><br />
要使用blkio的weight限制需要注意几个事情：<br />
1. 必须走directio, 如果buffered io因为最终写IO的进程不是发起IO的进程，结果会有很大的偏差。<br />
2. 调度器必须是CFQ。<br />
3. 测试工具必须支持cgroup的相关限制。<br />
4. 最好是随机的IO。</p>
<p>新版本的支持cgroup的fio可以在这里下载 git clone git://git.kernel.dk/fio.git， 更多参看<a href="http://blog.yufeng.info/archives/tag/fio">这里</a>。</p>
<p>man fio下可以看看cgroup相关的文档:</p>
<blockquote><p>       cgroup=str<br />
              Add  job to this control group. If it doesn&#8217;t exist, it will be created.  The system must have a mounted cgroup blkio mount<br />
              point for this to work. If your system doesn&#8217;t have it mounted, you can do so with:</p>
<p>              # mount -t cgroup -o blkio none /cgroup</p>
<p>       cgroup_weight=int<br />
              Set the weight of the cgroup to this value. See the documentation that comes with the kernel, allowed  values  are  in  the<br />
              range of 100..1000.</p>
<p>       cgroup_nodelete=bool<br />
              Normally  fio  will  delete  the  cgroups  it has created after the job completion.  To override this behavior and to leave<br />
              cgroups around after the job completion, set cgroup_nodelete=1. This can be useful if one wants to inspect  various  cgroup<br />
              files after job completion. Default: false
</p></blockquote>
<p>这里只是粗粗演示下如何用fio按照比例来限制进程使用的IO, 我们来构造下场景：</p>
<p>我们在创建2个1g大小的文件，进行随机的混合读写，一个给500的比例，一个给100的比例，总的比例是1000。那么理论上可以看到A进程可以得到多于B进程5倍的IO能力。</p>
<p>操作如下：</p>
<pre class="brush: bash; title: ; notranslate">
$ cat test.fio
[global]
bs=4k
ioengine=libaio
iodepth=32
direct=1
rw=randrw
rwmixread=90
time_based
runtime=180
cgroup_nodelete=1

[test1]
filename=test1.dat
size=1G
cgroup_weight=500
cgroup=test1

[test2]
filename=test2.dat
size=1G
cgroup_weight=100
cgroup=test2

$ cat /sys/block/sda/queue/scheduler
noop deadline [cfq] 

$ sudo fio test.fio
test1: (g=0): rw=randrw, bs=4K-4K/4K-4K, ioengine=libaio, iodepth=32
test2: (g=0): rw=randrw, bs=4K-4K/4K-4K, ioengine=libaio, iodepth=32
fio 2.0
Starting 2 processes
Jobs: 2 (f=2): [mm] [5.5% done] [618K/90K /s] [151 /22  iops] [eta 02m:51s]
...
</pre>
<p>我们从另外一个终端可以看到IO能力的分配情况：</p>
<pre class="brush: bash; title: ; notranslate">
$ sudo lssubsys -am
cpuset
net_cls
perf_event
cpu /sys/fs/cgroup/cpu
cpuacct /sys/fs/cgroup/cpuacct
memory /sys/fs/cgroup/memory
devices /sys/fs/cgroup/devices
freezer /sys/fs/cgroup/freezer
blkio /sys/fs/cgroup/blkio
$ pgrep -x fio
3837
3839
3840
$ cat /sys/fs/cgroup/blkio/test1/tasks
3839
$ cat /sys/fs/cgroup/blkio/test2/tasks
3840
$ sudo iotop
</pre>
<p><a href="http://blog.yufeng.info/wp-content/uploads/2011/12/Screenshot-at-2011-12-28-162303.png"><img src="http://blog.yufeng.info/wp-content/uploads/2011/12/Screenshot-at-2011-12-28-162303.png" alt="" title="IO分配比例截图" width="658" height="99" class="alignnone size-full wp-image-2004" /></a></p>
<p>差不多是5:1的比例，符合预期。</p>
<p>我们在使用的时候会担心kernel的稳定性，所以用fio能够大压力，长时间的来测试cgroup模块的可靠性，收集数据作为应用的参考。</p>
<p>祝玩得开心！</p>
<div style="margin-top: 0; margin-bottom: 15px; color: #888888; font-size: 80%; font-style: italic">
<p>Post Footer automatically generated by <a href="http://easwy.com/blog/wordpress/wp-posturl/" style="color: #8888FF; text-decoration: underline;">wp-posturl plugin</a> for wordpress.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.yufeng.info/archives/2001/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flash存储设备在淘宝的应用实践(2011年iDevOps系统技术沙龙）</title>
		<link>http://blog.yufeng.info/archives/1997</link>
		<comments>http://blog.yufeng.info/archives/1997#comments</comments>
		<pubDate>Mon, 26 Dec 2011 12:11:53 +0000</pubDate>
		<dc:creator>Yu Feng</dc:creator>
				<category><![CDATA[数据库]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[pcie]]></category>
		<category><![CDATA[ssd]]></category>

		<guid isPermaLink="false">http://blog.yufeng.info/?p=1997</guid>
		<description><![CDATA[原创文章，转载请注明： 转载自Erlang非业余研究 本文链接地址: Flash存储设备在淘宝的应用实践(2011年iDevOps系统技术沙龙） Flash存储设备在淘宝的应用实践 View more presentations from Feng Yu Post Footer automatically generated by wp-posturl plugin for wordpress.]]></description>
			<content:encoded><![CDATA[<div style="margin-top: 15px; font-style: italic">
<p><strong>原创文章，转载请注明：</strong> 转载自<a href="http://blog.yufeng.info/">Erlang非业余研究</a></p>
<p><strong>本文链接地址:</strong> <a href="http://blog.yufeng.info/archives/1997">Flash存储设备在淘宝的应用实践(2011年iDevOps系统技术沙龙）</a></p>
</div>
<div style="width:425px" id="__ss_10689552"> <strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/mryufeng/flash-10689552" title="Flash存储设备在淘宝的应用实践" target="_blank">Flash存储设备在淘宝的应用实践</a></strong> <iframe src="http://www.slideshare.net/slideshow/embed_code/10689552" width="425" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>
<div style="padding:5px 0 12px"> View more <a href="http://www.slideshare.net/" target="_blank">presentations</a> from <a href="http://www.slideshare.net/mryufeng" target="_blank">Feng Yu</a> </div>
</p></div>
<div style="margin-top: 0; margin-bottom: 15px; color: #888888; font-size: 80%; font-style: italic">
<p>Post Footer automatically generated by <a href="http://easwy.com/blog/wordpress/wp-posturl/" style="color: #8888FF; text-decoration: underline;">wp-posturl plugin</a> for wordpress.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.yufeng.info/archives/1997/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SSD在淘宝的应用实践</title>
		<link>http://blog.yufeng.info/archives/1991</link>
		<comments>http://blog.yufeng.info/archives/1991#comments</comments>
		<pubDate>Thu, 22 Dec 2011 15:59:32 +0000</pubDate>
		<dc:creator>Yu Feng</dc:creator>
				<category><![CDATA[数据库]]></category>
		<category><![CDATA[调优]]></category>
		<category><![CDATA[fusionio]]></category>
		<category><![CDATA[ssd]]></category>
		<category><![CDATA[virident]]></category>

		<guid isPermaLink="false">http://blog.yufeng.info/?p=1991</guid>
		<description><![CDATA[原创文章，转载请注明： 转载自Erlang非业余研究 本文链接地址: SSD在淘宝的应用实践 SSD在淘宝的应用实践 View more presentations from Feng Yu Post Footer automatically generated by wp-posturl plugin for wordpress.]]></description>
			<content:encoded><![CDATA[<div style="margin-top: 15px; font-style: italic">
<p><strong>原创文章，转载请注明：</strong> 转载自<a href="http://blog.yufeng.info/">Erlang非业余研究</a></p>
<p><strong>本文链接地址:</strong> <a href="http://blog.yufeng.info/archives/1991">SSD在淘宝的应用实践</a></p>
</div>
<div style="width:425px" id="__ss_10666599"> <strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/mryufeng/ssd-10666599" title="SSD在淘宝的应用实践" target="_blank">SSD在淘宝的应用实践</a></strong> <iframe src="http://www.slideshare.net/slideshow/embed_code/10666599" width="425" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>
<div style="padding:5px 0 12px"> View more <a href="http://www.slideshare.net/" target="_blank">presentations</a> from <a href="http://www.slideshare.net/mryufeng" target="_blank">Feng Yu</a> </div>
</p></div>
<div style="margin-top: 0; margin-bottom: 15px; color: #888888; font-size: 80%; font-style: italic">
<p>Post Footer automatically generated by <a href="http://easwy.com/blog/wordpress/wp-posturl/" style="color: #8888FF; text-decoration: underline;">wp-posturl plugin</a> for wordpress.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.yufeng.info/archives/1991/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>大文件重定向和管道的效率对比</title>
		<link>http://blog.yufeng.info/archives/1981</link>
		<comments>http://blog.yufeng.info/archives/1981#comments</comments>
		<pubDate>Tue, 20 Dec 2011 06:07:18 +0000</pubDate>
		<dc:creator>Yu Feng</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[调优]]></category>
		<category><![CDATA[systemtap]]></category>

		<guid isPermaLink="false">http://blog.yufeng.info/?p=1981</guid>
		<description><![CDATA[原创文章，转载请注明： 转载自Erlang非业余研究 本文链接地址: 大文件重定向和管道的效率对比 微博上的@拉风_zhang提出了个问题： @淘宝褚霸 请教个问题，#1. cat huge_dump.sql &#124; mysql -uroot ；#2. mysql -uroot < huge_dump.sql ；#1效率要高，在linux中通过管道传输 和 < 这种方式有什么差别呢？谢谢！#AskBaye# 这个问题挺有意思的，我的第一反应是： 没比较过，应该是一样的，一个是cat负责打开文件，一个是bash 这种场景在MySQL运维操作里面应该比较多，所以就花了点时间做了个比较和原理上的分析： 我们先构造场景： 首先准备一个程序b.out来模拟mysql对数据的消耗： 编译好再顺手我们的程序功能是正确的：纯消耗流。 再来写个systemtap脚本用来方便观察程序的行为。 这个脚本重点观察几个系统调用的顺序和pipe的读写情况， 然后再准备个419M的大文件huge_dump.sql,在我们几十G内存的机器很容易在内存里放下： 因为这个文件是用bufferio写的，所以它的内容都cache在pagecahce内存里面，不会涉及到磁盘。 好了，场景齐全了，我们接着来比较下二种情况下的速度： 从数字看出来速度有3倍左右的差别了，第二种明显快很多。 是不是有点奇怪？好吧我们来从原来上面分析下，还是继续用数据说话： 这次准备个很小的数据文件，方便观察然后在一个窗口运行stap stap在收集数据了，我们在另外一个窗口运行情况1管道的情况： 我们从systemtap的日志可以看出: bash fork了2个进程，然后execve分别运行cat 和 b.out进程, 这二个进程用pipe通信，数据从由cat从 huge_dump.sql读出，写到pipe,然后b.out从pipe读出处理。 那么再看下情况二重定向的情况: bash fork了一个进程，打开数据文件，然后把文件句柄搞到0句柄上，这个进程execve运行b.out，然后b.out直接读取数据。 现在就非常清楚为什么二种场景速度有3倍的差别： 情况1. 读二次，写一次,外加一个进程上下文切换。 情况二：只读一次。 小结： 越简单的事情，有时候越有意思！ 祝玩得开心！ Post Footer [...]]]></description>
			<content:encoded><![CDATA[<div style="margin-top: 15px; font-style: italic">
<p><strong>原创文章，转载请注明：</strong> 转载自<a href="http://blog.yufeng.info/">Erlang非业余研究</a></p>
<p><strong>本文链接地址:</strong> <a href="http://blog.yufeng.info/archives/1981">大文件重定向和管道的效率对比</a></p>
</div>
<p>微博上的@拉风_zhang提出了个问题：</p>
<blockquote><p>    @淘宝褚霸 请教个问题，#1. cat huge_dump.sql | mysql -uroot ；#2. mysql -uroot < huge_dump.sql ；#1效率要高，在linux中通过管道传输 和 < 这种方式有什么差别呢？谢谢！#AskBaye#
</p></blockquote>
<p>这个问题挺有意思的，我的第一反应是：</p>
<blockquote><p>没比较过，应该是一样的，一个是cat负责打开文件，一个是bash</p></blockquote>
<p>这种场景在MySQL运维操作里面应该比较多，所以就花了点时间做了个比较和原理上的分析：<br />
我们先构造场景：<br />
首先准备一个程序b.out来模拟mysql对数据的消耗：</p>
<pre class="brush: bash; title: ; notranslate">
$ cat b.c
#include &lt;stdio.h&gt;
int main(int argc, char *argv[])
{
  char buf[4096];
  while(fread(buf, sizeof(buf), 1, stdin) &gt; 0);
  return 0;
}
$  gcc  -o b.out b.c
$ ls|./b.out
</pre>
<p>编译好再顺手我们的程序功能是正确的：纯消耗流。</p>
<p>再来写个systemtap脚本用来方便观察程序的行为。</p>
<pre class="brush: bash; title: ; notranslate">
$ cat test.stp
function should_log(){
  return (execname() == &quot;cat&quot; ||
      execname() == &quot;b.out&quot; ||
      execname() == &quot;bash&quot;) ;
}
probe syscall.open,
      syscall.close,
      syscall.read,
      syscall.write,
      syscall.pipe,
      syscall.fork,
      syscall.execve,
      syscall.dup,
      syscall.wait4
{
  if (!should_log()) next;
  printf(&quot;%s -&gt; %s\n&quot;, thread_indent(0), probefunc());
}

probe kernel.function(&quot;pipe_read&quot;),
      kernel.function(&quot;pipe_readv&quot;),
      kernel.function(&quot;pipe_write&quot;),
      kernel.function(&quot;pipe_writev&quot;)
{
  if (!should_log()) next;
  printf(&quot;%s -&gt; %s: file ino %d\n&quot;,  thread_indent(0), probefunc(), __file_ino($filp));
}
probe begin { println(&quot;:~&quot;) }
</pre>
<p>这个脚本重点观察几个系统调用的顺序和pipe的读写情况，</p>
<p>然后再准备个419M的大文件huge_dump.sql,在我们几十G内存的机器很容易在内存里放下：</p>
<pre class="brush: bash; title: ; notranslate">
$ sudo dd if=/dev/urandom of=huge_dump.sql bs=4096 count=102400
102400+0 records in
102400+0 records out
419430400 bytes (419 MB) copied, 63.9886 seconds, 6.6 MB/s
</pre>
<p>因为这个文件是用bufferio写的，所以它的内容都cache在pagecahce内存里面，不会涉及到磁盘。</p>
<p>好了，场景齐全了，我们接着来比较下二种情况下的速度：<br />
<span id="more-1981"></span></p>
<pre class="brush: bash; title: ; notranslate">
$ time (cat huge_dump.sql|./b.out)

real    0m0.596s
user    0m0.001s
sys     0m0.919s

$ time (./b.out &lt;huge_dump.sql)

real    0m0.151s
user    0m0.000s
sys     0m0.147s
</pre>
<p>从数字看出来速度有3倍左右的差别了，第二种明显快很多。</p>
<p>是不是有点奇怪？好吧我们来从原来上面分析下，还是继续用数据说话：</p>
<p>这次准备个很小的数据文件，方便观察然后在一个窗口运行stap</p>
<pre class="brush: bash; title: ; notranslate">
$ echo hello &gt; huge_dump.sql
$ sudo stap test.stp
:~
     0 bash(26570): -&gt; sys_read
     0 bash(26570): -&gt; sys_read
     0 bash(26570): -&gt; sys_write
     0 bash(26570): -&gt; sys_read
     0 bash(26570): -&gt; sys_write
     0 bash(26570): -&gt; sys_close
     0 bash(26570): -&gt; sys_pipe
     0 bash(26570): -&gt; sys_pipe
     0 bash(26570): -&gt; do_fork
     0 bash(26570): -&gt; sys_close
     0 bash(26570): -&gt; sys_close
     0 bash(26570): -&gt; do_fork
     0 bash(13775): -&gt; sys_close
     0 bash(13775): -&gt; sys_read
     0 bash(13775): -&gt; pipe_read: file ino 20906911
     0 bash(13775): -&gt; pipe_readv: file ino 20906911
     0 bash(13776): -&gt; sys_close
     0 bash(13776): -&gt; sys_close
     0 bash(13776): -&gt; sys_close
     0 bash(13776): -&gt; do_execve
     0 bash(26570): -&gt; sys_close
     0 bash(26570): -&gt; sys_close
     0 bash(26570): -&gt; sys_close
     0 bash(13775): -&gt; sys_close
     0 bash(26570): -&gt; sys_wait4
     0 bash(13775): -&gt; sys_close
     0 bash(13775): -&gt; sys_close
     0 b.out(13776): -&gt; sys_close
     0 b.out(13776): -&gt; sys_close
     0 bash(13775): -&gt; do_execve
     0 b.out(13776): -&gt; sys_open
     0 b.out(13776): -&gt; sys_close
     0 b.out(13776): -&gt; sys_open
     0 b.out(13776): -&gt; sys_read
     0 b.out(13776): -&gt; sys_close
     0 cat(13775): -&gt; sys_close
     0 cat(13775): -&gt; sys_close
     0 b.out(13776): -&gt; sys_read
     0 b.out(13776): -&gt; pipe_read: file ino 20906910
     0 b.out(13776): -&gt; pipe_readv: file ino 20906910
     0 cat(13775): -&gt; sys_open
     0 cat(13775): -&gt; sys_close
     0 cat(13775): -&gt; sys_open
     0 cat(13775): -&gt; sys_read
     0 cat(13775): -&gt; sys_close
     0 cat(13775): -&gt; sys_open
     0 cat(13775): -&gt; sys_close
     0 cat(13775): -&gt; sys_open
     0 cat(13775): -&gt; sys_read
     0 cat(13775): -&gt; sys_write
     0 cat(13775): -&gt; pipe_write: file ino 20906910
     0 cat(13775): -&gt; pipe_writev: file ino 20906910
     0 cat(13775): -&gt; sys_read
     0 b.out(13776): -&gt; sys_read
     0 b.out(13776): -&gt; pipe_read: file ino 20906910
     0 b.out(13776): -&gt; pipe_readv: file ino 20906910
     0 cat(13775): -&gt; sys_close
     0 cat(13775): -&gt; sys_close
     0 bash(26570): -&gt; sys_wait4
     0 bash(26570): -&gt; sys_close
     0 bash(26570): -&gt; sys_wait4
     0 bash(26570): -&gt; sys_write
</pre>
<p>stap在收集数据了，我们在另外一个窗口运行情况1管道的情况：</p>
<pre class="brush: bash; title: ; notranslate">
$ cat huge_dump.sql|./b.out
</pre>
<p>我们从systemtap的日志可以看出: bash fork了2个进程，然后execve分别运行cat 和 b.out进程, 这二个进程用pipe通信，数据从由cat从 huge_dump.sql读出，写到pipe,然后b.out从pipe读出处理。</p>
<p>那么再看下情况二重定向的情况:</p>
<pre class="brush: bash; title: ; notranslate">
$ ./b.out &lt; huge_dump.sql 

stap输出：
      0 bash(26570): -&gt; sys_read
     0 bash(26570): -&gt; sys_read
     0 bash(26570): -&gt; sys_write
     0 bash(26570): -&gt; sys_read
     0 bash(26570): -&gt; sys_write
     0 bash(26570): -&gt; sys_close
     0 bash(26570): -&gt; sys_pipe
     0 bash(26570): -&gt; do_fork
     0 bash(28926): -&gt; sys_close
     0 bash(28926): -&gt; sys_read
     0 bash(28926): -&gt; pipe_read: file ino 20920902
     0 bash(28926): -&gt; pipe_readv: file ino 20920902
     0 bash(26570): -&gt; sys_close
     0 bash(26570): -&gt; sys_close
     0 bash(26570): -&gt; sys_wait4
     0 bash(28926): -&gt; sys_close
     0 bash(28926): -&gt; sys_open
     0 bash(28926): -&gt; sys_close
     0 bash(28926): -&gt; do_execve
     0 b.out(28926): -&gt; sys_close
     0 b.out(28926): -&gt; sys_close
     0 b.out(28926): -&gt; sys_open
     0 b.out(28926): -&gt; sys_close
     0 b.out(28926): -&gt; sys_open
     0 b.out(28926): -&gt; sys_read
     0 b.out(28926): -&gt; sys_close
     0 b.out(28926): -&gt; sys_read
     0 b.out(28926): -&gt; sys_read
     0 bash(26570): -&gt; sys_wait4
     0 bash(26570): -&gt; sys_write
     0 bash(26570): -&gt; sys_read
</pre>
<p>bash fork了一个进程，打开数据文件，然后把文件句柄搞到0句柄上，这个进程execve运行b.out，然后b.out直接读取数据。<br />
现在就非常清楚为什么二种场景速度有3倍的差别：<br />
情况1. 读二次，写一次,外加一个进程上下文切换。<br />
情况二：只读一次。</p>
<p>小结： 越简单的事情，有时候越有意思！<br />
祝玩得开心！</p>
<div style="margin-top: 0; margin-bottom: 15px; color: #888888; font-size: 80%; font-style: italic">
<p>Post Footer automatically generated by <a href="http://easwy.com/blog/wordpress/wp-posturl/" style="color: #8888FF; text-decoration: underline;">wp-posturl plugin</a> for wordpress.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.yufeng.info/archives/1981/feed</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Erlang R15B 全新的observer</title>
		<link>http://blog.yufeng.info/archives/1969</link>
		<comments>http://blog.yufeng.info/archives/1969#comments</comments>
		<pubDate>Fri, 16 Dec 2011 19:37:33 +0000</pubDate>
		<dc:creator>Yu Feng</dc:creator>
				<category><![CDATA[Erlang探索]]></category>
		<category><![CDATA[observer]]></category>

		<guid isPermaLink="false">http://blog.yufeng.info/?p=1969</guid>
		<description><![CDATA[原创文章，转载请注明： 转载自Erlang非业余研究 本文链接地址: Erlang R15B 全新的observer 新发布的R15B在亮点里面提到： There is a new GUI tool in the observer application which integrates pman, etop, appmon and tv into one tool. The tool does also contain functions for activating tracing in an easy way. 这个observer完全用wx重新改写过，界面操作速度非常块，整合了几个常用的观察工具，很方便用户，我们来尝鲜下： 上截图： 系统信息: Appmon: Etop: Tv: Pman: 界面看起来很清爽！ 祝玩得开心！ Post Footer automatically generated by wp-posturl [...]]]></description>
			<content:encoded><![CDATA[<div style="margin-top: 15px; font-style: italic">
<p><strong>原创文章，转载请注明：</strong> 转载自<a href="http://blog.yufeng.info/">Erlang非业余研究</a></p>
<p><strong>本文链接地址:</strong> <a href="http://blog.yufeng.info/archives/1969">Erlang R15B 全新的observer</a></p>
</div>
<p>新发布的R15B在<a href="http://www.erlang.org/news/28">亮点</a>里面提到： </p>
<blockquote><p>There is a new GUI tool in the observer application which integrates pman, etop, appmon and tv into one tool. The tool does also contain functions for activating tracing in an easy way.</p></blockquote>
<p>这个observer完全用wx重新改写过，界面操作速度非常块，整合了几个常用的观察工具，很方便用户，我们来尝鲜下：</p>
<pre class="brush: bash; title: ; notranslate">
$ erl
Erlang R15B (erts-5.9) 1 [smp:2:2] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.9  (abort with ^G)
1&gt; observer:start().
ok
</pre>
<p>上截图：<br />
<span id="more-1969"></span><br />
系统信息:<br />
<a href="http://blog.yufeng.info/wp-content/uploads/2011/12/Picture-561.png"><img src="http://blog.yufeng.info/wp-content/uploads/2011/12/Picture-561.png" alt="" title="Picture 561" width="851" height="600" class="alignnone size-full wp-image-1970" /></a></p>
<p>Appmon:<br />
<a href="http://blog.yufeng.info/wp-content/uploads/2011/12/Picture-562.png"><img src="http://blog.yufeng.info/wp-content/uploads/2011/12/Picture-562.png" alt="" title="Picture 562" width="852" height="597" class="alignnone size-full wp-image-1971" /></a></p>
<p>Etop:<br />
<a href="http://blog.yufeng.info/wp-content/uploads/2011/12/Picture-563.png"><img src="http://blog.yufeng.info/wp-content/uploads/2011/12/Picture-563.png" alt="" title="Picture 563" width="851" height="603" class="alignnone size-full wp-image-1972" /></a></p>
<p>Tv:<br />
<a href="http://blog.yufeng.info/wp-content/uploads/2011/12/Picture-564.png"><img src="http://blog.yufeng.info/wp-content/uploads/2011/12/Picture-564.png" alt="" title="Picture 564" width="853" height="603" class="alignnone size-full wp-image-1973" /></a></p>
<p>Pman:<br />
<a href="http://blog.yufeng.info/wp-content/uploads/2011/12/Picture-565.png"><img src="http://blog.yufeng.info/wp-content/uploads/2011/12/Picture-565.png" alt="" title="Picture 565" width="856" height="603" class="alignnone size-full wp-image-1974" /></a></p>
<p>界面看起来很清爽！</p>
<p>祝玩得开心！</p>
<div style="margin-top: 0; margin-bottom: 15px; color: #888888; font-size: 80%; font-style: italic">
<p>Post Footer automatically generated by <a href="http://easwy.com/blog/wordpress/wp-posturl/" style="color: #8888FF; text-decoration: underline;">wp-posturl plugin</a> for wordpress.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.yufeng.info/archives/1969/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>slabtop简单的用途</title>
		<link>http://blog.yufeng.info/archives/1960</link>
		<comments>http://blog.yufeng.info/archives/1960#comments</comments>
		<pubDate>Thu, 15 Dec 2011 08:06:49 +0000</pubDate>
		<dc:creator>Yu Feng</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[工具介绍]]></category>
		<category><![CDATA[调优]]></category>
		<category><![CDATA[slabtop]]></category>

		<guid isPermaLink="false">http://blog.yufeng.info/?p=1960</guid>
		<description><![CDATA[原创文章，转载请注明： 转载自Erlang非业余研究 本文链接地址: slabtop简单的用途 我们知道内核的模块在分配资源的时候，为了提高效率和资源的利用率，都是透过slab来分配的。我们通过slab的信息，再配合源码能粗粗了解系统的运行情况，比如说什么资源有没有不正常的多，或者什么资源有没有泄漏。 linux系统透过/proc/slabinfo来向用户暴露slab的使用情况的,我们来看下： 其实还有更好的查看工具：slabtop很直观的可以看到slab使用情况和汇总，上图： 很清晰的为性能调优和trouble shoot提供一个参考面！ 祝玩得开心！ Post Footer automatically generated by wp-posturl plugin for wordpress.]]></description>
			<content:encoded><![CDATA[<div style="margin-top: 15px; font-style: italic">
<p><strong>原创文章，转载请注明：</strong> 转载自<a href="http://blog.yufeng.info/">Erlang非业余研究</a></p>
<p><strong>本文链接地址:</strong> <a href="http://blog.yufeng.info/archives/1960">slabtop简单的用途</a></p>
</div>
<p>我们知道内核的模块在分配资源的时候，为了提高效率和资源的利用率，都是透过slab来分配的。我们通过slab的信息，再配合源码能粗粗了解系统的运行情况，比如说什么资源有没有不正常的多，或者什么资源有没有泄漏。</p>
<p>linux系统透过/proc/slabinfo来向用户暴露slab的使用情况的,我们来看下：</p>
<pre class="brush: bash; title: ; notranslate">
$ head /proc/slabinfo
slabinfo - version: 2.0
# name            &lt;active_objs&gt; &lt;num_objs&gt; &lt;objsize&gt; &lt;objperslab&gt; &lt;pagesperslab&gt; : tunables &lt;batchcount&gt; &lt;limit&gt; &lt;sharedfactor&gt; : slabdata &lt;active_slabs&gt; &lt;num_slabs&gt; &lt;sharedavail&gt;
msi_cache              2      2   3840    1    1 : tunables   24   12    8 : slabdata      2      2      0
ip_fib_alias          11    226     16  226    1 : tunables  120   60    8 : slabdata      1      1      0
ip_fib_hash           11    119     32  119    1 : tunables  120   60    8 : slabdata      1      1      0
dm_mirror            100    105   1052    7    2 : tunables   24   12    8 : slabdata     15     15      0
dm_mpath               0      0   1052    7    2 : tunables   24   12    8 : slabdata      0      0      0
dm_tio                 0      0     16  226    1 : tunables  120   60    8 : slabdata      0      0      0
dm_io                  0      0     20  185    1 : tunables  120   60    8 : slabdata      0      0      0
dm-bvec-(256)          0      0   3072    2    2 : tunables   24   12    8 : slabdata      0      0      0
...
</pre>
<p>其实还有更好的查看工具：slabtop很直观的可以看到slab使用情况和汇总，上图：</p>
<p><a href="http://blog.yufeng.info/wp-content/uploads/2011/12/slabtop.jpg"><img src="http://blog.yufeng.info/wp-content/uploads/2011/12/slabtop.jpg" alt="" title="slabtop" width="602" height="343" class="alignnone size-full wp-image-1961" /></a></p>
<p>很清晰的为性能调优和trouble shoot提供一个参考面！</p>
<p>祝玩得开心！</p>
<div style="margin-top: 0; margin-bottom: 15px; color: #888888; font-size: 80%; font-style: italic">
<p>Post Footer automatically generated by <a href="http://easwy.com/blog/wordpress/wp-posturl/" style="color: #8888FF; text-decoration: underline;">wp-posturl plugin</a> for wordpress.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.yufeng.info/archives/1960/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Lockless Memory Allocator试用记</title>
		<link>http://blog.yufeng.info/archives/1951</link>
		<comments>http://blog.yufeng.info/archives/1951#comments</comments>
		<pubDate>Wed, 14 Dec 2011 07:28:11 +0000</pubDate>
		<dc:creator>Yu Feng</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[调优]]></category>
		<category><![CDATA[libllalloc]]></category>
		<category><![CDATA[Lockless]]></category>
		<category><![CDATA[内存分配器]]></category>

		<guid isPermaLink="false">http://blog.yufeng.info/?p=1951</guid>
		<description><![CDATA[原创文章，转载请注明： 转载自Erlang非业余研究 本文链接地址: Lockless Memory Allocator试用记 昨天@淘宝雕梁 同学推荐了无锁的内存分配器，上网站粗粗的了解了下，这家叫Lockless的公司主要有2个产品： Lockless MPI 和 Lockless Memory Allocator， 我对内存分配器比较感兴趣，它对高性能服务器的影响还是非常大的,特别是mysql这样的服务器，看它的文档对性能的提升好像比较明显。 我们重点来了解下 Lockless Memory Allocator: The Lockless Memory Allocator is downloadable under the GPL 3.0 License. 官网强调的特性： Multithread Optimized The Lockless memory allocator uses lock-free techniques to minimize latency and memory contention. This provides optimal scalability as the number of threads [...]]]></description>
			<content:encoded><![CDATA[<div style="margin-top: 15px; font-style: italic">
<p><strong>原创文章，转载请注明：</strong> 转载自<a href="http://blog.yufeng.info/">Erlang非业余研究</a></p>
<p><strong>本文链接地址:</strong> <a href="http://blog.yufeng.info/archives/1951">Lockless Memory Allocator试用记</a></p>
</div>
<p>昨天@淘宝雕梁 同学推荐了无锁的内存分配器，上<a href="http://locklessinc.com/">网站</a>粗粗的了解了下，这家叫Lockless的公司主要有2个产品：<br />
Lockless MPI 和 Lockless Memory Allocator， 我对内存分配器比较感兴趣，它对高性能服务器的影响还是非常大的,特别是mysql这样的服务器，看它的文档对性能的提升好像比较明显。</p>
<p>我们重点来了解下 Lockless Memory Allocator:</p>
<p>The Lockless Memory Allocator is downloadable under the GPL 3.0 License.</p>
<p>官网强调的特性：</p>
<blockquote><p>Multithread Optimized<br />
The Lockless memory allocator uses lock-free techniques to minimize latency and memory contention. This provides optimal scalability as the number of threads in your application increases. Per-thread data is used to reduce bus communication overhead. This results in thread-local allocations and frees not requiring any synchronization overhead in most cases.</p></blockquote>
<p>官网做的和主流的几种分配器的性能比较：<br />
<a href="http://blog.yufeng.info/wp-content/uploads/2011/12/plot_llgchdtc.png"><img src="http://blog.yufeng.info/wp-content/uploads/2011/12/plot_llgchdtc.png" alt="" title="benchmark" width="800" height="600" class="alignnone size-full wp-image-1952" /></a><br />
详细的bechmark见<a href="http://locklessinc.com/benchmarks_allocator.shtml">这里</a>，看上去让人挺印象深刻的。</p>
<p>代码在这里下载 http://locklessinc.com/downloads/， 支持32位和64位的Linux, 安装文档在<a href="http://locklessinc.com/install_allocator.shtml">这里</a></p>
<p>我们来尝鲜实验下：</p>
<pre class="brush: bash; title: ; notranslate">
$  wget http://locklessinc.com/downloads/lockless_allocator_src.tgz
$ tar xzf lockless_allocator_src.tgz
$ cd lockless_allocator
$ gcc -v
Using built-in specs.
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux
Thread model: posix
gcc version 4.4.5 20110214 (Red Hat 4.4.5-6) (GCC) 

$ make
/bin/sh -ec 'gcc -MM  ll_alloc.c | sed -n &quot;H;$ {g;s@.*:\(.*\)@ll_alloc.c := \$\(wildcard\1\)\nll_alloc.o ll_alloc.c.d: $\(ll_alloc.c\)@;p}&quot; &gt; ll_alloc.c.d'
cc ll_alloc.c -fomit-frame-pointer -Wcast-qual -Wmissing-format-attribute -Wlogical-op -Wstrict-aliasing -Wsign-compare -Wdeclaration-after-statement -Wnested-externs -Wdisabled-optimization -Winline -Wundef -Wimplicit -Wunused -Wfloat-equal -Winit-self -Wformat=2 -Wswitch -Wsequence-point -Wparentheses -Wimplicit -Wchar-subscripts -Wredundant-decls -Wstrict-prototypes -Wbad-function-cast -Wpointer-arith -Wwrite-strings -Wno-long-long -Wmissing-declarations -Wmissing-prototypes -Wextra -Wall -pedantic -ggdb3 -std=gnu99 -O3  -fPIC -pthread -c -o libllalloc.o
strip -g libllalloc.o
ar rcs libllalloc.a libllalloc.o
ranlib libllalloc.a
cc ll_alloc.c -fomit-frame-pointer -Wcast-qual -Wmissing-format-attribute -Wlogical-op -Wstrict-aliasing -Wsign-compare -Wdeclaration-after-statement -Wnested-externs -Wdisabled-optimization -Winline -Wundef -Wimplicit -Wunused -Wfloat-equal -Winit-self -Wformat=2 -Wswitch -Wsequence-point -Wparentheses -Wimplicit -Wchar-subscripts -Wredundant-decls -Wstrict-prototypes -Wbad-function-cast -Wpointer-arith -Wwrite-strings -Wno-long-long -Wmissing-declarations -Wmissing-prototypes -Wextra -Wall -pedantic -ggdb3 -std=gnu99 -O3  -shared -fpic -Wl,-soname,libllalloc.so.1.3 -Wl,-z,interpose -o libllalloc.so.1.3
strip libllalloc.so.1.3

$ ls libllalloc.*
libllalloc.a  libllalloc.o  libllalloc.so.1.3

$ LD_PRELOAD=./libllalloc.so.1.3  erl
Erlang R14B04 (erts-5.8.5) 1 [64-bit] [smp:16:16] [rq:16] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.8.5  (abort with ^G)
1&gt; 

#另外一个终端确认libllalloc.so.1.3在使用
$ lsof  -c beam.smp
COMMAND   PID           USER   FD      TYPE DEVICE     SIZE    NODE NAME
beam.smp 8458          chuba  txt       REG    8,5  2344032 3775338 /usr/local/lib/erlang/erts-5.8.5/bin/beam.smp
...
beam.smp 8458          chuba  mem       REG    8,6    40384  195304 /home/chuba/lockless_allocator/libllalloc.so.1.3
...
</pre>
<p>这里面有个问题： 编译的时候需要的gcc版本比较高，gcc version 4.1.2 20080704 (Red Hat 4.1.2-46)编译不过。<br />
之前tcmalloc就没通过erl的使用，因为erlang内部的指针的后4位被用了，如果分配器不遵守16字节对齐，就会出问题。</p>
<p>看了代码实现的也很简单，代码质量也一般，不知道具体的性能如何，后续找个案例benchmark下！<br />
未完待续！</p>
<p>祝玩得开心！</p>
<div style="margin-top: 0; margin-bottom: 15px; color: #888888; font-size: 80%; font-style: italic">
<p>Post Footer automatically generated by <a href="http://easwy.com/blog/wordpress/wp-posturl/" style="color: #8888FF; text-decoration: underline;">wp-posturl plugin</a> for wordpress.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.yufeng.info/archives/1951/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

