﻿<?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>P.Linux Laboratory &#187; Linux</title>
	<atom:link href="http://www.penglixun.com/tag/linux/feed" rel="self" type="application/rss+xml" />
	<link>http://www.penglixun.com</link>
	<description>MySQL DBA &#38; Linux SA</description>
	<lastBuildDate>Sun, 22 Jan 2012 16:34:39 +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>一个InnoDB性能超过Oracle的调优Case</title>
		<link>http://www.penglixun.com/tech/database/case_about_innodb_faster_than_oracle.html</link>
		<comments>http://www.penglixun.com/tech/database/case_about_innodb_faster_than_oracle.html#comments</comments>
		<pubDate>Sun, 22 Jan 2012 16:00:59 +0000</pubDate>
		<dc:creator>P.Linux</dc:creator>
				<category><![CDATA[数据库]]></category>
		<category><![CDATA[AIO]]></category>
		<category><![CDATA[InnoDB]]></category>
		<category><![CDATA[Kernel]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Percona]]></category>
		<category><![CDATA[XtraDB]]></category>

		<guid isPermaLink="false">http://www.penglixun.com/?p=1232</guid>
		<description><![CDATA[年前抽空到兄弟公司支援了一下Oracle迁移MySQL的测试，本想把MySQL调优到接近Oracle的性能即可，但经过 @何_登成 @淘宝丁奇 @淘宝褚霸 @淘伯松 诸位大牛的指导和帮助（排名不分先后，仅按第一次... ]]></description>
			<content:encoded><![CDATA[<p>年前抽空到兄弟公司支援了一下Oracle迁移MySQL的测试，本想把MySQL调优到接近Oracle的性能即可，但经过 @何_登成 @淘宝丁奇 @淘宝褚霸 @淘伯松 诸位大牛的指导和帮助（排名不分先后，仅按第一次为此CASE而骚扰的时间排序），不断修正方案，最终获得了比Oracle更好的性能，虽然是个特殊场景，但是我觉得意义是很广泛的，值得参考，遂记录于此。<br />
所有涉及表结构和具体业务模型的部分全部略去，也请勿咨询，不能透露，敬请谅解。</p>
<h2>一、测试模型：</h2>
<p>包含12张业务表，每个事务包含12个<acronym title="Structured Query Language">SQL</acronym>，每个<acronym title="Structured Query Language">SQL</acronym>向一张表做INSERT，做完12个<acronym title="Structured Query Language">SQL</acronym>即完成一个事务。</p>
<p>用一个C <acronym title="Application Programming Interface">API</acronym>编写的程序连接MySQL，不断执行如下操作</p>
<blockquote><p>开始事务：START TRANSACTION;<br />
每张表插入一行：INSERT INTO xxx VALUES (val1,val2,…); #一共12次<br />
提交事务：COMMIT;</p></blockquote>
<p>通过一个Shell脚本来启动32个测试程序并发测试</p>
<h2>二、测试环境：</h2>
<h3>1. 机型：</h3>
<p>R510<br />
CPU：Intel(R) Xeon(R) CPU E5645 @ 2.40GHz 双路24线程<br />
内存：6 * 8G 48G<br />
存储：FusionIO 320G MLC</p>
<p>R910<br />
CPU：Intel(R) Xeon(R) CPU E7530 @ 1.87GHz 四路48线程<br />
内存：32* 4G 128G<br />
存储：FusionIO 640G MLC</p>
<h3>2. Linux配置：</h3>
<p>单实例启动数据库：/boot/grub/menu.lst修改kernel启动参数增加numa=off<br />
多实例启动数据库：numactl &#8211;cpunodebind=$BIND_NO &#8211;localalloc $MYSQLD</p>
<p>RHEL 5.4 with 2.6.18内置内核<br />
RHEL 6.1 with 2.6.32淘宝版内核</p>
<p>fs.aio-max-nr = 1048576 #调整系统允许的最大异步IO队列长度<br />
vm.nr_hugepages = 18000 #大页页数<br />
vm.hugetlb_shm_group = 601 #允许使用大页的用户id，即mysql用户<br />
vm.swappiness = 0 #不倾向使用SWAP</p>
<h3>3. FusionIO配置：</h3>
<p>启动配置：<br />
/etc/modprobe.d/iomemory-vsl.conf<br />
options iomemory-vsl use_workqueue=0 # 忽略Linux IO调度<br />
options iomemory-vsl disable-msi=0 # 开启MSI中断<br />
options iomemory-vsl use_large_pcie_rx_buffer=1 # 打开PCIE缓冲<br />
options iomemory-vsl preallocate_memory=SN号 # 预分配管理内存</p>
<p>格式化配置：<br />
fio-format -b 4K /dev/fct0 # 格式化设备为4K匹配NAND芯片页大小<br />
mkfs.xfs -f -i attr=2 -l lazy-count=1,sectsize=4096 -b size=4096 -d sectsize=4096 -L data /dev/fioa # 调整XFS与FusionIO 4K页匹配，比较激进，需要更多稳定性测试认为这组参数充分安全</p>
<p>mount配置：<br />
/dev/fioa on /data type xfs (rw,noatime,nodiratime,noikeep,nobarrier,allocsize=100M,attr2,largeio,inode64,swalloc) # FusionIO的逻辑Block是100M，所以设为100M的预扩展</p>
<h3>4. MySQL版本和通用配置：</h3>
<p>Percona 5.1.60-13.1 原版<br />
Percona 5.1.60-13.1 修改版<br />
* 允许自定义InnoDB AIO队列申请长度 (5.5_change_aio_io_limit.patch)<br />
Percona 5.5.19-24.0 原版<br />
* 允许innodb_flush_neighbor_pages=2来合并真正相邻的脏页合并<br />
* Group Commit<br />
Percona 5.5.18-23.0 修改版<br />
* 允许自定义InnoDB AIO队列申请长度 (5.5_change_aio_io_limit.patch)<br />
* 允许预先扩展数据文件 (5.5_innodb_extent_tablespace.patch，@淘宝丁奇 贡献)<br />
* Group Cimmit</p>
<p>innodb_buffer_pool_size=20G<br />
sync_binlog=1<br />
innodb_flush_log_at_trx_commit=1</p>
<p>测试并发：32</p>
<h3>5. 修改补丁</h3>
<p>#cat 5.5_change_aio_io_limit.patch</p>

<div class="wp_codebox"><table><tr id="p12323"><td class="code" id="p1232code3"><pre class="cpp" style="font-family:monospace;"><span style="color: #000040;">---</span> Percona<span style="color: #000040;">-</span>Server<span style="color: #000040;">-</span>5.5.18<span style="color: #000040;">-</span><span style="color:#800080;">23.0</span><span style="color: #000040;">/</span>storage<span style="color: #000040;">/</span>innobase<span style="color: #000040;">/</span>handler<span style="color: #000040;">/</span>ha_innodb.<span style="color: #007788;">cc</span>	<span style="color: #0000dd;">2011</span><span style="color: #000040;">-</span><span style="color: #0000dd;">12</span><span style="color: #000040;">-</span><span style="color: #0000dd;">20</span> <span style="color: #208080;">06</span><span style="color: #008080;">:</span><span style="color: #0000dd;">38</span><span style="color: #008080;">:</span><span style="color:#800080;">58.000000000</span> <span style="color: #000040;">+</span><span style="color:#800080;">0800</span>
<span style="color: #000040;">+++</span> Percona<span style="color: #000040;">-</span>Server<span style="color: #000040;">-</span>5.5.18<span style="color: #000040;">-</span><span style="color:#800080;">23.0</span><span style="color: #000040;">-</span>debug<span style="color: #000040;">/</span>storage<span style="color: #000040;">/</span>innobase<span style="color: #000040;">/</span>handler<span style="color: #000040;">/</span>ha_innodb.<span style="color: #007788;">cc</span>	<span style="color: #0000dd;">2012</span><span style="color: #000040;">-</span><span style="color: #208080;">01</span><span style="color: #000040;">-</span><span style="color: #0000dd;">17</span> <span style="color: #0000dd;">10</span><span style="color: #008080;">:</span><span style="color: #0000dd;">13</span><span style="color: #008080;">:</span><span style="color:#800080;">41.000000000</span> <span style="color: #000040;">+</span><span style="color:#800080;">0800</span>
@@ <span style="color: #000040;">-</span><span style="color: #0000dd;">146</span>,<span style="color: #0000dd;">6</span> <span style="color: #000040;">+</span><span style="color: #0000dd;">146</span>,<span style="color: #0000dd;">7</span> @@
 <span style="color: #0000ff;">static</span> ulong innobase_commit_concurrency <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
 <span style="color: #0000ff;">static</span> ulong innobase_read_io_threads<span style="color: #008080;">;</span>
 <span style="color: #0000ff;">static</span> ulong innobase_write_io_threads<span style="color: #008080;">;</span>
<span style="color: #000040;">+</span><span style="color: #0000ff;">static</span> ulong innobase_aio_pending_ios_per_thread<span style="color: #008080;">;</span> <span style="color: #666666;">// Change AIO io_limit By P.Linux</span>
 <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">long</span> innobase_buffer_pool_instances <span style="color: #000080;">=</span> <span style="color: #0000dd;">1</span><span style="color: #008080;">;</span>
&nbsp;
 <span style="color: #0000ff;">static</span> ulong innobase_page_size<span style="color: #008080;">;</span>
@@ <span style="color: #000040;">-</span><span style="color: #0000dd;">2870</span>,<span style="color: #0000dd;">6</span> <span style="color: #000040;">+</span><span style="color: #0000dd;">2871</span>,<span style="color: #0000dd;">7</span> @@
 	srv_n_file_io_threads <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span>ulint<span style="color: #008000;">&#41;</span> innobase_file_io_threads<span style="color: #008080;">;</span>
 	srv_n_read_io_threads <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span>ulint<span style="color: #008000;">&#41;</span> innobase_read_io_threads<span style="color: #008080;">;</span>
 	srv_n_write_io_threads <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span>ulint<span style="color: #008000;">&#41;</span> innobase_write_io_threads<span style="color: #008080;">;</span>
<span style="color: #000040;">+</span>	srv_n_aio_pending_ios_per_thread <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span>ulint<span style="color: #008000;">&#41;</span> innobase_aio_pending_ios_per_thread<span style="color: #008080;">;</span>
&nbsp;
 	srv_read_ahead <span style="color: #000040;">&amp;</span>amp<span style="color: #008080;">;</span><span style="color: #000080;">=</span> <span style="color: #0000dd;">3</span><span style="color: #008080;">;</span>
 	srv_adaptive_flushing_method <span style="color: #000040;">%</span><span style="color: #000080;">=</span> <span style="color: #0000dd;">3</span><span style="color: #008080;">;</span>
@@ <span style="color: #000040;">-</span><span style="color: #0000dd;">12282</span>,<span style="color: #0000dd;">6</span> <span style="color: #000040;">+</span><span style="color: #0000dd;">12284</span>,<span style="color: #0000dd;">11</span> @@
   <span style="color: #FF0000;">&quot;Number of background write I/O threads in InnoDB.&quot;</span>,
   <span style="color: #0000ff;">NULL</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #0000dd;">4</span>, <span style="color: #0000dd;">1</span>, <span style="color: #0000dd;">64</span>, <span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #000040;">+</span><span style="color: #0000ff;">static</span> MYSQL_SYSVAR_ULONG<span style="color: #008000;">&#40;</span>aio_pending_ios_per_thread, innobase_aio_pending_ios_per_thread,
<span style="color: #000040;">+</span>  PLUGIN_VAR_RQCMDARG <span style="color: #000040;">|</span> PLUGIN_VAR_READONLY,
<span style="color: #000040;">+</span>  <span style="color: #FF0000;">&quot;Number of AIO pending IOS per-thread in InnoDB.&quot;</span>,
<span style="color: #000040;">+</span>  <span style="color: #0000ff;">NULL</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #0000dd;">4</span>, <span style="color: #0000dd;">32</span>, <span style="color: #0000dd;">4096</span>, <span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #000040;">+</span>
 <span style="color: #0000ff;">static</span> MYSQL_SYSVAR_LONG<span style="color: #008000;">&#40;</span>force_recovery, innobase_force_recovery,
   PLUGIN_VAR_RQCMDARG <span style="color: #000040;">|</span> PLUGIN_VAR_READONLY,
   <span style="color: #FF0000;">&quot;Helps to save your data in case the disk image of the database becomes corrupt.&quot;</span>,
<span style="color: #000040;">---</span> Percona<span style="color: #000040;">-</span>Server<span style="color: #000040;">-</span>5.5.18<span style="color: #000040;">-</span><span style="color:#800080;">23.0</span><span style="color: #000040;">/</span>storage<span style="color: #000040;">/</span>innobase<span style="color: #000040;">/</span>srv<span style="color: #000040;">/</span>srv0srv.<span style="color: #007788;">c</span>	<span style="color: #0000dd;">2011</span><span style="color: #000040;">-</span><span style="color: #0000dd;">12</span><span style="color: #000040;">-</span><span style="color: #0000dd;">20</span> <span style="color: #208080;">06</span><span style="color: #008080;">:</span><span style="color: #0000dd;">38</span><span style="color: #008080;">:</span><span style="color:#800080;">57.000000000</span> <span style="color: #000040;">+</span><span style="color:#800080;">0800</span>
<span style="color: #000040;">+++</span> Percona<span style="color: #000040;">-</span>Server<span style="color: #000040;">-</span>5.5.18<span style="color: #000040;">-</span><span style="color:#800080;">23.0</span><span style="color: #000040;">-</span>debug<span style="color: #000040;">/</span>storage<span style="color: #000040;">/</span>innobase<span style="color: #000040;">/</span>srv<span style="color: #000040;">/</span>srv0srv.<span style="color: #007788;">c</span>	<span style="color: #0000dd;">2012</span><span style="color: #000040;">-</span><span style="color: #208080;">01</span><span style="color: #000040;">-</span><span style="color: #0000dd;">17</span> <span style="color: #0000dd;">10</span><span style="color: #008080;">:</span><span style="color: #0000dd;">23</span><span style="color: #008080;">:</span><span style="color:#800080;">35.000000000</span> <span style="color: #000040;">+</span><span style="color:#800080;">0800</span>
@@ <span style="color: #000040;">-</span><span style="color: #0000dd;">242</span>,<span style="color: #0000dd;">6</span> <span style="color: #000040;">+</span><span style="color: #0000dd;">242</span>,<span style="color: #0000dd;">7</span> @@
 UNIV_INTERN ulint	srv_n_file_io_threads	<span style="color: #000080;">=</span> ULINT_MAX<span style="color: #008080;">;</span>
 UNIV_INTERN ulint	srv_n_read_io_threads	<span style="color: #000080;">=</span> ULINT_MAX<span style="color: #008080;">;</span>
 UNIV_INTERN ulint	srv_n_write_io_threads	<span style="color: #000080;">=</span> ULINT_MAX<span style="color: #008080;">;</span>
<span style="color: #000040;">+</span>UNIV_INTERN ulint   srv_n_aio_pending_ios_per_thread <span style="color: #000080;">=</span> ULINT_MAX<span style="color: #008080;">;</span> <span style="color: #666666;">// Change AIO io_limit By P.Linux</span>
&nbsp;
 <span style="color: #ff0000; font-style: italic;">/* Switch to enable random read ahead. */</span>
 UNIV_INTERN my_bool	srv_random_read_ahead	<span style="color: #000080;">=</span> FALSE<span style="color: #008080;">;</span>
<span style="color: #000040;">---</span> Percona<span style="color: #000040;">-</span>Server<span style="color: #000040;">-</span>5.5.18<span style="color: #000040;">-</span><span style="color:#800080;">23.0</span><span style="color: #000040;">/</span>storage<span style="color: #000040;">/</span>innobase<span style="color: #000040;">/</span>srv<span style="color: #000040;">/</span>srv0start.<span style="color: #007788;">c</span>	<span style="color: #0000dd;">2011</span><span style="color: #000040;">-</span><span style="color: #0000dd;">12</span><span style="color: #000040;">-</span><span style="color: #0000dd;">20</span> <span style="color: #208080;">06</span><span style="color: #008080;">:</span><span style="color: #0000dd;">38</span><span style="color: #008080;">:</span><span style="color:#800080;">57.000000000</span> <span style="color: #000040;">+</span><span style="color:#800080;">0800</span>
<span style="color: #000040;">+++</span> Percona<span style="color: #000040;">-</span>Server<span style="color: #000040;">-</span>5.5.18<span style="color: #000040;">-</span><span style="color:#800080;">23.0</span><span style="color: #000040;">-</span>debug<span style="color: #000040;">/</span>storage<span style="color: #000040;">/</span>innobase<span style="color: #000040;">/</span>srv<span style="color: #000040;">/</span>srv0start.<span style="color: #007788;">c</span>	<span style="color: #0000dd;">2012</span><span style="color: #000040;">-</span><span style="color: #208080;">01</span><span style="color: #000040;">-</span><span style="color: #0000dd;">17</span> <span style="color: #0000dd;">10</span><span style="color: #008080;">:</span><span style="color: #0000dd;">25</span><span style="color: #008080;">:</span><span style="color:#800080;">12.000000000</span> <span style="color: #000040;">+</span><span style="color:#800080;">0800</span>
@@ <span style="color: #000040;">-</span><span style="color: #0000dd;">1475</span>,<span style="color: #0000dd;">14</span> <span style="color: #000040;">+</span><span style="color: #0000dd;">1475</span>,<span style="color: #0000dd;">16</span> @@
&nbsp;
 	ut_a<span style="color: #008000;">&#40;</span>srv_n_file_io_threads</pre></td></tr></table></div>

<p>#cat 5.5_innodb_extent_tablespace.patch</p>

<div class="wp_codebox"><table><tr id="p12324"><td class="code" id="p1232code4"><pre class="cpp" style="font-family:monospace;"><span style="color: #000040;">---</span> Percona<span style="color: #000040;">-</span>Server<span style="color: #000040;">-</span>5.5.18<span style="color: #000040;">-</span><span style="color:#800080;">23.0</span><span style="color: #000040;">/</span>sql<span style="color: #000040;">/</span>sql_yacc.<span style="color: #007788;">yy</span>	<span style="color: #0000dd;">2011</span><span style="color: #000040;">-</span><span style="color: #0000dd;">12</span><span style="color: #000040;">-</span><span style="color: #0000dd;">20</span> <span style="color: #208080;">06</span><span style="color: #008080;">:</span><span style="color: #0000dd;">38</span><span style="color: #008080;">:</span><span style="color:#800080;">58.000000000</span> <span style="color: #000040;">+</span><span style="color:#800080;">0800</span>
<span style="color: #000040;">+++</span> Percona<span style="color: #000040;">-</span>Server<span style="color: #000040;">-</span>5.5.18<span style="color: #000040;">-</span><span style="color:#800080;">23.0</span><span style="color: #000040;">-</span>debug<span style="color: #000040;">/</span>sql<span style="color: #000040;">/</span>sql_yacc.<span style="color: #007788;">yy</span>	<span style="color: #0000dd;">2012</span><span style="color: #000040;">-</span><span style="color: #208080;">01</span><span style="color: #000040;">-</span><span style="color: #0000dd;">17</span> <span style="color: #0000dd;">14</span><span style="color: #008080;">:</span><span style="color: #0000dd;">45</span><span style="color: #008080;">:</span><span style="color:#800080;">47.000000000</span> <span style="color: #000040;">+</span><span style="color:#800080;">0800</span>
@@ <span style="color: #000040;">-</span><span style="color: #0000dd;">3878</span>,<span style="color: #0000dd;">6</span> <span style="color: #000040;">+</span><span style="color: #0000dd;">3878</span>,<span style="color: #0000dd;">14</span> @@
           <span style="color: #008000;">&#123;</span> 
             Lex<span style="color: #000040;">-</span><span style="color: #000040;">&amp;</span>gt<span style="color: #008080;">;</span>alter_tablespace_info<span style="color: #000040;">-</span><span style="color: #000040;">&amp;</span>gt<span style="color: #008080;">;</span>ts_alter_tablespace_type<span style="color: #000080;">=</span> ALTER_TABLESPACE_DROP_FILE<span style="color: #008080;">;</span> 
           <span style="color: #008000;">&#125;</span>
<span style="color: #000040;">+</span>        <span style="color: #ff0000; font-style: italic;">/* innodb_extent_tablespace By P.Linux */</span>
<span style="color: #000040;">+</span>        <span style="color: #000040;">|</span> tablespace_name
<span style="color: #000040;">+</span>          SET
<span style="color: #000040;">+</span>          opt_ts_extent_size
<span style="color: #000040;">+</span>          <span style="color: #008000;">&#123;</span>
<span style="color: #000040;">+</span>            Lex<span style="color: #000040;">-</span><span style="color: #000040;">&amp;</span>gt<span style="color: #008080;">;</span>alter_tablespace_info<span style="color: #000040;">-</span><span style="color: #000040;">&amp;</span>gt<span style="color: #008080;">;</span>ts_alter_tablespace_type<span style="color: #000080;">=</span> ALTER_TABLESPACE_ALTER_FILE<span style="color: #008080;">;</span>
<span style="color: #000040;">+</span>          <span style="color: #008000;">&#125;</span>
<span style="color: #000040;">+</span>        <span style="color: #ff0000; font-style: italic;">/* End */</span>
         <span style="color: #008080;">;</span>
&nbsp;
 logfile_group_info<span style="color: #008080;">:</span>
<span style="color: #000040;">---</span> Percona<span style="color: #000040;">-</span>Server<span style="color: #000040;">-</span>5.5.18<span style="color: #000040;">-</span><span style="color:#800080;">23.0</span><span style="color: #000040;">/</span>sql<span style="color: #000040;">/</span>handler.<span style="color: #007788;">h</span>	<span style="color: #0000dd;">2011</span><span style="color: #000040;">-</span><span style="color: #0000dd;">12</span><span style="color: #000040;">-</span><span style="color: #0000dd;">20</span> <span style="color: #208080;">06</span><span style="color: #008080;">:</span><span style="color: #0000dd;">38</span><span style="color: #008080;">:</span><span style="color:#800080;">58.000000000</span> <span style="color: #000040;">+</span><span style="color:#800080;">0800</span>
<span style="color: #000040;">+++</span> Percona<span style="color: #000040;">-</span>Server<span style="color: #000040;">-</span>5.5.18<span style="color: #000040;">-</span><span style="color:#800080;">23.0</span><span style="color: #000040;">-</span>debug<span style="color: #000040;">/</span>sql<span style="color: #000040;">/</span>handler.<span style="color: #007788;">h</span>	<span style="color: #0000dd;">2012</span><span style="color: #000040;">-</span><span style="color: #208080;">01</span><span style="color: #000040;">-</span><span style="color: #0000dd;">17</span> <span style="color: #0000dd;">14</span><span style="color: #008080;">:</span><span style="color: #0000dd;">29</span><span style="color: #008080;">:</span><span style="color:#800080;">17.000000000</span> <span style="color: #000040;">+</span><span style="color:#800080;">0800</span>
@@ <span style="color: #000040;">-</span><span style="color: #0000dd;">501</span>,<span style="color: #0000dd;">7</span> <span style="color: #000040;">+</span><span style="color: #0000dd;">501</span>,<span style="color: #0000dd;">8</span> @@
 <span style="color: #008000;">&#123;</span>
   TS_ALTER_TABLESPACE_TYPE_NOT_DEFINED <span style="color: #000080;">=</span> <span style="color: #000040;">-</span><span style="color: #0000dd;">1</span>,
   ALTER_TABLESPACE_ADD_FILE <span style="color: #000080;">=</span> <span style="color: #0000dd;">1</span>,
<span style="color: #000040;">-</span>  ALTER_TABLESPACE_DROP_FILE <span style="color: #000080;">=</span> <span style="color: #0000dd;">2</span>
<span style="color: #000040;">+</span>  ALTER_TABLESPACE_DROP_FILE <span style="color: #000080;">=</span> <span style="color: #0000dd;">2</span>,
<span style="color: #000040;">+</span>  ALTER_TABLESPACE_ALTER_FILE <span style="color: #000080;">=</span> <span style="color: #0000dd;">3</span> <span style="color: #666666;">// innodb_extent_tablespace By P.Linux</span>
 <span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
 <span style="color: #0000ff;">enum</span> tablespace_access_mode
<span style="color: #000040;">---</span> Percona<span style="color: #000040;">-</span>Server<span style="color: #000040;">-</span>5.5.18<span style="color: #000040;">-</span><span style="color:#800080;">23.0</span><span style="color: #000040;">/</span>storage<span style="color: #000040;">/</span>innobase<span style="color: #000040;">/</span>fil<span style="color: #000040;">/</span>fil0fil.<span style="color: #007788;">c</span>	<span style="color: #0000dd;">2011</span><span style="color: #000040;">-</span><span style="color: #0000dd;">12</span><span style="color: #000040;">-</span><span style="color: #0000dd;">20</span> <span style="color: #208080;">06</span><span style="color: #008080;">:</span><span style="color: #0000dd;">38</span><span style="color: #008080;">:</span><span style="color:#800080;">57.000000000</span> <span style="color: #000040;">+</span><span style="color:#800080;">0800</span>
<span style="color: #000040;">+++</span> Percona<span style="color: #000040;">-</span>Server<span style="color: #000040;">-</span>5.5.18<span style="color: #000040;">-</span><span style="color:#800080;">23.0</span><span style="color: #000040;">-</span>debug<span style="color: #000040;">/</span>storage<span style="color: #000040;">/</span>innobase<span style="color: #000040;">/</span>fil<span style="color: #000040;">/</span>fil0fil.<span style="color: #007788;">c</span>	<span style="color: #0000dd;">2012</span><span style="color: #000040;">-</span><span style="color: #208080;">01</span><span style="color: #000040;">-</span><span style="color: #0000dd;">17</span> <span style="color: #0000dd;">14</span><span style="color: #008080;">:</span><span style="color: #0000dd;">31</span><span style="color: #008080;">:</span><span style="color:#800080;">40.000000000</span> <span style="color: #000040;">+</span><span style="color:#800080;">0800</span>
@@ <span style="color: #000040;">-</span><span style="color: #0000dd;">368</span>,<span style="color: #0000dd;">7</span> <span style="color: #000040;">+</span><span style="color: #0000dd;">368</span>,<span style="color: #0000dd;">8</span> @@
 Checks <span style="color: #0000ff;">if</span> a single<span style="color: #000040;">-</span>table tablespace <span style="color: #0000ff;">for</span> a given table name exists in the
 tablespace memory cache.
 @<span style="color: #0000ff;">return</span>	space id, ULINT_UNDEFINED <span style="color: #0000ff;">if</span> not found <span style="color: #000040;">*/</span>
<span style="color: #000040;">-</span><span style="color: #0000ff;">static</span>
<span style="color: #000040;">+</span><span style="color: #666666;">//static</span>
<span style="color: #000040;">+</span>UNIV_INTERN <span style="color: #666666;">// innodb_extent_tablespace By P.Linux</span>
 ulint
 fil_get_space_id_for_table<span style="color: #008000;">&#40;</span>
 <span style="color: #ff0000; font-style: italic;">/*=======================*/</span>
@@ <span style="color: #000040;">-</span><span style="color: #0000dd;">4676</span>,<span style="color: #0000dd;">7</span> <span style="color: #000040;">+</span><span style="color: #0000dd;">4677</span>,<span style="color: #0000dd;">8</span> @@
 Checks <span style="color: #0000ff;">if</span> a single<span style="color: #000040;">-</span>table tablespace <span style="color: #0000ff;">for</span> a given table name exists in the
 tablespace memory cache.
 @<span style="color: #0000ff;">return</span>	space id, ULINT_UNDEFINED <span style="color: #0000ff;">if</span> not found <span style="color: #000040;">*/</span>
<span style="color: #000040;">-</span><span style="color: #0000ff;">static</span>
<span style="color: #000040;">+</span><span style="color: #666666;">//static</span>
<span style="color: #000040;">+</span>UNIV_INTERN <span style="color: #666666;">// innodb_extent_tablespace By P.Linux</span>
 ulint
 fil_get_space_id_for_table<span style="color: #008000;">&#40;</span>
 <span style="color: #ff0000; font-style: italic;">/*=======================*/</span>
<span style="color: #000040;">---</span> Percona<span style="color: #000040;">-</span>Server<span style="color: #000040;">-</span>5.5.18<span style="color: #000040;">-</span><span style="color:#800080;">23.0</span><span style="color: #000040;">/</span>storage<span style="color: #000040;">/</span>innobase<span style="color: #000040;">/</span>handler<span style="color: #000040;">/</span>ha_innodb.<span style="color: #007788;">cc</span>	<span style="color: #0000dd;">2011</span><span style="color: #000040;">-</span><span style="color: #0000dd;">12</span><span style="color: #000040;">-</span><span style="color: #0000dd;">20</span> <span style="color: #208080;">06</span><span style="color: #008080;">:</span><span style="color: #0000dd;">38</span><span style="color: #008080;">:</span><span style="color:#800080;">58.000000000</span> <span style="color: #000040;">+</span><span style="color:#800080;">0800</span>
<span style="color: #000040;">+++</span> Percona<span style="color: #000040;">-</span>Server<span style="color: #000040;">-</span>5.5.18<span style="color: #000040;">-</span><span style="color:#800080;">23.0</span><span style="color: #000040;">-</span>debug<span style="color: #000040;">/</span>storage<span style="color: #000040;">/</span>innobase<span style="color: #000040;">/</span>handler<span style="color: #000040;">/</span>ha_innodb.<span style="color: #007788;">cc</span>	<span style="color: #0000dd;">2012</span><span style="color: #000040;">-</span><span style="color: #208080;">01</span><span style="color: #000040;">-</span><span style="color: #0000dd;">17</span> <span style="color: #0000dd;">14</span><span style="color: #008080;">:</span><span style="color: #0000dd;">37</span><span style="color: #008080;">:</span><span style="color:#800080;">49.000000000</span> <span style="color: #000040;">+</span><span style="color:#800080;">0800</span>
@@ <span style="color: #000040;">-</span><span style="color: #0000dd;">433</span>,<span style="color: #0000dd;">6</span> <span style="color: #000040;">+</span><span style="color: #0000dd;">434</span>,<span style="color: #0000dd;">12</span> @@
 <span style="color: #ff0000; font-style: italic;">/*=======================*/</span>
 	uint	flags<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #000040;">+</span><span style="color: #ff0000; font-style: italic;">/****************************************************************/</span><span style="color: #ff0000; font-style: italic;">/**
+Alter tablespace supported in an InnoDB table. Allow setting extent space. */</span>
<span style="color: #000040;">+</span><span style="color: #0000ff;">int</span> innobase_alter_tablespace<span style="color: #008000;">&#40;</span>handlerton <span style="color: #000040;">*</span>hton,
<span style="color: #000040;">+</span>                                THD<span style="color: #000040;">*</span> thd, st_alter_tablespace <span style="color: #000040;">*</span>alter_info<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #000040;">+</span><span style="color: #ff0000; font-style: italic;">/* innodb_extent_tablespace By P.Linux */</span>
<span style="color: #000040;">+</span>
 <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">const</span> <span style="color: #0000ff;">char</span> innobase_hton_name<span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span><span style="color: #000080;">=</span> <span style="color: #FF0000;">&quot;InnoDB&quot;</span><span style="color: #008080;">;</span>
&nbsp;
 <span style="color: #ff0000; font-style: italic;">/*************************************************************/</span><span style="color: #ff0000; font-style: italic;">/**
@@ -2489,6 +2496,7 @@
         innobase_hton-&amp;gt;flags=HTON_NO_FLAGS;
         innobase_hton-&amp;gt;release_temporary_latches=innobase_release_temporary_latches;
 	innobase_hton-&amp;gt;alter_table_flags = innobase_alter_table_flags;
+	innobase_hton-&amp;gt;alter_tablespace= innobase_alter_tablespace; // innodb_extent_tablespace By P.Linux
&nbsp;
 	ut_a(DATA_MYSQL_TRUE_VARCHAR == (ulint)MYSQL_TYPE_VARCHAR);
&nbsp;
@@ -3146,6 +3155,33 @@
 		| HA_INPLACE_ADD_PK_INDEX_NO_READ_WRITE);
 }
&nbsp;
+/****************************************************************/</span><span style="color: #ff0000; font-style: italic;">/**
+Alter tablespace supported in an InnoDB table. Allow setting extent space. */</span>
<span style="color: #000040;">+</span><span style="color: #0000ff;">int</span> innobase_alter_tablespace<span style="color: #008000;">&#40;</span>handlerton <span style="color: #000040;">*</span>hton,
<span style="color: #000040;">+</span>                                THD<span style="color: #000040;">*</span> thd, st_alter_tablespace <span style="color: #000040;">*</span>alter_info<span style="color: #008000;">&#41;</span>
<span style="color: #000040;">+</span><span style="color: #008000;">&#123;</span>
<span style="color: #000040;">+</span>       <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>alter_info<span style="color: #000040;">-</span><span style="color: #000040;">&amp;</span>gt<span style="color: #008080;">;</span>ts_alter_tablespace_type <span style="color: #000040;">!</span><span style="color: #000080;">=</span> ALTER_TABLESPACE_ALTER_FILE<span style="color: #008000;">&#41;</span>
<span style="color: #000040;">+</span>       <span style="color: #008000;">&#123;</span>
<span style="color: #000040;">+</span>               <span style="color: #0000ff;">return</span> HA_ADMIN_NOT_IMPLEMENTED<span style="color: #008080;">;</span>
<span style="color: #000040;">+</span>       <span style="color: #008000;">&#125;</span>
<span style="color: #000040;">+</span>
<span style="color: #000040;">+</span>       ulint table_space<span style="color: #000080;">=</span> fil_get_space_id_for_table<span style="color: #008000;">&#40;</span>alter_info<span style="color: #000040;">-</span><span style="color: #000040;">&amp;</span>gt<span style="color: #008080;">;</span>tablespace_name<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #000040;">+</span>
<span style="color: #000040;">+</span>       <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>table_space <span style="color: #000080;">==</span> ULINT_UNDEFINED<span style="color: #008000;">&#41;</span>
<span style="color: #000040;">+</span>       <span style="color: #008000;">&#123;</span>
<span style="color: #000040;">+</span>               my_error<span style="color: #008000;">&#40;</span>ER_WRONG_TABLE_NAME, MYF<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span>, alter_info<span style="color: #000040;">-</span><span style="color: #000040;">&amp;</span>gt<span style="color: #008080;">;</span>tablespace_name<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #000040;">+</span>               <span style="color: #0000ff;">return</span> EE_FILENOTFOUND<span style="color: #008080;">;</span>
<span style="color: #000040;">+</span>       <span style="color: #008000;">&#125;</span>
<span style="color: #000040;">+</span>
<span style="color: #000040;">+</span>       ulint extent_size<span style="color: #000080;">=</span> alter_info<span style="color: #000040;">-</span><span style="color: #000040;">&amp;</span>gt<span style="color: #008080;">;</span>extent_size<span style="color: #008080;">;</span>
<span style="color: #000040;">+</span>       
<span style="color: #000040;">+</span>       ulint actual_size<span style="color: #000080;">=</span><span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #000040;">+</span>       fil_extend_space_to_desired_size<span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>amp<span style="color: #008080;">;</span>actual_size, table_space, extent_size<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #000040;">+</span>
<span style="color: #000040;">+</span>       <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #000040;">+</span><span style="color: #008000;">&#125;</span>
<span style="color: #000040;">+</span><span style="color: #ff0000; font-style: italic;">/* innodb_extent_tablespace By P.Linux */</span>
<span style="color: #000040;">+</span>
 <span style="color: #ff0000; font-style: italic;">/*****************************************************************/</span><span style="color: #ff0000; font-style: italic;">/**
 Commits a transaction in an InnoDB database. */</span>
 <span style="color: #0000ff;">static</span>
<span style="color: #000040;">---</span> Percona<span style="color: #000040;">-</span>Server<span style="color: #000040;">-</span>5.5.18<span style="color: #000040;">-</span><span style="color:#800080;">23.0</span><span style="color: #000040;">/</span>storage<span style="color: #000040;">/</span>innobase<span style="color: #000040;">/</span>include<span style="color: #000040;">/</span>fil0fil.<span style="color: #007788;">h</span>	<span style="color: #0000dd;">2011</span><span style="color: #000040;">-</span><span style="color: #0000dd;">12</span><span style="color: #000040;">-</span><span style="color: #0000dd;">20</span> <span style="color: #208080;">06</span><span style="color: #008080;">:</span><span style="color: #0000dd;">38</span><span style="color: #008080;">:</span><span style="color:#800080;">57.000000000</span> <span style="color: #000040;">+</span><span style="color:#800080;">0800</span>
<span style="color: #000040;">+++</span> Percona<span style="color: #000040;">-</span>Server<span style="color: #000040;">-</span>5.5.18<span style="color: #000040;">-</span><span style="color:#800080;">23.0</span><span style="color: #000040;">-</span>debug<span style="color: #000040;">/</span>storage<span style="color: #000040;">/</span>innobase<span style="color: #000040;">/</span>include<span style="color: #000040;">/</span>fil0fil.<span style="color: #007788;">h</span>	<span style="color: #0000dd;">2012</span><span style="color: #000040;">-</span><span style="color: #208080;">01</span><span style="color: #000040;">-</span><span style="color: #0000dd;">17</span> <span style="color: #0000dd;">14</span><span style="color: #008080;">:</span><span style="color: #0000dd;">39</span><span style="color: #008080;">:</span><span style="color:#800080;">20.000000000</span> <span style="color: #000040;">+</span><span style="color:#800080;">0800</span>
@@ <span style="color: #000040;">-</span><span style="color: #0000dd;">744</span>,<span style="color: #0000dd;">6</span> <span style="color: #000040;">+</span><span style="color: #0000dd;">744</span>,<span style="color: #0000dd;">18</span> @@
 <span style="color: #ff0000; font-style: italic;">/*============================*/</span>
 	ulint		id<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>	<span style="color: #ff0000; font-style: italic;">/*!&amp;lt; in: space id */</span>
&nbsp;
<span style="color: #000040;">+</span><span style="color: #ff0000; font-style: italic;">/*******************************************************************/</span><span style="color: #ff0000; font-style: italic;">/**
+Checks if a single-table tablespace for a given table name exists in the
+tablespace memory cache.
+@return        space id, ULINT_UNDEFINED if not found */</span>
<span style="color: #000040;">+</span>UNIV_INTERN
<span style="color: #000040;">+</span>ulint
<span style="color: #000040;">+</span>fil_get_space_id_for_table<span style="color: #008000;">&#40;</span>
<span style="color: #000040;">+</span><span style="color: #ff0000; font-style: italic;">/*=======================*/</span>
<span style="color: #000040;">+</span>       <span style="color: #0000ff;">const</span> <span style="color: #0000ff;">char</span><span style="color: #000040;">*</span>     name<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>  <span style="color: #ff0000; font-style: italic;">/*!&amp;lt; in: table name in the standard
+                               'databasename/tablename' format */</span>
<span style="color: #000040;">+</span><span style="color: #ff0000; font-style: italic;">/* innodb_extent_tablespace By P.Linux */</span>
<span style="color: #000040;">+</span>
 <span style="color: #ff0000; font-style: italic;">/*************************************************************************
 Return local hash table informations. */</span></pre></td></tr></table></div>

<h2>三、测试结果：</h2>
<h3>1. R910 Oracle单实例</h3>
<p>测试人：童家旺，支付宝<br />
TPS：稳定值2000,峰值2600 （我没参与测试，也没有报告，无法确定详情）<br />
我的补充：Oracle已经是调优的过的，请相信我们的Oracle <acronym title="Database Administrator">DBA</acronym>不是吃素的。我把听Oracle <acronym title="Database Administrator">DBA</acronym>描述的只言碎语随便写下，Oracle跑到后面TPS也是有所下降，不是能一直100%稳定，最后CPU已经吃尽了，所以基本上再怎么优化提升的幅度会比较小。</p>
<h3>2. R910 MySQL单实例 Percona 5.1.59 原版</h3>
<p>测试人：帝俊，支付宝<br />
TPS：峰值1500，无法稳定（具体不祥）<br />
测试人描述：<br />
目前的测试数据显示，由于MySQL在checkpoint上处理跟不上，不足以持续支持1.5K/s的事务数，10MB/s的redo量下的交易创建。该负载下，FIO的写出速度为160～190MB/s，写IOPS为2～2.3k，测试FIO的写吞吐量可以到600MB/s，写IOPS有8K+，需要进一步研究如何进一步提升系统的吞吐量。</p>
<h3>3. R910 MySQL多实例 Percona 5.1.60-13.1原版</h3>
<p>测试人：彭立勋，B2B<br />
TPS：峰值500*4（无法稳定），谷值100，均值450＊4<br />
重要配置：<br />
innodb_page_size=4K # 修改数据页大小与FusionIO匹配<br />
innodb_log_block_size=4K # 修改日志页大小于FusionIO匹配<br />
innodb_log_file_size=1G<br />
innodb_log_files_in_group=3<br />
innodb_buffer_pool_size=20G<br />
innodb_max_dirty_pages_pct=75<br />
innodb_flush_method=ALL_O_DIRECT # 修改文件写入方式全部为O_DIRECT<br />
innodb_read_io_threads=2<br />
innodb_write_io_threads=10<br />
innodb_io_capacity=20000<br />
innodb_extra_rsegments=16<br />
innodb_use_purge_thread=4<br />
innodb_adaptive_flushing_method=3 # 采用Keep_average刷新方式<br />
innodb_flush_neighbor_pages=0 # 不为了凑顺序IO刷相邻未修改的页<br />
测试人描述：<br />
每颗物理CPU绑定一个MySQL实例，四个实例同时接受测试。可以看到在测试过程中，IOPS抖动很大，在4K～17K之间抖动，可以判定，是Checkpoint机制不完善导致刷新间歇性繁忙，在IO闲置的时候不能充分发挥性能。但多实例可以提升整体TPS接近Oracle的均值，说明MySQL内部可能某些常量设置不合理，或者锁定力度太粗导致单实例不能充分发挥单机性能。</p>
<h3>4. R910 MySQL多实例 Percona 5.1.60-13.1 修改版</h3>
<p>测试人：彭立勋，B2B<br />
TPS：峰值1200*4，谷值0，均值950*4<br />
重要配置：（在测试3的基础上）<br />
innodb_aio_pending_ios_per_thread=1024<br />
测试人描述：<br />
经过对测试3的分析，可以发现，InnoDB已经标记了很多Page到Flush_list，但是并没有被即时的回写，可以在INNODB_BUFFER_POOL_PAGES系统表中发现很页flush_type=2，即在Flush_list中。<br />
经过review代码，发现InnoDB申请的AIO队列的长度只有256，由常量OS_AIO_N_PENDING_IOS_PER_THREAD（os0file.h）定义。将此常量修改为InnoDB的参数后，重新测试，可以使FusionIO的IOPS达到7K～18K，IO利用率得以提升，整体性能已经超越Oracle，但存在严重的低谷，大约每10s一次。</p>
<h3>5.R510 MySQL单实例 Percona 5.5.18-23.0 修改版</h3>
<p>测试人：彭立勋,B2B<br />
TPS：峰值2800，谷值2300，均值2500<br />
重要配置：（在测试3的基础上）<br />
innodb_aio_pending_ios_per_thread=512<br />
alter tablespace `trade/xxx` set extent_size=5000000; # 预先扩展数据文件<br />
测试人描述：<br />
根据测试4的结果进行分析，需要解决的主要问题就是抖动，抖动可能是两个原因导致的，一个是Checkpoint机制不完善，一个是数据文件扩展。Checkpoint机制不完善这个暂时无法改进，只能先解决数据文件扩展上的问题，采用淘宝丁奇的方法，对MySQL增加预先扩展文件的功能，在测试前先将文件扩展至测试写满需要的大小，使测试过程中无需扩展文件。<br />
实例测试中发现非常有效，抖动范围在2300～2800之间，可以接受。但是Buffer Pool一旦脏页写满，为了控制脏页量InnoDB就会加大刷新量，影响到TPS。实际上在脏页未满的时候，IOPS就没有用完，但是InnoDB计算刷新量并没有考虑操作系统反馈的影响信息，只是根据自己的redo产生量计算。<br />
<a href="http://www.yupoo.com/photos/plinux/84222190/" title="R510_1"><img src="http://pic.yupoo.com/plinux/BGH3jg5X/medish.jpg" alt="R510_1" width="533" height="462" border="0" /></a><br />
同时观察CPU还发现，2.6.18内核会将所有软中断发送到Core0上处理，这可能也是瓶颈之一。（当时忘记拷贝状态，这是后来确认内核问题看得，可以看这篇文章，一样的，<a href="http://dbahacker.com/linux/cpu%E8%BD%AF%E4%B8%AD%E6%96%AD%E5%AE%9E%E8%B7%B5%E4%B8%80" title="CPU软中断实践" target="_blank">CPU软中断实践</a>）<br />
03:05:17 PM CPU %user %nice %sys %iowait %irq %soft %steal %idle intr/s<br />
03:05:18 PM all 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00 1014.00<br />
03:05:18 PM 0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00 1000.00</p>
<h3>6. R510 MySQL单实例 Percona 5.5.19-24.0 原版</h3>
<p>测试人：彭立勋，B2B<br />
TPS：峰值3100，谷值2400，均值2700<br />
重要配置：（在测试3的基础上）<br />
替换内核版本为2.6.32淘宝版，使用IO中断负载均衡。<br />
innodb_adaptive_flushing_method = 2<br />
innodb_flush_neighbor_pages = cont<br />
测试人描述：<br />
采用淘宝版内核后，可以发现每个CPU都被用的比较满：(部分)<br />
06:27:26 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle<br />
06:27:27 PM  all   69.80    0.00   18.68    0.51    0.00    0.17    0.00    0.00   10.84<br />
06:27:27 PM    0   74.75    0.00   17.17    0.00    0.00    0.00    0.00    0.00    8.08<br />
06:27:27 PM    1   73.96    0.00   16.67    1.04    0.00    0.00    0.00    0.00    8.33<br />
06:27:27 PM    2   73.20    0.00   17.53    1.03    0.00    0.00    0.00    0.00    8.25<br />
06:27:27 PM    3   71.72    0.00   19.19    1.01    0.00    0.00    0.00    0.00    8.08<br />
06:27:27 PM    4   71.43    0.00   18.37    1.02    0.00    0.00    0.00    0.00    9.18<br />
06:27:27 PM    5   70.71    0.00   19.19    1.01    0.00    0.00    0.00    0.00    9.09</p>
<p>这是个好现象，说明CPU被充分用起来了，在脏页未满之前，TPS可以比较稳定的维持在3000以上。但还是老问题，脏页一满，速度就下降，到测试结束时下降为2400。<br />
<a href="http://www.yupoo.com/photos/plinux/84222191/" title="R510_2"><img src="http://pic.yupoo.com/plinux/BGH3jipn/q6QVk.jpg" alt="R510_2" width="530" height="372" border="0" /></a></p>
<h2>四、测试结论：</h2>
<p>MySQL的调优与操作系统结合非常紧密，需要整体联动才能获得好的效果，InnoDB琐粒度较粗的缺陷，在代码实现简单的情况下，实际上对并发的影响不是很明显。<br />
目前MySQL对高速硬件的利用主要缺陷是，不少常量写死，Checkpoint机制不完善，Checkpoint刷新脏页&#8211;&gt;InnoDB AIO队列&#8211;&gt;操作系统IO队列&#8211;&gt;存储设备，中间任何一环存在问题，都可能导致性能下降。<br />
InnoDB AIO队列可以通过补丁开放参数设置，这个瓶颈已经消除。<br />
操作系统IO队列可以通过淘宝的内核补丁将中断分散到每个核上处理来解决。<br />
目前存在最大的问题就是Checkpoint刷新脏页的机制，仅仅依赖redo产生的速度，其实硬件IO还有很多余量，但InnoDB并不知道。<br />
如果能限定一种机型，限定一种操作系统，在MySQL内获取操作系统报告的硬件状态，自适应的决策自己的行为，这样可以充分利用系统资源，例如IO util%并不高的时候，即使脏页还没到阈值，也可以加大刷新量，充分利用IO，这样可能系统根本就达不到脏页阈值，可以一直保持搞TPS，至少可以延缓TPS下降的趋势。<br />
抖动问题则是Oracle和MySQL都存在的问题，扩展数据文件的瞬间必然导致TPS下降，淘宝丁奇的方法可以完美解决，Oracle也是类似的方法通过预先分配表空间文件解决。</p>
<h2>五、测试缺陷：</h2>
<p>测试CASE不全，没有在R910上测试5.5（虽然已经超了Oracle，但R910上应该还能猛一点），没有测试5.5多实例下可以获得何种性能，没有测试5.1在2.6.32内核下的表现，没有测试不同的页大小对InnoDB的影响。<br />
没有稳定性测试，原版+多实例 属于稳定方案，其他改动是否100%不影响稳定，尚需测试。<br />
在R910上的测试没有监控系统，也就没有图，坑爹了。</p>
<h2>六、后续Action</h2>
<p>在InnoDB控制刷赃页量的地方加入对系统diskstat的监控，当系统IO util%<80%的时候，增加(IO_CAPACITY-当前系统IO数-redo计算的刷新量)个页的刷新，在系统不忙的时候提前加大刷新量，期望保持TPS稳定。</p>
<h2>七、随意补充</h2>
<p>为什么读为主的应用不用担心IO用不完？因为读操作是同步IO，一旦请求就被发送到磁盘，所以只要并发够多，总能把IO压爆。但是写为了加速，几乎所有数据库都是先写到内存，再异步写到磁盘，当然你要是搞最大保护模式，应该也是有数据库可以直接同步写磁盘的，但是对大部分数据库都是先写内存，再异步到磁盘，所以如果异步IO这里存在设计上的瓶颈，不管加多少并发，都是徒劳，内存一旦写满，链接线程就都堵住了，要等异步IO消化完才能继续，所以对于写为主的应用，这个CASE都是很有参考价值的。</p><h2  class="related_post_title">类似的文章</h2><ul class="related_post"><li>2011年12月23日 -- <a href="http://www.penglixun.com/tech/database/server_kill_idle_transaction.html" title="在Server层实现Kill Idle Transaction">在Server层实现Kill Idle Transaction</a> (1)</li><li>2010年12月6日 -- <a href="http://www.penglixun.com/tech/database/percona_vs_mysql.html" title="Percona对MySQL标准版本的改进">Percona对MySQL标准版本的改进</a> (3)</li><li>2010年01月14日 -- <a href="http://www.penglixun.com/tech/database/xtradb_compile_error.html" title="XtraDB 1.0.6-9编译错误的解决">XtraDB 1.0.6-9编译错误的解决</a> (0)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.penglixun.com/tech/database/case_about_innodb_faster_than_oracle.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Linux Cache 机制探究</title>
		<link>http://www.penglixun.com/tech/system/linux_cache_discovery.html</link>
		<comments>http://www.penglixun.com/tech/system/linux_cache_discovery.html#comments</comments>
		<pubDate>Fri, 27 Aug 2010 04:56:31 +0000</pubDate>
		<dc:creator>P.Linux</dc:creator>
				<category><![CDATA[操作系统]]></category>
		<category><![CDATA[Cache]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Radix Tree]]></category>

		<guid isPermaLink="false">http://www.penglixun.com/?p=1160</guid>
		<description><![CDATA[本文内容遵从CC版权协议, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://www.penglixun.com/tech/system/linux_cache_discovery.html 经过研究了下Linux相关代码，把对Lin... ]]></description>
			<content:encoded><![CDATA[<p><span style="color: #888888;">本文内容遵从<a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh" target="_blank">CC版权协议</a>, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明</br>网址: http://www.penglixun.com/tech/system/linux_cache_discovery.html </p>
<p></span>经过研究了下Linux相关代码，把对Linux Cache实现的方式做一些总结。<br />
相关源码主要在：<br />
./fs/fscache/cache.c    Cache实现的代码<br />
./mm/slab.c                                     SLAB管理器代码<br />
./mm/swap.c                                   缓存替换算法代码<br />
./mm/mmap.c             内存管理器代码<br />
./mm/mempool.c       内存池实现代码</p>
<h2>0. 预备：Linux内存管理基础</h2>
<p>创建进程fork()、程序载入execve()、映射文件mmap()、动态内存分配malloc()/brk()等进程相关操作都需要分配内存给进程。不过这时进程申请和获得的还不是实际内存，而是虚拟内存，准确的说是“内存区域”。Linux除了内核以外，App都不能直接使用内存，因为Linux采用Memory Map的管理方式，App拿到的全部是内核映射自物理内存的一块虚拟内存。malloc分配很少会失败，因为malloc只是通知内存App需要内存，在没有正式使用之前，这段内存其实只在真正开始使用的时候才分配，所以malloc成功了并不代表使用的时候就真的可以拿到这么多内存。据说Google的tcmalloc改进了这一点。</p>
<p>进程对内存区域的分配最终多会归结到do_mmap()函数上来（brk调用被单独以系统调用实现，不用do_mmap()）。内核使用do_mmap()函数创建一个新的线性地址区间，如果创建的地址区间和一个已经存在的地址区间相邻，并且它们具有相同的访问权限的话，那么两个区间将合并为一个。如果不能合并，那么就确实需要创建一个新的VMA了。但无论哪种情况， do_mmap()函数都会将一个地址区间加入到进程的地址空间中，无论是扩展已存在的内存区域还是创建一个新的区域。同样释放一个内存区域使用函数do_ummap()，它会销毁对应的内存区域。</p>
<p>另一个重要的部分是SLAB分配器。在Linux中以页为最小单位分配内存对于内核管理系统物理内存来说是比较方便的，但内核自身最常使用的内存却往往是很小（远远小于一页）的内存块，因为大都是一些描述符。一个整页中可以聚集多个这种这些小块内存，如果一样按页分配，那么会被频繁的创建/销毁，开始是非常大的。</p>
<p>为了满足内核对这种小内存块的需要，Linux系统采用了SLAB分配器。Slab分配器的实现相当复杂，但原理不难，其核心思想就是Memory Pool。内存片段（小块内存）被看作对象，当被使用完后，并不直接释放而是被缓存到Memory Pool里，留做下次使用，这就避免了频繁创建与销毁对象所带来的额外负载。</p>
<p>Slab技术不但避免了内存内部分片带来的不便，而且可以很好利用硬件缓存提高访问速度。但Slab仍然是建立在页面基础之上，Slab将页面分成众多小内存块以供分配，Slab中的对象分配和销毁使用kmem_cache_alloc与kmem_cache_free。</p>
<p>关于SALB分配器有一份资料：<a href="http://lsec.cc.ac.cn/~tengfei/doc/ldd3/ch08s02.html">http://lsec.cc.ac.cn/~tengfei/doc/ldd3/ch08s02.html</a><br />
关于内存管理的两份资料：<a href="http://lsec.cc.ac.cn/~tengfei/doc/ldd3/ch15.html">http://lsec.cc.ac.cn/~tengfei/doc/ldd3/ch15.html</a><br />
<a href="http://memorymyann.javaeye.com/blog/193061">http://memorymyann.javaeye.com/blog/193061</a></p>
<h2>1. Linux Cache的体系</h2>
<p>在 Linux 中，当App需要读取Disk文件中的数据时，Linux先分配一些内存，将数据从Disk读入到这些内存中，然后再将数据传给App。当需要往文件中写数据时，Linux先分配内存接收用户数据，然后再将数据从内存写到Disk上。Linux Cache  管理指的就是对这些由Linux分配，并用来存储文件数据的内存的管理。</p>
<p>下图描述了 Linux 中文件 Cache 管理与内存管理以及文件系统的关系。从图中可以看到，在 Linux 中，具体的文件系统，如  ext2/ext3/ext4 等，负责在文件  Cache和存储设备之间交换数据，位于具体文件系统之上的虚拟文件系统VFS负责在应用程序和文件 Cache 之间通过 read/write  等接口交换数据，而内存管理系统负责文件 Cache 的分配和回收，同时虚拟内存管理系统(VMM)则允许应用程序和文件 Cache 之间通过  memory map的方式交换数据，FS Cache底层通过SLAB管理器来管理内存。</p>
<p style="text-align: left;"><a title="Linux Cache体系 1" href="http://www.yupoo.com/photos/plinux/77106238/"><img class="aligncenter" src="http://pic.yupoo.com/plinux/AqzqMw23/eSwSS.jpg" border="0" alt="Linux Cache体系 1" width="567" height="484" /></a><br />
下图则非常清晰的描述了Cache所在的位置，磁盘与VFS之间的纽带。</p>
<p style="text-align: center;"><a title="Linux Cache体系 2" href="http://www.yupoo.com/photos/plinux/77106302/"><img class="aligncenter" src="http://pic.yupoo.com/plinux/AqzrM4oI/JfuYd.jpg" border="0" alt="Linux Cache体系 2" width="313" height="432" /></a></p>
<h2 style="text-align: left;">2. Linux Cache的结构</h2>
<p style="text-align: left;">在 Linux 中，文件 Cache 分为两层，一是 Page Cache，另一个 Buffer Cache，每一个 Page  Cache 包含若干 Buffer Cache。内存管理系统和 VFS 只与 Page Cache 交互，内存管理系统负责维护每项 Page  Cache 的分配和回收，同时在使用 memory map 方式访问时负责建立映射；VFS 负责 Page Cache  与用户空间的数据交换。而具体文件系统则一般只与 Buffer Cache 交互，它们负责在外围存储设备和 Buffer Cache  之间交换数据。读缓存以Page Cache为单位，每次读取若干个Page Cache，回写磁盘以Buffer Cache为单位，每次回写若干个Buffer Cache。<br />
Page Cache、Buffer Cache、文件以及磁盘之间的关系如下图所示。</p>
<p style="text-align: left;">
<p style="text-align: center;"><a title="Linux Cache实现" href="http://www.yupoo.com/photos/plinux/77106240/"><img class="aligncenter" src="http://pic.yupoo.com/plinux/AqzqMUfN/K05Tc.jpg" border="0" alt="Linux Cache实现" width="389" height="268" /></a></p>
<p style="text-align: left;">Page 结构和 buffer_head  数据结构的关系如下图所示。Page指向一组Buffer的头指针，Buffer的头指针指向磁盘块。在这两个图中，假定了 Page 的大小是 4K，磁盘块的大小是 1K。</p>
<p style="text-align: center;"><a title="Page Cache结构" href="http://www.yupoo.com/photos/plinux/77106241/"><img class="aligncenter" src="http://pic.yupoo.com/plinux/AqzqMRAZ/4YDuW.jpg" border="0" alt="Page Cache结构" width="373" height="258" /></a></p>
<p>在 Linux 内核中，文件的每个数据块最多只能对应一个 Page Cache  项，它通过两个数据结构来管理这些 Cache 项，一个是 Radix Tree，另一个是双向链表。Radix Tree 是一种搜索树，Linux  内核利用这个数据结构来通过文件内偏移快速定位 Cache 项，图 4 是 radix tree的一个示意图，该 radix tree  的分叉为4(22)，树高为4，用来快速定位8位文件内偏移。Linux(2.6.7) 内核中的分叉为 64(26)，树高为 6(64位系统)或者  11(32位系统)，用来快速定位 32 位或者 64 位偏移，Radix tree 中的每一个到叶子节点的路径上的Key所拼接起来的字串都是一个地址，指向文件内相应偏移所对应的Cache项。</p>
<p style="text-align: center;"><a title="Page Cache使用的Radix Tree 1" href="http://www.yupoo.com/photos/plinux/77106242/"><img src="http://pic.yupoo.com/plinux/AqzqMTB3/tnoPA.gif" border="0" alt="Page Cache使用的Radix Tree 1" width="521" height="362" /></a></p>
<p>查看Page Cache的核心数据结构struct address_space就可以看到上述结构（略去了无关结构）：</p>

<div class="wp_codebox"><table><tr id="p11608"><td class="code" id="p1160code8"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">struct</span> address_space  <span style="color: #008000;">&#123;</span>
<span style="color: #0000ff;">struct</span> inode             <span style="color: #000040;">*</span>host<span style="color: #008080;">;</span>              <span style="color: #ff0000; font-style: italic;">/* owner: inode, block_device */</span>
<span style="color: #0000ff;">struct</span> radix_tree_root      page_tree<span style="color: #008080;">;</span>         <span style="color: #ff0000; font-style: italic;">/* radix tree of all pages */</span>
<span style="color: #0000ff;">unsigned</span> <span style="color: #0000ff;">long</span>           nrpages<span style="color: #008080;">;</span>  <span style="color: #ff0000; font-style: italic;">/* number of total pages */</span>
<span style="color: #0000ff;">struct</span> address_space       <span style="color: #000040;">*</span>assoc_mapping<span style="color: #008080;">;</span>      <span style="color: #ff0000; font-style: italic;">/* ditto */</span>
......
<span style="color: #008000;">&#125;</span> __attribute__<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>aligned<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">sizeof</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">long</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p style="text-align: left;">下面是一个Radix Tree实例：</p>
<p style="text-align: center;"><a title="Page Cache使用的Radix Tree 2" href="http://www.yupoo.com/photos/plinux/77106308/"><img class="aligncenter" src="http://pic.yupoo.com/plinux/AqzslYCb/3D95i.jpg" border="0" alt="Page Cache使用的Radix Tree 2" width="442" height="423" /></a></p>
<p>另一个数据结构是双向链表，Linux内核为每一片物理内存区域(zone)  维护active_list和inactive_list两个双向链表，这两个list主要用来实现物理内存的回收。这两个链表上除了文件Cache之 外，还包括其它匿名(Anonymous)内存，如进程堆栈等。</p>
<p style="text-align: center;"><a title="Linux Cache 置换算法" href="http://www.yupoo.com/photos/plinux/77107061/"><img class="aligncenter" src="http://pic.yupoo.com/plinux/AqzJSDWK/cc9PP.png" border="0" alt="Linux Cache 置换算法" width="547" height="243" /></a></p>
<p style="text-align: left;">相关数据结构如下：</p>

<div class="wp_codebox"><table><tr id="p11609"><td class="code" id="p1160code9"><pre class="cpp" style="font-family:monospace;">truct page<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">struct</span> list_head list<span style="color: #008080;">;</span>   <span style="color: #666666;">//通过使用它进入下面的数据结构free_area_struct结构中的双向链队列</span>
    <span style="color: #0000ff;">struct</span> address_space <span style="color: #000040;">*</span> mapping<span style="color: #008080;">;</span>   <span style="color: #666666;">//用于内存交换的数据结构</span>
    <span style="color: #0000ff;">unsigned</span> <span style="color: #0000ff;">long</span> index<span style="color: #008080;">;</span><span style="color: #666666;">//当页面进入交换文件后</span>
    <span style="color: #0000ff;">struct</span> page <span style="color: #000040;">*</span>next_hash<span style="color: #008080;">;</span> <span style="color: #666666;">//自身的指针，这样就可以链接成一个链表</span>
    atomic t count<span style="color: #008080;">;</span> <span style="color: #666666;">//用于页面交换的计数,若页面为空闲则为0，分配就赋值1，没建立或恢复一次映射就加1，断开映射就减一</span>
    <span style="color: #0000ff;">unsigned</span> <span style="color: #0000ff;">long</span> flags<span style="color: #008080;">;</span><span style="color: #666666;">//反应页面各种状态，例如活跃，不活跃脏，不活跃干净，空闲</span>
   <span style="color: #0000ff;">struct</span> list_head lru<span style="color: #008080;">;</span>
   <span style="color: #0000ff;">unsigned</span> <span style="color: #0000ff;">long</span> age<span style="color: #008080;">;</span> <span style="color: #666666;">//表示页面寿命</span>
   wait_queue_head_t wait<span style="color: #008080;">;</span>
   <span style="color: #0000ff;">struct</span> page <span style="color: #000040;">**</span> pprev_hash<span style="color: #008080;">;</span>
   <span style="color: #0000ff;">struct</span> buffer_head <span style="color: #000040;">*</span> buffers<span style="color: #008080;">;</span>
   <span style="color: #0000ff;">void</span> <span style="color: #000040;">*</span> <span style="color: #0000ff;">virtual</span>
   <span style="color: #0000ff;">struct</span> zone_struct <span style="color: #000040;">*</span> zone<span style="color: #008080;">;</span> <span style="color: #666666;">//指向所属的管理区</span>
<span style="color: #008000;">&#125;</span>
<span style="color: #0000ff;">typedef</span> <span style="color: #0000ff;">struct</span> free_area_struct <span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">struct</span> list_head free_list<span style="color: #008080;">;</span>   <span style="color: #666666;">//linux 中通用的双向链队列</span>
    <span style="color: #0000ff;">unsigned</span> <span style="color: #0000ff;">int</span> <span style="color: #000040;">*</span> map<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span> free_area_t<span style="color: #008080;">;</span>
<span style="color: #0000ff;">typedef</span> <span style="color: #0000ff;">struct</span> zone_struct<span style="color: #008000;">&#123;</span>
    spinlock_t        lock<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">unsigned</span> <span style="color: #0000ff;">long</span> offset<span style="color: #008080;">;</span>  <span style="color: #666666;">//表示该管理区在mem-map数组中，起始的页号</span>
    <span style="color: #0000ff;">unsigned</span> <span style="color: #0000ff;">long</span> <span style="color: #0000dd;">free</span> pages<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">unsigned</span> <span style="color: #0000ff;">long</span> inactive_clean_pages<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">unsigned</span> <span style="color: #0000ff;">long</span> inactive_dirty_pages<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">unsigned</span> pages_min, pages_low, pages_high<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">struct</span> list_head inactive_clean_list<span style="color: #008080;">;</span>   <span style="color: #666666;">//用于页面交换的队列，基于linux页面交换的机制。这里存贮的是不活动“干净”页面</span>
    free_area_t free_area<span style="color: #008000;">&#91;</span>MAX_ORDER<span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span> <span style="color: #666666;">//一组“空闲区间”队列，free_area_t定义在上面，其中空闲下标表示的是页面大小，例如：数组第一个元素0号，表示所有区间大小为2的 0次方的页面链接成的双向队列，1号表示所有2的1次方页面链接链接成的双向队列，2号表示所有2的2次方页面链接成的队列，其中要求是这些页面地址连续</span>
    <span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span> name<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">unsigned</span> <span style="color: #0000ff;">long</span> size<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">struct</span> pglist_data <span style="color: #000040;">*</span> zone_pgdat<span style="color: #008080;">;</span>   <span style="color: #666666;">//用于指向它所属的存贮节点，及下面的数据结构</span>
    <span style="color: #0000ff;">unsigned</span>  <span style="color: #0000ff;">long</span>  zone_start_paddr<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">unsigned</span>  <span style="color: #0000ff;">long</span>    zone_start_mapnr<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">struct</span> page <span style="color: #000040;">*</span> zone_mem_map<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span> zone_t<span style="color: #008080;">;</span></pre></td></tr></table></div>

<h2 style="text-align: left;">3. Cache预读与换出</h2>
<p style="text-align: left;">Linux  内核中文件预读算法的具体过程是这样的：<br />
对于每个文件的第一个读请求，系统读入所请求的页面并读入紧随其后的少数几个页面(不少于一个页面，通常是三个页 面)，这时的预读称为同步预读。对于第二次读请求，如果所读页面不在Cache中，即不在前次预读的group中，则表明文件访问不是顺序访问，系统继续 采用同步预读；如果所读页面在Cache中，则表明前次预读命中，操作系统把预读group扩大一倍，并让底层文件系统读入group中剩下尚不在  Cache中的文件数据块，这时的预读称为异步预读。无论第二次读请求是否命中，系统都要更新当前预读group的大小。<br />
此外，系统中定义了一个  window，它包括前一次预读的group和本次预读的group。任何接下来的读请求都会处于两种情况之一：<br />
第一种情况是所请求的页面处于预读  window中，这时继续进行异步预读并更新相应的window和group；<br />
第二种情况是所请求的页面处于预读window之外，这时系统就要进行同步 预读并重置相应的window和group。<br />
下图是Linux内核预读机制的一个示意图，其中a是某次读操作之前的情况，b是读操作所请求页面不在  window中的情况，而c是读操作所请求页面在window中的情况。</p>
<p style="text-align: center;"><a title="Cache预读算法" href="http://www.yupoo.com/photos/plinux/77106243/"><img class="aligncenter" src="http://pic.yupoo.com/plinux/AqzqN7jG/EEuVU.gif" border="0" alt="Cache预读算法" width="494" height="298" /></a></p>
<p>Linux内核中文件Cache替换的具体过程是这样的：刚刚分配的Cache项链入到inactive_list头部，并将其状态设置为active，当内存不够需要回收Cache时，系统首先从尾部开始反向扫描  active_list并将状态不是referenced的项链入到inactive_list的头部，然后系统反向扫描inactive_list，如果所扫描的项的处于合适的状态就回收该项，直到回收了足够数目的Cache项。其中Active_list的含义是热访问数据，及多次被访问的，inactive_list是冷访问数据，表示尚未被访问的。如果数据被访问了，Page会被打上一个Refrence标记，如果Page没有被访问过，则打上Unrefrence标记。这些处理在swap.c中可以找到。<br />
下图也描述了这个过程。</p>
<p style="text-align: center;"><a title="Linux Cache 置换算法" href="http://www.yupoo.com/photos/plinux/77107061/"><img class="aligncenter" src="http://pic.yupoo.com/plinux/AqzJSDWK/cc9PP.png" border="0" alt="Linux Cache 置换算法" width="547" height="243" /></a></p>
<p>下面的代码描述了一个Page被访问它的标记为变化：</p>

<div class="wp_codebox"><table><tr id="p116010"><td class="code" id="p1160code10"><pre class="cpp" style="font-family:monospace;"><span style="color: #000040;">*</span>
 <span style="color: #000040;">*</span> Mark a page as having seen activity.
 <span style="color: #000040;">*</span>
 <span style="color: #000040;">*</span> inactive,unreferenced        <span style="color: #000040;">-</span><span style="color: #000040;">&amp;</span>gt<span style="color: #008080;">;</span>      inactive,referenced
 <span style="color: #000040;">*</span> inactive,referenced          <span style="color: #000040;">-</span><span style="color: #000040;">&amp;</span>gt<span style="color: #008080;">;</span>      active,unreferenced
 <span style="color: #000040;">*</span> active,unreferenced          <span style="color: #000040;">-</span><span style="color: #000040;">&amp;</span>gt<span style="color: #008080;">;</span>      active,referenced
 <span style="color: #000040;">*/</span>
<span style="color: #0000ff;">void</span> mark_page_accessed<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">struct</span> page <span style="color: #000040;">*</span>page<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
        <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">!</span>PageActive<span style="color: #008000;">&#40;</span>page<span style="color: #008000;">&#41;</span> <span style="color: #000040;">&amp;</span>amp<span style="color: #008080;">;</span><span style="color: #000040;">&amp;</span>amp<span style="color: #008080;">;</span> <span style="color: #000040;">!</span>PageUnevictable<span style="color: #008000;">&#40;</span>page<span style="color: #008000;">&#41;</span> <span style="color: #000040;">&amp;</span>amp<span style="color: #008080;">;</span><span style="color: #000040;">&amp;</span>amp<span style="color: #008080;">;</span>
                        PageReferenced<span style="color: #008000;">&#40;</span>page<span style="color: #008000;">&#41;</span> <span style="color: #000040;">&amp;</span>amp<span style="color: #008080;">;</span><span style="color: #000040;">&amp;</span>amp<span style="color: #008080;">;</span> PageLRU<span style="color: #008000;">&#40;</span>page<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
                activate_page<span style="color: #008000;">&#40;</span>page<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
                ClearPageReferenced<span style="color: #008000;">&#40;</span>page<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        <span style="color: #008000;">&#125;</span> <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">!</span>PageReferenced<span style="color: #008000;">&#40;</span>page<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
                SetPageReferenced<span style="color: #008000;">&#40;</span>page<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>参考文章：<br />
<a href="http://lsec.cc.ac.cn/~tengfei/doc/ldd3/">http://lsec.cc.ac.cn/~tengfei/doc/ldd3/</a><br />
<a href="http://memorymyann.javaeye.com/blog/193061">http://memorymyann.javaeye.com/blog/193061</a><br />
<a href="http://www.cublog.cn/u/20047/showart.php?id=121850">http://www.cublog.cn/u/20047/showart.php?id=121850</a><br />
<a href="http://blog.chinaunix.net/u2/74194/showart_1089736.html">http://blog.chinaunix.net/u2/74194/showart_1089736.html</a><br />
关于内存管理，Linux有一个网页：<a href="http://linux-mm.org/">http://linux-mm.org/</a></p><h2  class="related_post_title">类似的文章</h2><ul class="related_post"><li>2009年12月14日 -- <a href="http://www.penglixun.com/tech/system/buffer_and_cache_diff.html" title="Buffer与Cache">Buffer与Cache</a> (1)</li><li>2009年10月20日 -- <a href="http://www.penglixun.com/tech/system/manual_free_linux_memory.html" title="[转]手工释放Linux内存——/proc/sys/vm/drop_caches ">[转]手工释放Linux内存——/proc/sys/vm/drop_caches </a> (0)</li><li>2012年01月23日 -- <a href="http://www.penglixun.com/tech/database/case_about_innodb_faster_than_oracle.html" title="一个InnoDB性能超过Oracle的调优Case">一个InnoDB性能超过Oracle的调优Case</a> (1)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.penglixun.com/tech/system/linux_cache_discovery.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Load和CPU利用率是如何算出来的</title>
		<link>http://www.penglixun.com/tech/system/how_to_calc_load_cpu.html</link>
		<comments>http://www.penglixun.com/tech/system/how_to_calc_load_cpu.html#comments</comments>
		<pubDate>Tue, 10 Aug 2010 09:19:50 +0000</pubDate>
		<dc:creator>P.Linux</dc:creator>
				<category><![CDATA[操作系统]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Load]]></category>
		<category><![CDATA[top]]></category>

		<guid isPermaLink="false">http://www.penglixun.com/?p=1158</guid>
		<description><![CDATA[本文内容遵从CC版权协议, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://www.penglixun.com/tech/system/how_to_calc_load_cpu.html 相信很多人都对Linux中top命令里“load... ]]></description>
			<content:encoded><![CDATA[<p><span style="color: #888888;">本文内容遵从<a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh" target="_blank">CC版权协议</a>, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明</br>网址: http://www.penglixun.com/tech/system/how_to_calc_load_cpu.html </p>
<p></span>相信很多人都对Linux中top命令里“<strong>load average</strong>”这一栏困惑过，到底什么是Load，Load代表了什么含义，Load高会有什么后果？“<strong>%CPU</strong>”这一栏为什么会超过100%，它是如何计算的？<br />
带着这些问题，我们通过一些测试，来探索下其中的不解之处。</p>
<p>首先，我们通过实验来大概确定其计算方式：<br />
测试服务器：4核Xeon处理器<br />
测试软件：MySQL 5.1.40<br />
服务器上除了MySQL没有运行其他任何非系统自带软件。因为MySQL只能单线程运行单条<acronym title="Structured Query Language">SQL</acronym>，所以可以很好的通过增加查询并发来控制使用的CPU核数。</p>
<p>空载时，top的信息为：</p>
<blockquote><p>top &#8211; 14:51:47 up 35 days,  4:43,  1 user,  load average: 0.00, 0.00, 0.00<br />
Tasks:  76 total,   1 running,  75 sleeping,   0 stopped,   0 zombie<br />
Cpu(s):  0.0%us,  0.0%sy,  0.0%ni, 99.5%id,  0.1%wa,  0.2%hi,  0.2%si,  0.0%st</p></blockquote>
<p>在数据库中启动一个大查询：</p>
<blockquote><p>top &#8211; 15:28:09 up 35 days,  5:19,  3 users,  load average: 0.99, 0.92, 0.67<br />
Tasks:  80 total,   1 running,  79 sleeping,   0 stopped,   0 zombie<br />
Cpu0  :  0.0%us,  0.0%sy,  0.0%ni, 96.3%id,  0.0%wa,  1.3%hi,  2.3%si,  0.0%st<br />
Cpu1  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st<br />
Cpu2  : 98.7%us,  1.3%sy,  0.0%ni,  0.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st<br />
Cpu3  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st</p></blockquote>
<p>同时可以看到%CPU也是在100%</p>
<blockquote><p>PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND<br />
877 mysql     15   0  308m 137m 4644 S 99.9  6.8  15:13.28 mysqld</p></blockquote>
<p>然后开启第二个大查询，不久就可以看到top信息的变化，Load到了2：</p>
<blockquote><p>top &#8211; 15:36:44 up 35 days,  5:28,  3 users,  load average: 1.99, 1.62, 1.08<br />
Tasks:  80 total,   1 running,  79 sleeping,   0 stopped,   0 zombie<br />
Cpu0  :  0.0%us,  0.0%sy,  0.0%ni, 97.7%id,  0.0%wa,  1.0%hi,  1.3%si,  0.0%st<br />
Cpu1  : 99.0%us,  1.0%sy,  0.0%ni,  0.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st<br />
Cpu2  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st<br />
Cpu3  : 99.0%us,  1.0%sy,  0.0%ni,  0.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st</p></blockquote>
<p>也可以观察到%CPU增加到了200%：</p>
<blockquote><p>PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND<br />
877 mysql     15   0  312m 141m 4644 S 199.8  7.0  22:31.27 mysqld</p></blockquote>
<p>由此可以简单的做出如下临时结论：<br />
<strong>1. %CPU是由每个核的CPU占用律之和算出来的。</strong><br />
<strong>2. load跟执行的任务数有关</strong><br />
不过要想准确的知道其含义，还是必须从源码入手。<br />
<span id="more-1158"></span><br />
</br></p>
<h1>CPU利用率的计算方法</h1>
<p>下载busybox的源码，在procps目录下有top.c的源码，查看第293行附近（1.17.1版），可以看到</p>

<div class="wp_codebox"><table><tr id="p115817"><td class="code" id="p1158code17"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>prev_hist_count<span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">do</span> <span style="color: #008000;">&#123;</span>
        <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>prev_hist<span style="color: #008000;">&#91;</span>i<span style="color: #008000;">&#93;</span>.<span style="color: #007788;">pid</span> <span style="color: #000080;">==</span> pid<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
                cur<span style="color: #000040;">-</span><span style="color: #000040;">&amp;</span>gt<span style="color: #008080;">;</span>pcpu <span style="color: #000080;">=</span> cur<span style="color: #000040;">-</span><span style="color: #000040;">&amp;</span>gt<span style="color: #008080;">;</span>ticks <span style="color: #000040;">-</span> prev_hist<span style="color: #008000;">&#91;</span>i<span style="color: #008000;">&#93;</span>.<span style="color: #007788;">ticks</span><span style="color: #008080;">;</span>
                total_pcpu <span style="color: #000040;">+</span><span style="color: #000080;">=</span> cur<span style="color: #000040;">-</span><span style="color: #000040;">&amp;</span>gt<span style="color: #008080;">;</span>pcpu<span style="color: #008080;">;</span>
                <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
        <span style="color: #008000;">&#125;</span>
        i <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span>i<span style="color: #000040;">+</span><span style="color: #0000dd;">1</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">%</span> prev_hist_count<span style="color: #008080;">;</span>
        <span style="color: #ff0000; font-style: italic;">/* hist_iterations++; */</span>
<span style="color: #008000;">&#125;</span> <span style="color: #0000ff;">while</span> <span style="color: #008000;">&#40;</span>i <span style="color: #000040;">!</span><span style="color: #000080;">=</span> last_i<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>这就是计算%CPU的代码，很明显total_pcpu就是累加了每个线程对每个核的使用率，所以<strong>%CPU的最大值就是核数*100%</strong>。</p>
<p>而CPU利用率又是怎么计算的呢，跟踪代码可以发现，是从系统的<strong>/proc/stat</strong>这里读取的，这个文件的格式可以参考：http://www.linuxhowtos.org/System/procstat.htm，下面是我笔记本上读出来的内容。</p>
<blockquote><p>plx@plinux-Laptop:~/busybox-1.17.1$ cat /proc/stat<br />
cpu  520529 3525 658608 3500749 210662 6650 29698 0 0<br />
cpu0 249045 1936 466387 1624486 136381 308 17051 0 0<br />
cpu1 271483 1588 192221 1876263 74281 6342 12646 0 0<br />
intr 84067574 42497789 41743 0 0 0 0 0 0 1 57928 0 0 7175 0 0 0 477092 24693 0 5 0 183 0 20 0 0 0 12455 821851 745906 10192555 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0<br />
ctxt 142313984<br />
btime 1281403521<br />
processes 6707<br />
procs_running 2<br />
procs_blocked 0<br />
softirq 56932805 0 20168080 9440286 238191 821787 0 10621375 4052209 13257 11577620</p></blockquote>
<p>cpuN的含义从左到右分别是：user、system、nice、idle、iowait、irq、softirq，具体含义可以看文档。<br />
在下面几行的含义是：<br />
“intr”这行给出中断的信息，第一个为自系统启动以来，发生的所有的中断的次数；然后每个数对应一个特定的中断自系统启动以来所发生的次数。<br />
“ctxt”给出了自系统启动以来CPU发生的上下文交换的次数。<br />
“btime”给出了从系统启动到现在为止的时间，单位为秒。<br />
“processes (total_forks) 自系统启动以来所创建的任务的个数目。<br />
“procs_running”：当前运行队列的任务的数目。<br />
“procs_blocked”：当前被阻塞的任务的数目。<br />
那么CPU利用率可以使用以下方法，先取两个采样点，然后计算其差值：</p>

<div class="wp_codebox"><table><tr id="p115818"><td class="code" id="p1158code18"><pre class="c" style="font-family:monospace;">cpu usage<span style="color: #339933;">=</span><span style="color: #009900;">&#40;</span>idle2<span style="color: #339933;">-</span>idle1<span style="color: #009900;">&#41;</span><span style="color: #339933;">/</span><span style="color: #009900;">&#40;</span>cpu2<span style="color: #339933;">-</span>cpu1<span style="color: #009900;">&#41;</span><span style="color: #339933;">*</span><span style="color: #0000dd;">100</span> cpu usage<span style="color: #339933;">=</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#40;</span>user_2 <span style="color: #339933;">+</span>sys_2<span style="color: #339933;">+</span>nice_2<span style="color: #009900;">&#41;</span> <span style="color: #339933;">-</span> <span style="color: #009900;">&#40;</span>user_1 <span style="color: #339933;">+</span> sys_1<span style="color: #339933;">+</span>nice_1<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">/</span><span style="color: #009900;">&#40;</span>total_2 <span style="color: #339933;">-</span> total_1<span style="color: #009900;">&#41;</span><span style="color: #339933;">*</span><span style="color: #0000dd;">100</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>这是一段Bash代码采集利用率的，摘自网络：</p>

<div class="wp_codebox"><table><tr id="p115819"><td class="code" id="p1158code19"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/sh</span>
<span style="color: #666666; font-style: italic;">##echo user nice system idle iowait irq softirq</span>
<span style="color: #007800;">CPULOG_1</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: #000000; font-weight: bold;">/</span>proc<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">stat</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> <span style="color: #ff0000;">'cpu '</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'{print $2&quot; &quot;$3&quot; &quot;$4&quot; &quot;$5&quot; &quot;$6&quot; &quot;$7&quot; &quot;$8}'</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #007800;">SYS_IDLE_1</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #007800;">$CPULOG_1</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'{print $4}'</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #007800;">Total_1</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #007800;">$CPULOG_1</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'{print $1+$2+$3+$4+$5+$6+$7}'</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
&nbsp;
<span style="color: #c20cb9; font-weight: bold;">sleep</span> <span style="color: #000000;">5</span>
&nbsp;
<span style="color: #007800;">CPULOG_2</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: #000000; font-weight: bold;">/</span>proc<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">stat</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> <span style="color: #ff0000;">'cpu '</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'{print $2&quot; &quot;$3&quot; &quot;$4&quot; &quot;$5&quot; &quot;$6&quot; &quot;$7&quot; &quot;$8}'</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #007800;">SYS_IDLE_2</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #007800;">$CPULOG_2</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'{print $4}'</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #007800;">Total_2</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #007800;">$CPULOG_2</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'{print $1+$2+$3+$4+$5+$6+$7}'</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> 
&nbsp;
<span style="color: #007800;">SYS_IDLE</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">expr</span> <span style="color: #007800;">$SYS_IDLE_2</span> - <span style="color: #007800;">$SYS_IDLE_1</span><span style="color: #000000; font-weight: bold;">`</span>
&nbsp;
<span style="color: #007800;">Total</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">expr</span> <span style="color: #007800;">$Total_2</span> - <span style="color: #007800;">$Total_1</span><span style="color: #000000; font-weight: bold;">`</span>
<span style="color: #007800;">SYS_USAGE</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">expr</span> <span style="color: #007800;">$SYS_IDLE</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$Total</span><span style="color: #000000; font-weight: bold;">*</span><span style="color: #000000;">100</span> <span style="color: #000000; font-weight: bold;">|</span><span style="color: #c20cb9; font-weight: bold;">bc</span> -l<span style="color: #000000; font-weight: bold;">`</span>
&nbsp;
<span style="color: #007800;">SYS_Rate</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">expr</span> <span style="color: #000000;">100</span>-<span style="color: #007800;">$SYS_USAGE</span> <span style="color: #000000; font-weight: bold;">|</span><span style="color: #c20cb9; font-weight: bold;">bc</span> -l<span style="color: #000000; font-weight: bold;">`</span>
&nbsp;
<span style="color: #007800;">Disp_SYS_Rate</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">expr</span> <span style="color: #ff0000;">&quot;scale=3; <span style="color: #007800;">$SYS_Rate</span>/1&quot;</span> <span style="color: #000000; font-weight: bold;">|</span><span style="color: #c20cb9; font-weight: bold;">bc</span><span style="color: #000000; font-weight: bold;">`</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #007800;">$Disp_SYS_Rate</span><span style="color: #000000; font-weight: bold;">%</span></pre></td></tr></table></div>

<p>还有一段<acronym title="Practical Extraction and Report Language">Perl</acronym>的代码，也是摘自网络：</p>

<div class="wp_codebox"><table><tr id="p115820"><td class="code" id="p1158code20"><pre class="perl" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/usr/bin/perl</span>
<span style="color: #000000; font-weight: bold;">use</span> warnings<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #0000ff;">$SLEEPTIME</span><span style="color: #339933;">=</span><span style="color: #cc66cc;">5</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">-</span>e <span style="color: #ff0000;">&quot;/tmp/stat&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<a href="http://perldoc.perl.org/functions/unlink.html"><span style="color: #000066;">unlink</span></a> <span style="color: #ff0000;">&quot;/tmp/stat&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<a href="http://perldoc.perl.org/functions/open.html"><span style="color: #000066;">open</span></a> <span style="color: #009900;">&#40;</span>JIFF_TMP<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;&amp;gt;&amp;gt;/tmp/stat&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> <a href="http://perldoc.perl.org/functions/die.html"><span style="color: #000066;">die</span></a> <span style="color: #ff0000;">&quot;Can't open /proc/stat file!<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<a href="http://perldoc.perl.org/functions/open.html"><span style="color: #000066;">open</span></a> <span style="color: #009900;">&#40;</span>JIFF<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;/proc/stat&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> <a href="http://perldoc.perl.org/functions/die.html"><span style="color: #000066;">die</span></a> <span style="color: #ff0000;">&quot;Can't open /proc/stat file!<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">@jiff_0</span><span style="color: #339933;">=;</span>
<a href="http://perldoc.perl.org/functions/print.html"><span style="color: #000066;">print</span></a> JIFF_TMP <span style="color: #0000ff;">$jiff_0</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">;</span>
<a href="http://perldoc.perl.org/functions/close.html"><span style="color: #000066;">close</span></a> <span style="color: #009900;">&#40;</span>JIFF<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<a href="http://perldoc.perl.org/functions/sleep.html"><span style="color: #000066;">sleep</span></a> <span style="color: #0000ff;">$SLEEPTIME</span><span style="color: #339933;">;</span>
&nbsp;
<a href="http://perldoc.perl.org/functions/open.html"><span style="color: #000066;">open</span></a> <span style="color: #009900;">&#40;</span>JIFF<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;/proc/stat&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> <a href="http://perldoc.perl.org/functions/die.html"><span style="color: #000066;">die</span></a> <span style="color: #ff0000;">&quot;Can't open /proc/stat file!<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>  <span style="color: #0000ff;">@jiff_1</span><span style="color: #339933;">=;</span>
<a href="http://perldoc.perl.org/functions/print.html"><span style="color: #000066;">print</span></a> JIFF_TMP <span style="color: #0000ff;">$jiff_1</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<a href="http://perldoc.perl.org/functions/close.html"><span style="color: #000066;">close</span></a> <span style="color: #009900;">&#40;</span>JIFF<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<a href="http://perldoc.perl.org/functions/close.html"><span style="color: #000066;">close</span></a> <span style="color: #009900;">&#40;</span>JIFF_TMP<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #0000ff;">@USER</span><span style="color: #339933;">=</span><span style="color: #ff0000;">`awk '{print <span style="color: #000099; font-weight: bold;">\$</span>2}' &quot;/tmp/stat&quot;`</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">@NICE</span><span style="color: #339933;">=</span><span style="color: #ff0000;">`awk '{print <span style="color: #000099; font-weight: bold;">\$</span>3}' &quot;/tmp/stat&quot;`</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">@SYSTEM</span><span style="color: #339933;">=</span><span style="color: #ff0000;">`awk '{print <span style="color: #000099; font-weight: bold;">\$</span>4}' &quot;/tmp/stat&quot;`</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">@IDLE</span><span style="color: #339933;">=</span><span style="color: #ff0000;">`awk '{print <span style="color: #000099; font-weight: bold;">\$</span>5}' &quot;/tmp/stat&quot;`</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">@IOWAIT</span><span style="color: #339933;">=</span><span style="color: #ff0000;">`awk '{print <span style="color: #000099; font-weight: bold;">\$</span>6}' &quot;/tmp/stat&quot;`</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">@IRQ</span><span style="color: #339933;">=</span><span style="color: #ff0000;">`awk '{print <span style="color: #000099; font-weight: bold;">\$</span>7}' &quot;/tmp/stat&quot;`</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">@SOFTIRQ</span><span style="color: #339933;">=</span><span style="color: #ff0000;">`awk '{print <span style="color: #000099; font-weight: bold;">\$</span>8}' &quot;/tmp/stat&quot;`</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #0000ff;">$JIFF_0</span><span style="color: #339933;">=</span><span style="color: #0000ff;">$USER</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span><span style="color: #0000ff;">$NICE</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span><span style="color: #0000ff;">$SYSTEM</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span><span style="color: #0000ff;">$IDLE</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span><span style="color: #0000ff;">$IOWAIT</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span><span style="color: #0000ff;">$IRQ</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span><span style="color: #0000ff;">$SOFTIRQ</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$JIFF_1</span><span style="color: #339933;">=</span><span style="color: #0000ff;">$USER</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span><span style="color: #0000ff;">$NICE</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span><span style="color: #0000ff;">$SYSTEM</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span><span style="color: #0000ff;">$IDLE</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span><span style="color: #0000ff;">$IOWAIT</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span><span style="color: #0000ff;">$IRQ</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span><span style="color: #0000ff;">$SOFTIRQ</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$SYS_IDLE</span><span style="color: #339933;">=</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$IDLE</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">-</span><span style="color: #0000ff;">$IDLE</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">/</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$JIFF_0</span><span style="color: #339933;">-</span><span style="color: #0000ff;">$JIFF_1</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">*</span> <span style="color: #cc66cc;">100</span><span style="color: #339933;">;</span>  <span style="color: #0000ff;">$SYS_USAGE</span><span style="color: #339933;">=</span><span style="color: #cc66cc;">100</span> <span style="color: #339933;">-</span> <span style="color: #0000ff;">$SYS_IDLE</span><span style="color: #339933;">;</span>
&nbsp;
<a href="http://perldoc.perl.org/functions/printf.html"><span style="color: #000066;">printf</span></a> <span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;The CPU usage is %1.2f%%<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$SYS_USAGE</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p></br><br />
</br></p>
<h1>Load的计算方法</h1>
<p>跟踪busybox的代码可以知道，load是从/proc/loadavg中读取的。<br />
我本机的一次抓取内容如下：</p>
<blockquote><p>plx@plinux-Laptop:~/busybox-1.17.1$ cat /proc/loadavg<br />
0.64 0.81 0.86 3/364 6930</p></blockquote>
<p>每个值的含义依次为：<br />
lavg_1 (0.64) 1-分钟平均负载<br />
lavg_5 (0.81) 5-分钟平均负载<br />
lavg_15(0.86) 15-分钟平均负载<br />
nr_running (3) 在采样时刻，运行队列的任务的数目，与/proc/stat的procs_running表示相同意思<br />
nr_threads (364) 在采样时刻，系统中活跃的任务的个数（不包括运行已经结束的任务）<br />
last_pid(6930) 最大的pid值，包括轻量级进程，即线程。<br />
假设当前有两个CPU，则每个CPU的当前任务数为0.64/2=0.32</p>
<p>我们可以在Linux内核中找到loadavg文件的源码：</p>

<div class="wp_codebox"><table><tr id="p115821"><td class="code" id="p1158code21"><pre class="c" style="font-family:monospace;">tatic <span style="color: #993333;">int</span> loadavg_read_proc<span style="color: #009900;">&#40;</span><span style="color: #993333;">char</span> <span style="color: #339933;">*</span>page<span style="color: #339933;">,</span> <span style="color: #993333;">char</span> <span style="color: #339933;">**</span>start<span style="color: #339933;">,</span> off_t off<span style="color: #339933;">,</span>
                                 <span style="color: #993333;">int</span> count<span style="color: #339933;">,</span> <span style="color: #993333;">int</span> <span style="color: #339933;">*</span>eof<span style="color: #339933;">,</span> <span style="color: #993333;">void</span> <span style="color: #339933;">*</span>data<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
        <span style="color: #993333;">int</span> a<span style="color: #339933;">,</span> b<span style="color: #339933;">,</span> c<span style="color: #339933;">;</span>
        <span style="color: #993333;">int</span> len<span style="color: #339933;">;</span>
<span style="color: #339933;">#</span>
&nbsp;
        a <span style="color: #339933;">=</span> avenrun<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span>FIXED_1<span style="color: #339933;">/</span><span style="color: #0000dd;">200</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        b <span style="color: #339933;">=</span> avenrun<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span>FIXED_1<span style="color: #339933;">/</span><span style="color: #0000dd;">200</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        c <span style="color: #339933;">=</span> avenrun<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span>FIXED_1<span style="color: #339933;">/</span><span style="color: #0000dd;">200</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        len <span style="color: #339933;">=</span> sprintf<span style="color: #009900;">&#40;</span>page<span style="color: #339933;">,</span><span style="color: #ff0000;">&quot;%d.%02d %d.%02d %d.%02d %ld/%d %d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span>
                LOAD_INT<span style="color: #009900;">&#40;</span>a<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> LOAD_FRAC<span style="color: #009900;">&#40;</span>a<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
                LOAD_INT<span style="color: #009900;">&#40;</span>b<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> LOAD_FRAC<span style="color: #009900;">&#40;</span>b<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
                LOAD_INT<span style="color: #009900;">&#40;</span>c<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> LOAD_FRAC<span style="color: #009900;">&#40;</span>c<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
                nr_running<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> nr_threads<span style="color: #339933;">,</span> last_pid<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> proc_calc_metrics<span style="color: #009900;">&#40;</span>page<span style="color: #339933;">,</span> start<span style="color: #339933;">,</span> off<span style="color: #339933;">,</span> count<span style="color: #339933;">,</span> eof<span style="color: #339933;">,</span> len<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>以及计算load的代码：</p>

<div class="wp_codebox"><table><tr id="p115822"><td class="code" id="p1158code22"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#define FSHIFT      11          /* nr of bits of precision */</span>
<span style="color: #339933;">#define FIXED_1     (1&lt;&lt;FSHIFT) /* 1.0 as fixed-point(定点) */</span>
<span style="color: #339933;">#define LOAD_FREQ   (5*HZ)      /* 5 sec intervals，每隔5秒计算一次平均负载值 */</span>
<span style="color: #339933;">#define CALC_LOAD(load, exp, n)     \
         load *= exp;               \
         load += n*(FIXED_1 - exp); \
         load &gt;&gt;= FSHIFT;</span>
&nbsp;
<span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> avenrun<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
EXPORT_SYMBOL<span style="color: #009900;">&#40;</span>avenrun<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">/*
* calc_load - given tick count, update the avenrun load estimates.
* This is called while holding a write_lock on xtime_lock.
*/</span>
<span style="color: #993333;">static</span> <span style="color: #000000; font-weight: bold;">inline</span> <span style="color: #993333;">void</span> calc_load<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> ticks<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
        <span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> active_tasks<span style="color: #339933;">;</span> <span style="color: #808080; font-style: italic;">/* fixed-point */</span>
        <span style="color: #993333;">static</span> <span style="color: #993333;">int</span> count <span style="color: #339933;">=</span> LOAD_FREQ<span style="color: #339933;">;</span>
        count <span style="color: #339933;">-=</span> ticks<span style="color: #339933;">;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>count <span style="color: #339933;">&lt;</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                count <span style="color: #339933;">+=</span> LOAD_FREQ<span style="color: #339933;">;</span>
                active_tasks <span style="color: #339933;">=</span> count_active_tasks<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                CALC_LOAD<span style="color: #009900;">&#40;</span>avenrun<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> EXP_1<span style="color: #339933;">,</span> active_tasks<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                CALC_LOAD<span style="color: #009900;">&#40;</span>avenrun<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> EXP_5<span style="color: #339933;">,</span> active_tasks<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                CALC_LOAD<span style="color: #009900;">&#40;</span>avenrun<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> EXP_15<span style="color: #339933;">,</span> active_tasks<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>看了<a href="http://bitirainy.itpub.net/post/330/6405">大师的文章</a>，理解了这些代码。<br />
所以可以明白：<strong>Linux的系统负载指运行队列的平均长度，也就是等待CPU的平均进程数。</strong> Linux的系统负载指运行队列的平均长度，也就是等待CPU的平均进程数。因为Linux内禁止浮点运算，因此系统的负载只能通过计算变化的次数这一修正值来计算。Linux内核定义一个长度为3的双字数组avenrun，双字的低11位用于存放负载的小数部分，高21位用于存放整数部分。当进程所耗的 CPU时间片数超过CPU在5秒内能够提供的时间片数时，内核计算上述的三个负载。负载初始化为0，假设最近1、5、15分钟内的平均负载分别为 load1、load5和load15，那么下一个计算时刻到来时，内核通过下面的算式计算负载：<br />
    load1 -= load1 -* exp(-5 / 60) -+ n * (1 &#8211; exp(-5 / 60 ))<br />
    load5 -= load5 -* exp(-5 / 300) + n * (1 &#8211; exp(-5 / 300))<br />
    load15 = load15 * exp(-5 / 900) + n * (1 &#8211; exp(-5 / 900))<br />
    其中，exp(x)为e的x次幂，n为当前运行队列的长度。Linux内核认为进程的生存时间服从参数为1的指数分布，指数分布的概率密度为：以内核计算负载load1为例，设相邻两个计算时刻之间系统活动的进程集合为S0。从1分钟前到当前计算时刻这段时间里面活动的load1个进程，设他们的集合是 S1，内核认为的概率密度是:λe-λx，而在当前时刻活动的n个进程，设他们的集合是Sn内核认为的概率密度是1-λe-λx。其中x = 5 / 60，因为相邻两个计算时刻之间进程所耗的CPU时间为5秒，而考虑的时间段是1分钟(60秒)。那么可以求出最近1分钟系统运行队列的长度：<br />
    <strong>load1 = |S1| -* λe-λx + |Sn| * (1-λe-λx) = load1 * λe-λx + n * (1-λe-λx)</strong><br />
其中λ = 1， x = 5 / 60， |S1|和|Sn|是集合元素的个数，这就是Linux内核源文件shed.c的函数calc_load()计算负载的数学依据。<br />
</br><br />
所以“Load值=CPU核数”，这是最理想的状态，没有任何竞争，一个任务分配一个核。<br />
由于数据是每隔5秒钟检查一次活跃的进程数，然后根据这个数值算出来的。<strong>如果这个数除以CPU的核数，结果高于5的时候就表明系统在超负荷运转了。</strong></p><h2  class="related_post_title">类似的文章</h2><ul class="related_post"><li>2009年10月21日 -- <a href="http://www.penglixun.com/tech/system/commond_watch_linux_system_resources.html" title="[转]Linux中查看系统资源占用情况的命令">[转]Linux中查看系统资源占用情况的命令</a> (0)</li><li>2012年01月23日 -- <a href="http://www.penglixun.com/tech/database/case_about_innodb_faster_than_oracle.html" title="一个InnoDB性能超过Oracle的调优Case">一个InnoDB性能超过Oracle的调优Case</a> (1)</li><li>2010年08月27日 -- <a href="http://www.penglixun.com/tech/system/linux_cache_discovery.html" title="Linux Cache 机制探究">Linux Cache 机制探究</a> (1)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.penglixun.com/tech/system/how_to_calc_load_cpu.html/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Linux下编译PHP的几种错误</title>
		<link>http://www.penglixun.com/tech/system/linux_compile_php_error.html</link>
		<comments>http://www.penglixun.com/tech/system/linux_compile_php_error.html#comments</comments>
		<pubDate>Mon, 18 Jan 2010 05:03:56 +0000</pubDate>
		<dc:creator>P.Linux</dc:creator>
				<category><![CDATA[操作系统]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[编译]]></category>

		<guid isPermaLink="false">http://www.penglixun.com/?p=890</guid>
		<description><![CDATA[本文内容遵从CC版权协议, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://www.penglixun.com/tech/system/linux_compile_php_error.html Forcing buildconf buildconf: checking install... ]]></description>
			<content:encoded><![CDATA[<p><span style="color: #888888;">本文内容遵从<a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh" target="_blank">CC版权协议</a>, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明</br>网址: http://www.penglixun.com/tech/system/linux_compile_php_error.html </p>
<p></span>Forcing buildconf<br />
buildconf: checking installation…<br />
buildconf: autoconf version 2.65 (ok)<br />
buildconf: Your version of autoconf likely contains buggy cache code.<br />
Running vcsclean for you.<br />
To avoid this, install autoconf-2.13.<br />
Can’t figure out your VCS, not cleaning.<br />
rebuilding configure<br />
configure.in:492: warning: AC_CACHE_VAL(have_broken_glibc_fopen_append, …): suspicious cache-id, must contain _cv_ to be cached<br />
autoconf/general.m4:2013: AC_CACHE_VAL is expanded from…<br />
aclocal.m4:1736: PHP_BROKEN_GLIBC_FOPEN_APPEND is expanded from…<br />
ext/mbstring/config.m4:356: warning: AC_CACHE_VAL(cv_php_mbstring_stdarg, …): suspicious cache-id, must contain _cv_ to be cached<br />
autoconf/general.m4:2026: AC_CACHE_CHECK is expanded from…<br />
ext/mbstring/config.m4:205: PHP_MBSTRING_SETUP_MBREGEX is expanded from…<br />
ext/pdo_dblib/config.m4:71: warning: AC_CACHE_VAL(pdo_inc_path, …): suspicious cache-id, must contain _cv_ to be cached<br />
aclocal.m4:2754: PHP_CHECK_PDO_INCLUDES is expanded from…<br />
ext/pdo_firebird/config.m4:48: warning: AC_CACHE_VAL(pdo_inc_path, …): suspicious cache-id, must contain _cv_ to be cached<br />
ext/pdo_mysql/config.m4:160: warning: AC_CACHE_VAL(pdo_inc_path, …): suspicious cache-id, must contain _cv_ to be cached<br />
ext/pdo_oci/config.m4:211: warning: AC_CACHE_VAL(pdo_inc_path, …): suspicious cache-id, must contain _cv_ to be cached<br />
ext/pdo_odbc/config.m4:59: warning: AC_CACHE_VAL(pdo_inc_path, …): suspicious cache-id, must contain _cv_ to be cached<br />
ext/pdo_pgsql/config.m4:121: warning: AC_CACHE_VAL(pdo_inc_path, …): suspicious cache-id, must contain _cv_ to be cached<br />
ext/pdo_sqlite/config.m4:31: warning: AC_CACHE_VAL(pdo_inc_path, …): suspicious cache-id, must contain _cv_ to be cached<br />
ext/sqlite/config.m4:50: warning: AC_CACHE_VAL(pdo_inc_path, …): suspicious cache-id, must contain _cv_ to be cached<br />
ext/standard/config.m4:235: warning: AC_CACHE_VAL(php_can_support_proc_open, …): suspicious cache-id, must contain _cv_ to be cached<span id="more-890"></span><br />
configure.in:1347: warning: AC_CACHE_VAL(lt_prog_compiler_static_works, …): suspicious cache-id, must contain _cv_ to be cached<br />
aclocal.m4:3585: AC_LIBTOOL_LINKER_OPTION is expanded from…<br />
aclocal.m4:5597: _LT_AC_LANG_C_CONFIG is expanded from…<br />
aclocal.m4:5492: AC_LIBTOOL_LANG_C_CONFIG is expanded from…<br />
aclocal.m4:3109: AC_LIBTOOL_SETUP is expanded from…<br />
aclocal.m4:2967: _AC_PROG_LIBTOOL is expanded from…<br />
aclocal.m4:2947: AC_PROG_LIBTOOL is expanded from…<br />
configure.in:1347: warning: AC_CACHE_VAL(lt_prog_compiler_pic_works, …): suspicious cache-id, must contain _cv_ to be cached<br />
aclocal.m4:3548: AC_LIBTOOL_COMPILER_OPTION is expanded from…<br />
aclocal.m4:8133: AC_LIBTOOL_PROG_COMPILER_PIC is expanded from…<br />
configure.in:1347: warning: AC_CACHE_VAL(lt_prog_compiler_pic_works_CXX, …): suspicious cache-id, must contain _cv_ to be cached<br />
aclocal.m4:6549: _LT_AC_LANG_CXX_CONFIG is expanded from…<br />
aclocal.m4:5605: AC_LIBTOOL_LANG_CXX_CONFIG is expanded from…<br />
aclocal.m4:4737: _LT_AC_TAGCONFIG is expanded from…<br />
rebuilding main/php_config.h.in<br />
autoheader: WARNING: Using auxiliary files such as `acconfig.h’, `config.h.bot’<br />
autoheader: WARNING: and `config.h.top’, to define templates for `config.h.in’<br />
autoheader: WARNING: is deprecated and discouraged.<br />
autoheader:<br />
autoheader: WARNING: Using the third argument of `AC_DEFINE’ and<br />
autoheader: WARNING: `AC_DEFINE_UNQUOTED’ allows one to define a template without<br />
autoheader: WARNING: `acconfig.h’:<br />
autoheader:<br />
autoheader: WARNING:   AC_DEFINE([NEED_FUNC_MAIN], 1,<br />
autoheader:             [Define if a function `main' is needed.])<br />
autoheader:<br />
autoheader: WARNING: More sophisticated templates can also be produced, see the<br />
autoheader: WARNING: documentation.<br />
configure.in:492: warning: AC_CACHE_VAL(have_broken_glibc_fopen_append, …): suspicious cache-id, must contain _cv_ to be cached<br />
autoconf/general.m4:2013: AC_CACHE_VAL is expanded from…<br />
aclocal.m4:1736: PHP_BROKEN_GLIBC_FOPEN_APPEND is expanded from…<br />
ext/mbstring/config.m4:356: warning: AC_CACHE_VAL(cv_php_mbstring_stdarg, …): suspicious cache-id, must contain _cv_ to be cached<br />
autoconf/general.m4:2026: AC_CACHE_CHECK is expanded from…<br />
ext/mbstring/config.m4:205: PHP_MBSTRING_SETUP_MBREGEX is expanded from…<br />
ext/pdo_dblib/config.m4:71: warning: AC_CACHE_VAL(pdo_inc_path, …): suspicious cache-id, must contain _cv_ to be cached<br />
aclocal.m4:2754: PHP_CHECK_PDO_INCLUDES is expanded from…<br />
ext/pdo_firebird/config.m4:48: warning: AC_CACHE_VAL(pdo_inc_path, …): suspicious cache-id, must contain _cv_ to be cached<br />
ext/pdo_mysql/config.m4:160: warning: AC_CACHE_VAL(pdo_inc_path, …): suspicious cache-id, must contain _cv_ to be cached<br />
ext/pdo_oci/config.m4:211: warning: AC_CACHE_VAL(pdo_inc_path, …): suspicious cache-id, must contain _cv_ to be cached<br />
ext/pdo_odbc/config.m4:59: warning: AC_CACHE_VAL(pdo_inc_path, …): suspicious cache-id, must contain _cv_ to be cached<br />
ext/pdo_pgsql/config.m4:121: warning: AC_CACHE_VAL(pdo_inc_path, …): suspicious cache-id, must contain _cv_ to be cached<br />
ext/pdo_sqlite/config.m4:31: warning: AC_CACHE_VAL(pdo_inc_path, …): suspicious cache-id, must contain _cv_ to be cached<br />
ext/sqlite/config.m4:50: warning: AC_CACHE_VAL(pdo_inc_path, …): suspicious cache-id, must contain _cv_ to be cached<br />
ext/standard/config.m4:235: warning: AC_CACHE_VAL(php_can_support_proc_open, …): suspicious cache-id, must contain _cv_ to be cached<br />
configure.in:1347: warning: AC_CACHE_VAL(lt_prog_compiler_static_works, …): suspicious cache-id, must contain _cv_ to be cached<br />
aclocal.m4:3585: AC_LIBTOOL_LINKER_OPTION is expanded from…<br />
aclocal.m4:5597: _LT_AC_LANG_C_CONFIG is expanded from…<br />
aclocal.m4:5492: AC_LIBTOOL_LANG_C_CONFIG is expanded from…<br />
aclocal.m4:3109: AC_LIBTOOL_SETUP is expanded from…<br />
aclocal.m4:2967: _AC_PROG_LIBTOOL is expanded from…<br />
aclocal.m4:2947: AC_PROG_LIBTOOL is expanded from…<br />
configure.in:1347: warning: AC_CACHE_VAL(lt_prog_compiler_pic_works, …): suspicious cache-id, must contain _cv_ to be cached<br />
aclocal.m4:3548: AC_LIBTOOL_COMPILER_OPTION is expanded from…<br />
aclocal.m4:8133: AC_LIBTOOL_PROG_COMPILER_PIC is expanded from…<br />
configure.in:1347: warning: AC_CACHE_VAL(lt_prog_compiler_pic_works_CXX, …): suspicious cache-id, must contain _cv_ to be cached<br />
aclocal.m4:6549: _LT_AC_LANG_CXX_CONFIG is expanded from…<br />
aclocal.m4:5605: AC_LIBTOOL_LANG_CXX_CONFIG is expanded from…<br />
aclocal.m4:4737: _LT_AC_TAGCONFIG is expanded from…</p>
<p>貌似因为autoconf版本太高。</p>
<p>在debian下执行<br />
aptitude install autoconf2.13<br />
export PHP_AUTOCONF=/usr/bin/autoconf2.13<br />
export PHP_AUTOHEADER=/usr/bin/autoheader2.13<br />
然后再重新autoconf就行了。</p>
<p>64位下编译最好加上在 configure 时加参数 –with-libdir=lib64 指定使用64位库。</p><h2  class="related_post_title">类似的文章</h2><ul class="related_post"><li>2009年07月9日 -- <a href="http://www.penglixun.com/tech/program/add_database_module_for_php.html" title="为PHP添加数据库模块">为PHP添加数据库模块</a> (0)</li><li>2012年01月23日 -- <a href="http://www.penglixun.com/tech/database/case_about_innodb_faster_than_oracle.html" title="一个InnoDB性能超过Oracle的调优Case">一个InnoDB性能超过Oracle的调优Case</a> (1)</li><li>2010年08月27日 -- <a href="http://www.penglixun.com/tech/system/linux_cache_discovery.html" title="Linux Cache 机制探究">Linux Cache 机制探究</a> (1)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.penglixun.com/tech/system/linux_compile_php_error.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Linux下压缩/解压缩命令</title>
		<link>http://www.penglixun.com/tech/system/linux_compress_uncompress.html</link>
		<comments>http://www.penglixun.com/tech/system/linux_compress_uncompress.html#comments</comments>
		<pubDate>Thu, 31 Dec 2009 07:37:05 +0000</pubDate>
		<dc:creator>P.Linux</dc:creator>
				<category><![CDATA[操作系统]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[压缩]]></category>

		<guid isPermaLink="false">http://www.penglixun.com/?p=869</guid>
		<description><![CDATA[本文内容遵从CC版权协议, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://www.penglixun.com/tech/system/linux_compress_uncompress.html .tar 解包： tar xvf FileName.tar 打包... ]]></description>
			<content:encoded><![CDATA[<p><span style="color: #888888;">本文内容遵从<a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh" target="_blank">CC版权协议</a>, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明</br>网址: http://www.penglixun.com/tech/system/linux_compress_uncompress.html </p>
<p></span>.tar<br />
解包： tar xvf FileName.tar<br />
打包：tar cvf FileName.tar DirName<br />
（注：tar是打包，不是压缩，适合将很多小文件备份）<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
.gz<br />
解压1：gunzip FileName.gz<br />
解压2：gzip -d FileName.gz<br />
压缩：gzip FileName<br />
.tar.gz<br />
解压：tar zxvf FileName.tar.gz<br />
压缩：tar zcvf FileName.tar.gz DirName<br />
（一般常用的就是这个了）</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
<span id="more-869"></span> .bz2<br />
解压1：bzip2 -d FileName.bz2<br />
解压2：bunzip2 FileName.bz2<br />
压缩： bzip2 -z FileName<br />
.tar.bz2<br />
解压：tar jxvf FileName.tar.bz2<br />
压缩：tar jcvf FileName.tar.bz2 DirName<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
.Z<br />
解压：uncompress FileName.Z<br />
压缩：compress FileName<br />
.tar.Z<br />
解压：tar Zxvf FileName.tar.Z<br />
压缩：tar Zcvf FileName.tar.Z DirName<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
.tgz<br />
解压：tar zxvf FileName.tgz<br />
.tar.tgz<br />
解压：tar zxvf FileName.tar.tgz<br />
压缩：tar zcvf FileName.tar.tgz FileName<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
.zip<br />
解压：unzip FileName.zip<br />
压缩：zip FileName.zip DirName<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
.rar<br />
解压：rar a FileName.rar<br />
压缩：rar e FileName.rar<br />
（需要下一个rar程序）<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
.rpm<br />
解包：rpm2cpio FileName.rpm | cpio -div<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p><h2  class="related_post_title">类似的文章</h2><ul class="related_post"><li>2012年01月23日 -- <a href="http://www.penglixun.com/tech/database/case_about_innodb_faster_than_oracle.html" title="一个InnoDB性能超过Oracle的调优Case">一个InnoDB性能超过Oracle的调优Case</a> (1)</li><li>2010年08月27日 -- <a href="http://www.penglixun.com/tech/system/linux_cache_discovery.html" title="Linux Cache 机制探究">Linux Cache 机制探究</a> (1)</li><li>2010年08月10日 -- <a href="http://www.penglixun.com/tech/system/how_to_calc_load_cpu.html" title="Load和CPU利用率是如何算出来的">Load和CPU利用率是如何算出来的</a> (5)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.penglixun.com/tech/system/linux_compress_uncompress.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>gFTP目录乱码问题</title>
		<link>http://www.penglixun.com/tech/system/gftp_dir_garbled.html</link>
		<comments>http://www.penglixun.com/tech/system/gftp_dir_garbled.html#comments</comments>
		<pubDate>Sat, 19 Dec 2009 17:12:16 +0000</pubDate>
		<dc:creator>P.Linux</dc:creator>
				<category><![CDATA[操作系统]]></category>
		<category><![CDATA[gFTP]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://www.penglixun.com/?p=846</guid>
		<description><![CDATA[本文内容遵从CC版权协议, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://www.penglixun.com/tech/system/gftp_dir_garbled.html 看MySQL的文档有些累了，想下载个电影... ]]></description>
			<content:encoded><![CDATA[<p><span style="color: #888888;">本文内容遵从<a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh" target="_blank">CC版权协议</a>, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明</br>网址: http://www.penglixun.com/tech/system/gftp_dir_garbled.html </p>
<p></span>看MySQL的文档有些累了，想下载个电影看看，遂上学校<acronym title="File Transfer Protocol">FTP</acronym>。<br />
看了看Linux下<acronym title="File Transfer Protocol">FTP</acronym>客户端的比较，最终选了gFTP，虽然ftp命令也能下，毕竟电脑是拿来用的不是来装B的，能省事的还是省事点。<br />
结果登录上学校的<acronym title="File Transfer Protocol">FTP</acronym>，gFTP中目录全都不显示，遂Google之。<br />
有的人说改/usr/bin/gftp脚本，加入export LANG=zh_CN.GBK，并且用locale-gen zh_CN.GBK，不过经我实测是不行的。在日志里看获取的目录是可以正常显示，但是界面里还是不行，有的人说是gtk1和gtk2的问题之类的，我觉得应该是扯淡。<br />
然后又看了些解决方案，说locale-gen zh_CN，光GBK没用，然后改.gftp/gftprc，在remote_charset加入gbk,gb2312,utf8等字符集，并且把export LANG改为了zh_CN，实验之，一切OK。<br />
整理步骤就是：<br />
locale-gen zh_CN （我不确定locale-gen zh_CN.GBK是否也必要）<br />
在/usr/bin/gftp中加入export LANG=zh_CN。（我不确定在.gftp/gftprc中的remote_charset加入gbk等是否必要）<br />
遇到类似情况，自己尝试吧，毕竟每个人情况可能不一样，我这里给出的是我已经解决的，我的系统是Ubuntu 9.10 64bit Gnome。</p>
<p>下载《世界大战》ing，最近被某人带的对2012，宇宙，外星人之类的东西很感兴趣，额……好像一致很感兴趣……</p><h2  class="related_post_title">类似的文章</h2><ul class="related_post"><li>2012年01月23日 -- <a href="http://www.penglixun.com/tech/database/case_about_innodb_faster_than_oracle.html" title="一个InnoDB性能超过Oracle的调优Case">一个InnoDB性能超过Oracle的调优Case</a> (1)</li><li>2010年08月27日 -- <a href="http://www.penglixun.com/tech/system/linux_cache_discovery.html" title="Linux Cache 机制探究">Linux Cache 机制探究</a> (1)</li><li>2010年08月10日 -- <a href="http://www.penglixun.com/tech/system/how_to_calc_load_cpu.html" title="Load和CPU利用率是如何算出来的">Load和CPU利用率是如何算出来的</a> (5)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.penglixun.com/tech/system/gftp_dir_garbled.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[转] memcached完全剖析</title>
		<link>http://www.penglixun.com/tech/system/memcached_complete_analyze.html</link>
		<comments>http://www.penglixun.com/tech/system/memcached_complete_analyze.html#comments</comments>
		<pubDate>Tue, 15 Dec 2009 12:59:45 +0000</pubDate>
		<dc:creator>P.Linux</dc:creator>
				<category><![CDATA[操作系统]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Memcached]]></category>

		<guid isPermaLink="false">http://www.penglixun.com/?p=649</guid>
		<description><![CDATA[本文内容遵从CC版权协议, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://www.penglixun.com/tech/system/memcached_complete_analyze.html 版权声明：可以任意转载，但转... ]]></description>
			<content:encoded><![CDATA[<p><span style="color: #888888;">本文内容遵从<a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh" target="_blank">CC版权协议</a>, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明</br>网址: http://www.penglixun.com/tech/system/memcached_complete_analyze.html </p>
<p></span><strong>版权声明：可以任意转载，但转载时必须标明原作者charlee、原始链接<a href="http://tech.idv2.com/2008/08/17/memcached-pdf/">http://tech.idv2.com/2008/08/17/memcached-pdf/</a>以及本声明。</strong></p>
<p>作者已经做成<acronym title="Portable Document Format">PDF</acronym>版，我提供一个下载副本，上面的链接里也有，下面列出目录，有兴趣的可以下载。</p>
<p>下载地址：Note: There is a file embedded within this post, please visit this post to download the file.</p>
<p><span id="more-649"></span><br />
第1 章 memcached的基础&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;..5<br />
1.1 memcached是什么？&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;5<br />
1.2 memcached的特征&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.6<br />
协议简单&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;6<br />
基于libevent的事件处理&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.6<br />
内置内存存储方式&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;6<br />
memcached不互相通信的分布式&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;6<br />
1.3 安装memcached&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.7<br />
memcached的安装&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;7<br />
memcached的启动&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;8<br />
1.4 用客户端连接&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;8<br />
1.5 使用Cache::Memcached&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.9<br />
使用Cache::Memcached连接memcached&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;..9<br />
保存数据&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.10<br />
获取数据&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.10<br />
删除数据&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.10<br />
增一和减一操作&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;..10<br />
1.6 总结&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.11</p>
<p>第2章 理解memcached的内存存储&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.12<br />
2.1 Slab Allocation机制：整理内存以便重复使用&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.12<br />
Slab Allocation的主要术语&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;..13<br />
2.2 在Slab中缓存记录的原理&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.13<br />
2.3 Slab Allocator的缺点&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.13<br />
2.4 使用Growth Factor进行调优&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;14<br />
2.5 查看memcached的内部状态&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;15<br />
2.6 查看slabs的使用状况&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;..16<br />
2.7 总结&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.17</p>
<p>第3 章 memcached的删除机制和发展方向&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;..18<br />
3.1 memcached在数据删除方面有效利用资源&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.18<br />
数据不会真正从memcached中消失&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;..18<br />
Lazy Expiration&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;18<br />
3.2 LRU：从缓存中有效删除数据的原理&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;18<br />
3.3 memcached的最新发展方向&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.18<br />
关于二进制协议&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;..19<br />
二进制协议的格式&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.19<br />
HEADER中引人注目的地方&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;..20<br />
3.4 外部引擎支持&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;20<br />
外部引擎支持的必要性&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;..20<br />
简单<acronym title="Application Programming Interface">API</acronym>设计的成功的关键&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;21<br />
重新审视现在的体系&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;21<br />
3.5 总结&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;22</p>
<p>第4 章 memcached的分布式算法&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;23<br />
4.1 memcached的分布式&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.23<br />
memcached的分布式是什么意思？&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;23<br />
4.2 Cache::Memcached的分布式方法&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.25<br />
根据余数计算分散&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.25<br />
根据余数计算分散的缺点&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.26<br />
4.3 Consistent Hashing&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;..27<br />
Consistent Hashing的简单说明&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;..27<br />
支持Consistent Hashing的函数库&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;29<br />
4.4 总结&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;29</p>
<p>第5 章 memcached的应用和兼容程序&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.30<br />
5.1 mixi案例研究&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.30<br />
服务器配置和数量&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.30<br />
memcached进程&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;..31<br />
memcached使用方法和客户端&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;..31<br />
5.2 memcached应用经验&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.32<br />
通过daemontools启动&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.33<br />
监视&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;33<br />
memcached的性能&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.33<br />
5.3 兼容应用程序&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;35<br />
Tokyo Tyrant案例&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;35</p><h2  class="related_post_title">类似的文章</h2><ul class="related_post"><li>2009年11月17日 -- <a href="http://www.penglixun.com/tech/system/configure_all_function_cacti.html" title="配置全功能Cacti">配置全功能Cacti</a> (0)</li><li>2012年01月23日 -- <a href="http://www.penglixun.com/tech/database/case_about_innodb_faster_than_oracle.html" title="一个InnoDB性能超过Oracle的调优Case">一个InnoDB性能超过Oracle的调优Case</a> (1)</li><li>2010年08月27日 -- <a href="http://www.penglixun.com/tech/system/linux_cache_discovery.html" title="Linux Cache 机制探究">Linux Cache 机制探究</a> (1)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.penglixun.com/tech/system/memcached_complete_analyze.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Buffer与Cache</title>
		<link>http://www.penglixun.com/tech/system/buffer_and_cache_diff.html</link>
		<comments>http://www.penglixun.com/tech/system/buffer_and_cache_diff.html#comments</comments>
		<pubDate>Mon, 14 Dec 2009 09:17:54 +0000</pubDate>
		<dc:creator>P.Linux</dc:creator>
				<category><![CDATA[操作系统]]></category>
		<category><![CDATA[Buffer]]></category>
		<category><![CDATA[Cache]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://www.penglixun.com/?p=638</guid>
		<description><![CDATA[本文内容遵从CC版权协议, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://www.penglixun.com/tech/system/buffer_and_cache_diff.html 今天Twitter上关于Buffer和Cache讨论得... ]]></description>
			<content:encoded><![CDATA[<p><span style="color: #888888;">本文内容遵从<a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh" target="_blank">CC版权协议</a>, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明</br>网址: http://www.penglixun.com/tech/system/buffer_and_cache_diff.html </p>
<p></span>今天Twitter上关于Buffer和Cache讨论得蛮火的，被各种说话一搅和，有点乱了，就干脆整理一下。<br />
首先从翻译上，Buffer应该翻译为“缓冲”，Cache应该翻译为“缓存”，两个完全不是一个东西。<br />
在硬件这一层看，Buffer应该为内存，Cache为CPU集成的告诉缓存。<br />
Buffer为了让不同速度的设备能够同步，建立的一个缓冲区域，写进Buffer的数据是为了从中拿出写入其他设备。<br />
Cache是为了提高读取速度，将经常或马上需要的数据预读到缓存中，写进Cache的数据是为了其他设备从中去读取。<br />
从软件这一层来说，Buffer是块设备的缓冲，Cache是文件系统的缓存。以Linux为例，<br />
Buffer(Buffer Cache)以块形式缓冲了块设备的操作，定时或手动的同步到硬盘，它是为了缓冲写操作然后一次性将很多改动写入硬盘，避免频繁写硬盘，提高写入效率。<br />
Cache(Page Cache)以页面形式缓存了文件系统的文件，给需要使用的程序读取，它是为了给读操作提供缓冲，避免频繁读硬盘，提高读取效率。<br />
总而言之，Buffer里面的东西是为了写到别处去，Cache里面的东西是为了给别处读。<br />
我的理解就是这样，欢迎大牛拍砖～</p><h2  class="related_post_title">类似的文章</h2><ul class="related_post"><li>2010年08月27日 -- <a href="http://www.penglixun.com/tech/system/linux_cache_discovery.html" title="Linux Cache 机制探究">Linux Cache 机制探究</a> (1)</li><li>2010年06月22日 -- <a href="http://www.penglixun.com/tech/database/database_algorithm_and_data_structure_cache_buffer_lock.html" title="数据库算法与数据结构——Cache&#038;Buffer&#038;Lock">数据库算法与数据结构——Cache&#038;Buffer&#038;Lock</a> (1)</li><li>2009年10月29日 -- <a href="http://www.penglixun.com/tech/system/the_diffrents_of_page_cache_and_buffer_cache.html" title="Page Cache和Buffer Cache的区别">Page Cache和Buffer Cache的区别</a> (0)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.penglixun.com/tech/system/buffer_and_cache_diff.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>配置全功能Cacti</title>
		<link>http://www.penglixun.com/tech/system/configure_all_function_cacti.html</link>
		<comments>http://www.penglixun.com/tech/system/configure_all_function_cacti.html#comments</comments>
		<pubDate>Tue, 17 Nov 2009 08:48:43 +0000</pubDate>
		<dc:creator>P.Linux</dc:creator>
				<category><![CDATA[操作系统]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[Cacti]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Memcached]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Nigix]]></category>

		<guid isPermaLink="false">http://www.penglixun.com/PLX/Blog/?p=535</guid>
		<description><![CDATA[本文内容遵从CC版权协议, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://www.penglixun.com/tech/system/configure_all_function_cacti.html 今天终于配置好了Cacti，加入... ]]></description>
			<content:encoded><![CDATA[<p><span style="color: #888888;">本文内容遵从<a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh" target="_blank">CC版权协议</a>, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明</br>网址: http://www.penglixun.com/tech/system/configure_all_function_cacti.html </p>
<p></span>今天终于配置好了Cacti，加入了MySQL/Linux/Apache/Memcached/Nigix模板。<br />
主要遇到的一个问题是修改轮询时间，默认5分钟，我想改成1分钟。<br />
要修改的地方是/etc/cron.d/cacti，改成1分钟间隔，*/<span style="color: #ff0000;">1 </span>* * * * root php /var/www/cacti/poller.php &amp;&gt;/dev/null<br />
然后最好先设置好轮询间隔再导入模板，这样可以在导入的时候把模板的间隔也改掉，否则要手动去改。<br />
修改了轮询时间需要重建轮询索引，最好还要关闭所有的设备再启动，怕有轮询器还没关闭。</p>
<p>过程很多地方有了：<br />
1062错误的解决方法：</p>
<p>http://yadayadayada.nl/archives/2009/04/000779-tuning_cacti_with_the_spine_poller_the_solution.html</p>
<p>http://yadayadayada.nl/archives/2008/11/000750-tuning_cacti_with_the_spine_poller_mysql_error_1062_.html</p>
<p>采用<acronym title="Secure Shell">SSH</acronym>方式监控：http://code.google.com/p/mysql-cacti-templates/wiki/SSHBasedTemplates<br />
MySQL模板安装方法：http://xok.la/2009/05/cacti_mysql_monitor.html<br />
Cacti源代码安装方法：http://www.askwan.com/post/48/<br />
Cacti中文版安装方法：http://hi.baidu.com/%C2%ED%B3%A4%D5%F72008/blog/item/566cbb440ac6742fcefca347.html</p><h2  class="related_post_title">类似的文章</h2><ul class="related_post"><li>2012年01月23日 -- <a href="http://www.penglixun.com/tech/database/case_about_innodb_faster_than_oracle.html" title="一个InnoDB性能超过Oracle的调优Case">一个InnoDB性能超过Oracle的调优Case</a> (1)</li><li>2009年12月15日 -- <a href="http://www.penglixun.com/tech/system/memcached_complete_analyze.html" title="[转] memcached完全剖析">[转] memcached完全剖析</a> (0)</li><li>2009年10月25日 -- <a href="http://www.penglixun.com/tech/database/mysql_gui_tool_in_linux.html" title="MySQL GUI Tool在Linux下运行">MySQL GUI Tool在Linux下运行</a> (0)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.penglixun.com/tech/system/configure_all_function_cacti.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[转]iostat来对Linux硬盘IO性能进行了解</title>
		<link>http://www.penglixun.com/tech/system/use_iostat_analyse_linux_disks.html</link>
		<comments>http://www.penglixun.com/tech/system/use_iostat_analyse_linux_disks.html#comments</comments>
		<pubDate>Fri, 30 Oct 2009 02:48:22 +0000</pubDate>
		<dc:creator>P.Linux</dc:creator>
				<category><![CDATA[操作系统]]></category>
		<category><![CDATA[iostat]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://www.penglixun.com/PLX/Blog/?p=510</guid>
		<description><![CDATA[本文内容遵从CC版权协议, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://www.penglixun.com/tech/system/use_iostat_analyse_linux_disks.html 转载本站文章请注明，转载... ]]></description>
			<content:encoded><![CDATA[<p><span style="color: #888888;">本文内容遵从<a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh" target="_blank">CC版权协议</a>, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明</br>网址: http://www.penglixun.com/tech/system/use_iostat_analyse_linux_disks.html </p>
<p></span>
<div>
<p>转载本站文章请注明，转载自：<strong>扶凯</strong>[<a href="http://www.php-oa.com/">http://www.php-oa.com</a>]</p>
<p>本文链接: <a title="iostat来对linux硬盘IO性能进行了解" href="http://www.php-oa.com/2009/02/03/iostat.html">http://www.php-oa.com/2009/02/03/iostat.html</a></p>
<p>以前一直不太会用这个参数。现在认真研究了一下iostat，因为刚好有台重要的服务器压力高,所以放上来分析一下.下面这台就是IO有压力过大的服务器</p>
<p><strong># iostat -x 1 10</strong><br />
Linux 2.6.18-92.el5xen    02/03/2009</p>
<p>avg-cpu:  %user   %nice %system %iowait  %steal   %idle<br />
1.10    0.00    4.82   39.54    0.07   54.46</p>
<p>Device:         rrqm/s   wrqm/s   r/s   w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await  svctm  %util<br />
sda               0.00     3.50  0.40  2.50     5.60    48.00    18.48     0.00    0.97   0.97   0.28<br />
sdb               0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00<br />
sdc               0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00<br />
sdd               0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00<br />
sde               0.00     0.10  0.30  0.20     2.40     2.40     9.60     0.00    1.60   1.60   0.08<br />
sdf              17.40     0.50 102.00  0.20 12095.20     5.60   118.40     0.70    6.81   2.09  21.36<br />
sdg             232.40     1.90 379.70  0.50 76451.20    19.20   201.13     4.94   13.78   2.45  93.16</p>
<p><strong><span id="more-510"></span>rrqm/s:</strong> 每秒进行 merge 的读操作数目。即 delta(rmerge)/s<br />
<strong>wrqm/s:</strong> 每秒进行 merge 的写操作数目。即 delta(wmerge)/s<br />
<strong>r/s:</strong> 每秒完成的读 I/O 设备次数。即 delta(rio)/s<br />
<strong>w/s:</strong> 每秒完成的写 I/O 设备次数。即 delta(wio)/s<br />
<strong>rsec/s:</strong> 每秒读扇区数。即 delta(rsect)/s<br />
<strong>wsec/s: </strong>每秒写扇区数。即 delta(wsect)/s<br />
<strong>rkB/s: </strong> 每秒读K字节数。是 rsect/s 的一半，因为每扇区大小为512字节。(需要计算)<br />
<strong>wkB/s:</strong> 每秒写K字节数。是 wsect/s 的一半。(需要计算)<br />
<strong>avgrq-sz: </strong>平均每次设备I/O操作的数据大小 (扇区)。delta(rsect+wsect)/delta(rio+wio)<br />
<strong>avgqu-sz:</strong> 平均I/O队列长度。即 delta(aveq)/s/1000 (因为aveq的单位为毫秒)。<br />
<strong>await:</strong> 平均每次设备I/O操作的等待时间 (毫秒)。即 delta(ruse+wuse)/delta(rio+wio)<br />
<strong>svctm: </strong>平均每次设备I/O操作的服务时间 (毫秒)。即 delta(use)/delta(rio+wio)<br />
<strong>%util: </strong>一秒中有百分之多少的时间用于 I/O 操作，或者说一秒中有多少时间 I/O 队列是非空的。即 delta(use)/s/1000 (因为use的单位为毫秒)</p>
<p><strong>如果 %util 接近 100%，说明产生的I/O请求太多，I/O系统已经满负荷，该磁盘<br />
可能存在瓶颈。<br />
idle小于70% IO压力就较大了,一般读取速度有较多的wait.</strong><br />
<strong>同时可以结合vmstat 查看查看b参数(<span style="font-family: verdana,arial,helvetica; font-size: x-small;">等待资源的进程数</span>)和wa参数(<span style="font-family: verdana,arial,helvetica; font-size: x-small;">IO等待所占用的CPU时间的百分比,高过30%时IO压力高</span>)</strong></p>
<p><strong>另外还可以参考</strong><br />
svctm 一般要小于 await (因为同时等待的请求的等待时间被重复计算了)，svctm 的大小一般和磁盘性能有关，CPU/内存的负荷也会对其有影响，请求过多也会间接导致 svctm 的增加。await 的大小一般取决于服务时间(svctm) 以及 I/O 队列的长度和 I/O 请求的发出模式。如果 svctm 比较接近 await，说明 I/O 几乎没有等待时间；如果 await 远大于 svctm，说明 I/O 队列太长，应用得到的响应时间变慢，如果响应时间超过了用户可以容许的范围，这时可以考虑更换更快的磁盘，调整内核 elevator 算法，优化应用，或者升级 CPU。<br />
队列长度(avgqu-sz)也可作为衡量系统 I/O 负荷的指标，但由于 avgqu-sz 是按照单位时间的平均值，所以不能反映瞬间的 I/O 洪水。</p>
<p><strong><br />
别人一个不错的例子.(I/O 系统 vs. 超市排队)</strong></p>
<p>举一个例子，我们在超市排队 checkout 时，怎么决定该去哪个交款台呢? 首当是看排的队人数，5个人总比20人要快吧? 除了数人头，我们也常常看看前面人购买的东西多少，如果前面有个采购了一星期食品的大妈，那么可以考虑换个队排了。还有就是收银员的速度了，如果碰上了连 钱都点不清楚的新手，那就有的等了。另外，时机也很重要，可能 5 分钟前还人满为患的收款台，现在已是人去楼空，这时候交款可是很爽啊，当然，前提是那过去的 5 分钟里所做的事情比排队要有意义 (不过我还没发现什么事情比排队还无聊的)。</p>
<p>I/O 系统也和超市排队有很多类似之处:</p>
<p>r/s+w/s 类似于交款人的总数<br />
平均队列长度(avgqu-sz)类似于单位时间里平均排队人的个数<br />
平均服务时间(svctm)类似于收银员的收款速度<br />
平均等待时间(await)类似于平均每人的等待时间<br />
平均I/O数据(avgrq-sz)类似于平均每人所买的东西多少<br />
I/O 操作率 (%util)类似于收款台前有人排队的时间比例。</p>
<p>我们可以根据这些数据分析出 I/O 请求的模式，以及 I/O 的速度和响应时间。</p>
<p><strong>下面是别人写的这个参数输出的分析</strong></p>
<p># iostat -x 1<br />
avg-cpu:  %user   %nice    %sys   %idle<br />
16.24    0.00    4.31   79.44<br />
Device:    rrqm/s wrqm/s   r/s   w/s  rsec/s  wsec/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %util<br />
/dev/cciss/c0d0<br />
0.00  44.90  1.02 27.55    8.16  579.59     4.08   289.80    20.57    22.35   78.21   5.00  14.29<br />
/dev/cciss/c0d0p1<br />
0.00  44.90  1.02 27.55    8.16  579.59     4.08   289.80    20.57    22.35   78.21   5.00  14.29<br />
/dev/cciss/c0d0p2<br />
0.00   0.00  0.00  0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00</p>
<p>上面的 iostat 输出表明秒有 28.57 次设备 I/O 操作: 总IO(io)/s = r/s(读) +w/s(写) = 1.02+27.55 = 28.57 (次/秒) 其中写操作占了主体 (w:r = 27:1)。</p>
<p>平均每次设备 I/O 操作只需要 5ms 就可以完成，但每个 I/O 请求却需要等上 78ms，为什么? 因为发出的 I/O 请求太多 (每秒钟约 29 个)，假设这些请求是同时发出的，那么平均等待时间可以这样计算:</p>
<p>平均等待时间 = 单个 I/O 服务时间 * ( 1 + 2 + … + 请求总数-1) / 请求总数</p>
<p>应用到上面的例子: 平均等待时间 = 5ms * (1+2+…+28)/29 = 70ms，和 iostat 给出的78ms 的平均等待时间很接近。这反过来表明 I/O 是同时发起的。</p>
<p>每秒发出的 I/O 请求很多 (约 29 个)，平均队列却不长 (只有 2 个 左右)，这表明这 29 个请求的到来并不均匀，大部分时间 I/O 是空闲的。</p>
<p>一秒中有 14.29% 的时间 I/O 队列中是有请求的，也就是说，85.71% 的时间里 I/O 系统无事可做，所有 29 个 I/O 请求都在142毫秒之内处理掉了。</p>
<p>delta(ruse+wuse)/delta(io) = await = 78.21 =&gt; delta(ruse+wuse)/s =78.21 * delta(io)/s = 78.21*28.57 = 2232.8，表明每秒内的I/O请求总共需要等待2232.8ms。所以平均队列长度应为 2232.8ms/1000ms = 2.23，而 iostat 给出的平均队列长度 (avgqu-sz) 却为 22.35，为什么?! 因为 iostat 中有 bug，avgqu-sz 值应为 2.23，而不是 22.35。</p></div><h2  class="related_post_title">类似的文章</h2><ul class="related_post"><li>2009年10月21日 -- <a href="http://www.penglixun.com/tech/system/commond_watch_linux_system_resources.html" title="[转]Linux中查看系统资源占用情况的命令">[转]Linux中查看系统资源占用情况的命令</a> (0)</li><li>2012年01月23日 -- <a href="http://www.penglixun.com/tech/database/case_about_innodb_faster_than_oracle.html" title="一个InnoDB性能超过Oracle的调优Case">一个InnoDB性能超过Oracle的调优Case</a> (1)</li><li>2010年08月27日 -- <a href="http://www.penglixun.com/tech/system/linux_cache_discovery.html" title="Linux Cache 机制探究">Linux Cache 机制探究</a> (1)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.penglixun.com/tech/system/use_iostat_analyse_linux_disks.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL GUI Tool在Linux下运行</title>
		<link>http://www.penglixun.com/tech/database/mysql_gui_tool_in_linux.html</link>
		<comments>http://www.penglixun.com/tech/database/mysql_gui_tool_in_linux.html#comments</comments>
		<pubDate>Sat, 24 Oct 2009 16:34:22 +0000</pubDate>
		<dc:creator>P.Linux</dc:creator>
				<category><![CDATA[数据库]]></category>
		<category><![CDATA[GUI]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Tool]]></category>

		<guid isPermaLink="false">http://www.penglixun.com/PLX/Blog/?p=459</guid>
		<description><![CDATA[本文内容遵从CC版权协议, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://www.penglixun.com/tech/database/mysql_gui_tool_in_linux.html 一运行就报错，说gtkmm找不到，... ]]></description>
			<content:encoded><![CDATA[<p><span style="color: #888888;">本文内容遵从<a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh" target="_blank">CC版权协议</a>, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明</br>网址: http://www.penglixun.com/tech/database/mysql_gui_tool_in_linux.html </p>
<p></span>一运行就报错，说gtkmm找不到，那我yum install gtkmm*。<br />
再运行又说libprce.so.3找不到，搜索lib文件夹，有libprece.so.0，做个软链接，还说不行。<br />
我崩溃了……<br />
点开mysql-gui-tool-5.0目录中的一个连接文件，猛然发现，指向的链接是/opt/mysql-gui-tool-5.0，我那个汗那……<br />
把目录拷贝到/opt下，果然可以运行了……<br />
我成吉思汗……</p><h2  class="related_post_title">类似的文章</h2><ul class="related_post"><li>2012年01月23日 -- <a href="http://www.penglixun.com/tech/database/case_about_innodb_faster_than_oracle.html" title="一个InnoDB性能超过Oracle的调优Case">一个InnoDB性能超过Oracle的调优Case</a> (1)</li><li>2009年11月17日 -- <a href="http://www.penglixun.com/tech/system/configure_all_function_cacti.html" title="配置全功能Cacti">配置全功能Cacti</a> (0)</li><li>2009年07月9日 -- <a href="http://www.penglixun.com/tech/program/add_database_module_for_php.html" title="为PHP添加数据库模块">为PHP添加数据库模块</a> (0)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.penglixun.com/tech/database/mysql_gui_tool_in_linux.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[转]Linux中查看系统资源占用情况的命令</title>
		<link>http://www.penglixun.com/tech/system/commond_watch_linux_system_resources.html</link>
		<comments>http://www.penglixun.com/tech/system/commond_watch_linux_system_resources.html#comments</comments>
		<pubDate>Wed, 21 Oct 2009 09:54:58 +0000</pubDate>
		<dc:creator>P.Linux</dc:creator>
				<category><![CDATA[操作系统]]></category>
		<category><![CDATA[free]]></category>
		<category><![CDATA[iostat]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[top]]></category>
		<category><![CDATA[uptime]]></category>
		<category><![CDATA[vmstat]]></category>

		<guid isPermaLink="false">http://www.penglixun.com/PLX/Blog/?p=440</guid>
		<description><![CDATA[本文内容遵从CC版权协议, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://www.penglixun.com/tech/system/commond_watch_linux_system_resources.html top: 主要参数 d：指定更... ]]></description>
			<content:encoded><![CDATA[<p><span style="color: #888888;">本文内容遵从<a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh" target="_blank">CC版权协议</a>, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明</br>网址: http://www.penglixun.com/tech/system/commond_watch_linux_system_resources.html </p>
<p></span><span style="font-size: large;"><strong>top</strong>:</span><br />
主要参数<br />
d：指定更新的间隔，以秒计算。<br />
q：没有任何延迟的更新。如果使用者有超级用户，则top命令将会以最高的优先序执行。<br />
c：显示进程完整的路径与名称。<br />
S：累积模式，会将己完成或消失的子行程的CPU时间累积起来。<br />
s：安全模式。<br />
i：不显示任何闲置(Idle)或无用(Zombie)的行程。<br />
n：显示更新的次数，完成后将会退出to<br />
显示参数:<br />
PID（Process ID）：进程标示号。<br />
USER：进程所有者的用户名。<br />
PR：进程的优先级别。<br />
NI：进程的优先级别数值。<br />
VIRT：进程占用的虚拟内存值。<br />
RES：进程占用的物理内存值。<br />
SHR：进程使用的共享内存值。<br />
S：进程的状态，其中S表示休眠，R表示正在运行，Z表示僵死状态，N表示该进程优先值是负数。<br />
%CPU：该进程占用的CPU使用率。<br />
%MEM：该进程占用的物理内存和总内存的百分比。<br />
TIME＋：该进程启动后占用的总的CPU时间。<br />
Command：进程启动的启动命令名称，如果这一行显示不下，进程会有一个完整的命令行。<br />
top命令使用过程中，还可以使用一些交互的命令来完成其它参数的功能。这些命令是通过快捷键启动的。<br />
&lt;空格&gt;：立刻刷新。<br />
P：根据CPU使用大小进行排序。<br />
T：根据时间、累计时间排序。<br />
q：退出top命令。<br />
m：切换显示内存信息。<br />
t：切换显示进程和CPU状态信息。<br />
c：切换显示命令名称和完整命令行。<br />
M：根据使用内存大小进行排序。<br />
W：将当前设置写入~/.toprc文件中。这是写top配置文件的推荐方法。</p>
<p><strong><span style="font-size: large;"><span id="more-440"></span>free</span></strong><br />
1.作用<br />
free命令用来显示内存的使用情况，使用权限是所有用户。</p>
<p>2.格式<br />
free [－b－k－m] [－o] [－s delay] [－t] [－V]</p>
<p>3.主要参数<br />
－b －k －m：分别以字节（<acronym title="Kilobyte">KB</acronym>、<acronym title="Megabyte">MB</acronym>）为单位显示内存使用情况。<br />
－s delay：显示每隔多少秒数来显示一次内存使用情况。<br />
－t：显示内存总和列。<br />
－o：不显示缓冲区调节列。</p>
<p><strong><span style="font-size: large;">uptime</span></strong><br />
18:59:15 up 25 min,  2 users,  load average: 1.23, 1.32, 1.21<br />
现在的时间<br />
系统开机运转到现在经过的时间<br />
连线的使用者数量<br />
最近一分钟，五分钟和十五分钟的系统负载<br />
参数： -V 显示版本资讯。</p>
<p><strong><span style="font-size: large;">vmstat</span></strong><br />
procs &#8212;&#8212;&#8212;&#8211;memory&#8212;&#8212;&#8212;- &#8212;swap&#8211; &#8212;&#8211;io&#8212;- &#8211;system&#8211; &#8212;-cpu&#8212;-<br />
r  b   swpd free   buff   cache    si   so    bi     bo    in    cs   us  sy  id wa<br />
0  1  24980 10792 8296  47316    5   19   205    52  1161   698  26  3  1  70<br />
1 观察磁盘活动情况<br />
磁盘活动情况主要从以下几个指标了解：<br />
bi：表示从磁盘每秒读取的块数(blocks/s)。数字越大，表示读磁盘的活动越多。<br />
bo：表示每秒写到磁盘的块数（blocks/s）。数字越大，表示写磁盘的活动越多。<br />
wa：cpu等待磁盘I／O（未决的磁盘IO）的时间比例。数字越大，表示文件系统活动阻碍cpu的情况越严重，因为cpu在等待慢速的磁盘系统提供数据。wa为0是最理想的。如果wa经常大于10，可能文件系统就需要进行性能调整了。<br />
2 观察cpu活动情况<br />
vmstat比top更能反映出cpu的使用情况：<br />
us：用户程序使用cpu的时间比例。这个数字越大，表示用户进程越繁忙。<br />
sy：系统调用使用cpu的时间比例。注意，NFS由于是在内核里面运行的，所以NFS活动所占用的cpu时间反映在sy里面。这个数字经常很大 的话，就需要注意是否某个内核进程，比如NFS任务比较繁重。如果us和sy同时都比较大的话，就需要考虑将某些用户程序分离到另外的服务器上面，以免互 相影响。<br />
id：cpu空闲的时间比例。<br />
wa：cpu等待未决的磁盘IO的时间比例。</p>
<p><strong><span style="font-size: large;">iostat</span></strong><br />
用于统计CPU的使用情况及tty设备、硬盘和<acronym title="Compact Disc">CD</acronym>-ROM的I/0量<br />
参数:<br />
-c      只显示CPU行<br />
-d      显示磁盘行<br />
-k      以千字节为单位显示磁盘输出<br />
-t       在输出中包括时间戳<br />
-x      在输出中包括扩展的磁盘指标</p>
<p>avg-cpu:  %user   %nice    %sys %iowait   %idle<br />
20.25    0.18    2.61   76.39    0.57<br />
%iowait 等待本地I/O时CPU空闲时间的百分比<br />
%idle 未等待本地I/O时CPU空闲时间的百分比</p>
<p>Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn<br />
hda               9.86       284.34        84.48     685407     2036<br />
每秒传输数（tps）、每秒512字节块读取数（Blk_read/s）、每秒512字节块写入数（Blk_wrtn/s）和512字节块读取（Blk_read）和写入（Blk_wrtn）的总数量。</p><h2  class="related_post_title">类似的文章</h2><ul class="related_post"><li>2010年08月10日 -- <a href="http://www.penglixun.com/tech/system/how_to_calc_load_cpu.html" title="Load和CPU利用率是如何算出来的">Load和CPU利用率是如何算出来的</a> (5)</li><li>2009年10月30日 -- <a href="http://www.penglixun.com/tech/system/use_iostat_analyse_linux_disks.html" title="[转]iostat来对Linux硬盘IO性能进行了解">[转]iostat来对Linux硬盘IO性能进行了解</a> (0)</li><li>2012年01月23日 -- <a href="http://www.penglixun.com/tech/database/case_about_innodb_faster_than_oracle.html" title="一个InnoDB性能超过Oracle的调优Case">一个InnoDB性能超过Oracle的调优Case</a> (1)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.penglixun.com/tech/system/commond_watch_linux_system_resources.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Linux硬盘读写性能测试</title>
		<link>http://www.penglixun.com/tech/system/linux_harddisk_io_test.html</link>
		<comments>http://www.penglixun.com/tech/system/linux_harddisk_io_test.html#comments</comments>
		<pubDate>Wed, 21 Oct 2009 09:22:48 +0000</pubDate>
		<dc:creator>P.Linux</dc:creator>
				<category><![CDATA[操作系统]]></category>
		<category><![CDATA[hdparm]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[性能]]></category>
		<category><![CDATA[测试]]></category>
		<category><![CDATA[硬盘]]></category>

		<guid isPermaLink="false">http://www.penglixun.com/PLX/Blog/?p=439</guid>
		<description><![CDATA[本文内容遵从CC版权协议, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://www.penglixun.com/tech/system/linux_harddisk_io_test.html 为了了解公司服务器的具体性能，... ]]></description>
			<content:encoded><![CDATA[<p><span style="color: #888888;">本文内容遵从<a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh" target="_blank">CC版权协议</a>, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明</br>网址: http://www.penglixun.com/tech/system/linux_harddisk_io_test.html </p>
<p></span>为了了解公司服务器的具体性能，好制定预警和监控脚本，今天全面测了一下服务器的性能指标，其中测硬盘的需要记录下，今天才学的。<br />
读取测试采用hdparm进行：<br />
脚本如下：<br />
for i in 1 2 3 4 5 6 7 8 9 10;<br />
do<br />
sleep 10;<br />
echo $&#8217;\n&#8217; $i;<br />
hdparm -tT /dev/sda;<br />
done</p>
<p>写入测试注意把写入的文件放到tmp或其他无关紧要的位置，否则后果自负。<br />
脚本如下。<br />
for i in 1 2 3 4 5 6 7 8 9 10;<br />
do<br />
sleep 10;<br />
echo $&#8217;\n&#8217; $i;<br />
dd if=/dev/zero of=/tmp/hdparm_write$i.tmp ibs=1M obs=1M count=1024;<br />
done<br />
这将反复写1M的内容1024次到文件中，最后会以M/s的单位告诉测试结果。<br />
测完以后全部记录下来。</p><h2  class="related_post_title">类似的文章</h2><ul class="related_post"><li>2009年10月20日 -- <a href="http://www.penglixun.com/tech/system/understand_linux_performance.html" title="[转]理解Linux的性能 ">[转]理解Linux的性能 </a> (0)</li><li>2012年01月23日 -- <a href="http://www.penglixun.com/tech/database/case_about_innodb_faster_than_oracle.html" title="一个InnoDB性能超过Oracle的调优Case">一个InnoDB性能超过Oracle的调优Case</a> (1)</li><li>2010年08月27日 -- <a href="http://www.penglixun.com/tech/system/linux_cache_discovery.html" title="Linux Cache 机制探究">Linux Cache 机制探究</a> (1)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.penglixun.com/tech/system/linux_harddisk_io_test.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[转]手工释放Linux内存——/proc/sys/vm/drop_caches</title>
		<link>http://www.penglixun.com/tech/system/manual_free_linux_memory.html</link>
		<comments>http://www.penglixun.com/tech/system/manual_free_linux_memory.html#comments</comments>
		<pubDate>Tue, 20 Oct 2009 04:56:25 +0000</pubDate>
		<dc:creator>P.Linux</dc:creator>
				<category><![CDATA[操作系统]]></category>
		<category><![CDATA[Cache]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[内存]]></category>

		<guid isPermaLink="false">http://www.penglixun.com/PLX/Blog/?p=433</guid>
		<description><![CDATA[本文内容遵从CC版权协议, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://www.penglixun.com/tech/system/manual_free_linux_memory.html 原文地址：http://www.linuxfly.org/post/... ]]></description>
			<content:encoded><![CDATA[<p><span style="color: #888888;">本文内容遵从<a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh" target="_blank">CC版权协议</a>, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明</br>网址: http://www.penglixun.com/tech/system/manual_free_linux_memory.html </p>
<p></span>原文地址：http://www.linuxfly.org/post/320/</p>
<p>总有很多朋友对于Linux的内存管理有疑问，之前一篇<a href="http://www.linuxfly.org/post/114/" target="_blank">[转]理解Linux的性能</a>日志似乎也没能清除大家的疑虑。而在新版核心中，似乎对这个问题提供了新的解决方法，特转出来给大家参考一下。最后，还附上我对这方法的意见，欢迎各位一同讨论。</p>
<p>当在Linux下频繁存取文件后，物理内存会很快被用光，当程序结束后，内存不会被正常释放，而是一直作为caching。这个问题，貌似有不少人在问，不过都没有看到有什么很好解决的办法。那么我来谈谈这个问题。<br />
<span id="more-433"></span><br />
<strong><span style="color: #4169e1;">一、通常情况</span></strong><br />
先来说说free命令：</p>
<div>
<div>引用</div>
<div>[root@server ~]# free -m<br />
total used free shared buffers cached<br />
Mem: 249 163 86 0 10 94<br />
-/+ buffers/cache: 58 191<br />
Swap: 511 0 511</div>
</div>
<p>其中：</p>
<div>
<div>引用</div>
<div>total 内存总数<br />
used 已经使用的内存数<br />
free 空闲的内存数<br />
shared 多个进程共享的内存总额<br />
buffers Buffer Cache和cached Page Cache 磁盘缓存的大小<br />
-buffers/cache 的内存数:used &#8211; buffers &#8211; cached<br />
+buffers/cache 的内存数:free + buffers + cached</div>
</div>
<p>可用的<span style="color: #ff0000;">memory=free memory+buffers+cached</span>。</p>
<p>有了这个基础后，可以得知，我现在used为163MB，free为86MB，buffer和cached分别为10MB，94MB。<br />
那么我们来看看,如果我执行复制文件,内存会发生什么变化.</p>
<div>
<div>引用</div>
<div>[root@server ~]# cp -r /etc ~/test/<br />
[root@server ~]# free -m<br />
total used free shared buffers cached<br />
Mem: 249 244 4 0 8 174<br />
-/+ buffers/cache: 62 187<br />
Swap: 511 0 511</div>
</div>
<p>在我命令执行结束后，used为244MB，free为4MB，buffers为8MB，cached为174MB，天呐，都被cached吃掉了。别紧张，这是为了提高文件读取效率的做法。</p>
<p>为 了提高磁盘存取效率，Linux做了一些精心的设计，除了对dentry进行缓存（用于VFS，加速文件路径名到inode的转换），还采取了两种主要 Cache方式：Buffer Cache和Page Cache。前者针对磁盘块的读写，后者针对文件inode的读写。这些Cache有效缩短了 I/O系统调用（比如read，write，getdents）的时间。</p>
<p>那么有人说过段时间，linux会自动释放掉所用的内存。等待一段时间后，我们使用free再来试试，看看是否有释放？</p>
<div>
<div>引用</div>
<div>[root@server test]# free -m<br />
total used free shared buffers cached<br />
Mem: 249 244 5 0 8 174<br />
-/+ buffers/cache: 61 188<br />
Swap: 511 0 511</div>
</div>
<p>似乎没有任何变化。（实际情况下，内存的管理还与Swap有关）</p>
<p>那么我能否手动释放掉这些内存呢？回答是可以的！</p>
<p><strong><span style="color: #4169e1;">二、手动释放缓存</span></strong><br />
/proc 是一个虚拟文件系统，我们可以通过对它的读写操作做为与kernel实体间进行通信的一种手段。也就是说可以通过修改/proc中的文件，来对当前 kernel的行为做出调整。那么我们可以通过调整/proc/sys/vm/drop_caches来释放内存。操作如下：</p>
<div>
<div>引用</div>
<div>[root@server test]# cat /proc/sys/vm/drop_caches<br />
0</div>
</div>
<p>首先，/proc/sys/vm/drop_caches的值，默认为0。</p>
<div>
<div>引用</div>
<div>[root@server test]# sync</div>
</div>
<p>手动执行sync命令（描述：sync 命令运行 sync 子例程。如果必须停止系统，则运行sync 命令以确保文件系统的完整性。sync 命令将所有未写的系统缓冲区写到磁盘中，包含已修改的 i-node、已延迟的块 I/O 和读写映射文件）</p>
<div>
<div>引用</div>
<div>[root@server test]# echo 3 &gt; /proc/sys/vm/drop_caches<br />
[root@server test]# cat /proc/sys/vm/drop_caches<br />
3</div>
</div>
<p>将/proc/sys/vm/drop_caches值设为3</p>
<div>
<div>引用</div>
<div>[root@server test]# free -m<br />
total used free shared buffers cached<br />
Mem: 249 66 182 0 0 11<br />
-/+ buffers/cache: 55 194<br />
Swap: 511 0 511</div>
</div>
<p>再来运行free命令，会发现现在的used为66MB，free为182MB，buffers为0MB，cached为11MB。那么有效的释放了buffer和cache。</p>
<p>◎ 有关/proc/sys/vm/drop_caches的用法在下面进行了说明</p>
<div>
<div>引用</div>
<div>/proc/sys/vm/drop_caches <span style="color: #ff0000;">(since Linux 2.6.16)</span><br />
Writing to this file causes the kernel to drop clean caches,<br />
dentries and inodes from memory, causing that memory to become<br />
free.</div>
<p>To free pagecache, use echo 1 &gt; /proc/sys/vm/drop_caches; to<br />
free dentries and inodes, use echo 2 &gt; /proc/sys/vm/drop_caches;<br />
to free pagecache, dentries and inodes, use echo 3 &gt;<br />
/proc/sys/vm/drop_caches.</p>
<p>Because this is a non-destructive operation and dirty objects<br />
are not freeable, the user should run sync first.</p></div>
<p><strong><span style="color: #4169e1;">三、我的意见</span></strong><br />
上述文章就长期以来很多用户对Linux内存管理方面的疑问，给出了一个比较“直观”的回复，我更觉得有点像是核心开发小组的妥协。<br />
对于是否需要使用这个值，或向用户提及这个值，我是有保留意见的：</p>
<div>
<div>引用</div>
<div>1、从man可以看到，这值从2.6.16以后的核心版本才提供，也就是老版的操作系统，如红旗DC 5.0、RHEL 4.x之前的版本都没有；<br />
2、若对于系统内存是否够用的观察，我还是原意去看swap的使用率和si/so两个值的大小；</div>
</div>
<p>用户常见的疑问是，为什么free这么小，是否关闭应用后内存没有释放？<br />
但实际上，我们都知道这是因为Linux对内存的管理与Windows不同，free小并不是说内存不够用了，应该看的是free的第二行最后一个值：</p>
<div>
<div>引用</div>
<div>-/+ buffers/cache: 58 <span style="color: #ff0000;">191</span></div>
</div>
<p>这才是系统可用的内存大小。<br />
实际项目中告诉我们，如果因为是应用有像内存泄露、溢出的问题，从swap的使用情况是可以比较快速可以判断的，但free上面反而比较难查看。<br />
相反，如果在这个时候，我们告诉用户，修改系统的一个值，“可以”释放内存，free就大了。用户会怎么想？不会觉得操作系统“有问题”吗？<br />
所以说，我觉得既然核心是可以快速清空buffer或cache，也不难做到（这从上面的操作中可以明显看到），但核心并没有这样做（默认值是0），我们就不应该随便去改变它。<br />
一般情况下，应用在系统上稳定运行了，free值也会保持在一个稳定值的，虽然看上去可能比较小。<br />
当发生内存不足、应用获取不到可用内存、OOM错误等问题时，<span style="color: #ff0000;">还是更应该去分析应用方面的原因</span>，如用户量太大导致内存不足、发生应用内存溢出等情况，否则，清空buffer，强制腾出free的大小，<span style="color: #ff0000;">可能只是把问题给暂时屏蔽了</span>。</p>
<p>我 觉得，排除内存不足的情况外，除非是在软件开发阶段，需要临时清掉buffer，以判断应用的内存使用情况；或应用已经不再提供支持，即使应用对内存的时 候确实有问题，而且无法避免的情况下，才考虑定时清空buffer。（可惜，这样的应用通常都是运行在老的操作系统版本上，上面的操作也解决不了）。 O(∩_∩)O哈哈~</p><h2  class="related_post_title">类似的文章</h2><ul class="related_post"><li>2010年08月27日 -- <a href="http://www.penglixun.com/tech/system/linux_cache_discovery.html" title="Linux Cache 机制探究">Linux Cache 机制探究</a> (1)</li><li>2009年12月14日 -- <a href="http://www.penglixun.com/tech/system/buffer_and_cache_diff.html" title="Buffer与Cache">Buffer与Cache</a> (1)</li><li>2012年01月23日 -- <a href="http://www.penglixun.com/tech/database/case_about_innodb_faster_than_oracle.html" title="一个InnoDB性能超过Oracle的调优Case">一个InnoDB性能超过Oracle的调优Case</a> (1)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.penglixun.com/tech/system/manual_free_linux_memory.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[转]理解Linux的性能</title>
		<link>http://www.penglixun.com/tech/system/understand_linux_performance.html</link>
		<comments>http://www.penglixun.com/tech/system/understand_linux_performance.html#comments</comments>
		<pubDate>Tue, 20 Oct 2009 04:53:56 +0000</pubDate>
		<dc:creator>P.Linux</dc:creator>
				<category><![CDATA[操作系统]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[性能]]></category>

		<guid isPermaLink="false">http://www.penglixun.com/PLX/Blog/?p=431</guid>
		<description><![CDATA[本文内容遵从CC版权协议, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://www.penglixun.com/tech/system/understand_linux_performance.html 原文地址：http://www.linuxfly.org/p... ]]></description>
			<content:encoded><![CDATA[<p><span style="color: #888888;">本文内容遵从<a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh" target="_blank">CC版权协议</a>, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明</br>网址: http://www.penglixun.com/tech/system/understand_linux_performance.html </p>
<p></span>原文地址：http://www.linuxfly.org/post/114/</p>
<p>项目中常遇到需要对目前运行的系统进行效率分析，或碰到客户咨询如何优化系统的效率问题。更多的情况是，在系统出现问题的时候，需要分析原因，定 位系统故障或瓶颈，当然，最好是可以一并解决故障。但实际上，操作系统优化是一个非常复杂的问题，况且linux有自己一套有别于其他操作系统管理的机 制，由此会引起很多不必要的误解和麻烦。自问我是写不错条理性的文章了，只能转一份高人写的文档供参考。<span style="color: #0000ff;"><span style="text-decoration: underline;">（文章根据实际进行了一定的裁减，并对容易碰到的问题做了标识）</span></span><a name="entrymore"></a></p>
<p><span id="more-431"></span><br />
<strong>一、前提</strong><br />
我 们可以在文章的开始就列出一个列表，列出可能影响Linux操作系统性能的一些调优参数，但这样做其实并没有什么价值。因为性能调优是一个非常困难的任 务，它要求对硬件、操作系统、和应用都有着相当深入的了解。如果性能调优非常简单的话，那些我们要列出的调优参数早就写入硬件的微码或者操作系统中了，我 们就没有必要再继续读这篇文章了。正如下图所示，服务器的性能受到很多因素的影响。<br />
<a href="http://www.linuxfly.org/attachment/1168940406_0.gif" target="_blank"><img title="点击在新窗口中浏览此图片" src="http://www.linuxfly.org/attachment/1168940406_0.gif" border="0" alt="点击在新窗口中浏览此图片" width="500" /></a><br />
当面对一个使用单独IDE硬盘的，有20000用户的数据库服务器时，即使我们使用数周时间去调整I/O子系统也是徒劳无功的，通常一个新的驱动或者应用程序的一个更新（如<acronym title="Structured Query Language">SQL</acronym>优化）却可以使这个服务器的性能得到明显的提升。正如我们前面提到的，<strong><span style="color: #dc143c;">不要忘记系统的性能是受多方面因素影响的。</span></strong>理解操作系统管理系统资源的方法将帮助我们在面对问题时更好的判断应该对哪个子系统进行调整。<br />
<strong>二、Linux的CPU调度</strong><br />
任 何计算机的基本功能都十分简单，那就是计算。为了实现计算的功能就必须有一个方法去管理计算资源、处理器和计算任务（也被叫做线程或者进程）。非常感谢 Ingo Molnar，他为Linux内核带来了O（1）CPU调度器，区别于旧有的O（n）调度器，新的调度器是动态的，可以支持负载均衡，并以恒定的速度进行 操作。<br />
新调度器的可扩展性非常好，无论进程数量或者处理器数量，并且调度器本身的系统开销更少。新调取器的算法使用两个优先级队列。</p>
<div>
<div>引用</div>
<div>·活动运行队列<br />
·过期运行队列</div>
</div>
<p>调 度器的一个重要目标是根据优先级权限有效地为进程分配CPU 时间片，当分配完成后它被列在CPU的运行队列中，除了 CPU 的运行队列之外，还有一个过期运行队列。当活动运行队列中的一个任务用光自己的时间片之后，它就被移动到过期运行队列中。在移动过程中，会对其时间片重新 进行计算。如果活动运行队列中已经没有某个给定优先级的任务了，那么指向活动运行队列和过期运行队列的指针就会交换，这样就可以让过期优先级列表变成活动 优先级的列表。通常交互式进程（相对与实时进程而言）都有一个较高的优先级，它占有更长的时间片，比低优先级的进程获得更多的计算时间，但通过调度器自身 的调整并不会使低优先级的进程完全被饿死。<strong><span style="color: #ff0000;">新调度器的优势是显著的改变Linux内核的可扩展性，使新内核可以更好的处理一些有大量进程、大量处理器组成的企业级应用。</span></strong>新的O(1)调度器包含仔2.6内核中，但是也向下兼容2.4内核。<br />
<a href="http://www.linuxfly.org/attachment/1168940734_0.gif" target="_blank"><img title="点击在新窗口中浏览此图片" src="http://www.linuxfly.org/attachment/1168940734_0.gif" border="0" alt="点击在新窗口中浏览此图片" width="500" /></a><br />
新调度器另外一个重要的优势是体现在对NUMA(non-uniform memory architecture)和SMP（symmetric multithreading processors）的支持上，例如INTEL@的超线程技术。<br />
改进的NUMA支持保证了负载均衡不会发生在CECs或者NUMA节点之间，除非发生一个节点的超出负载限度。<br />
<strong>三、Linux的内存架构</strong><br />
今天我们面对选择32位操作系统还是64位操作系统的情况。对企业级用户它们之间最大的区别是64位操作系统可以支持大于4GB的内存寻址。从性能角度来讲，我们需要了解32位和64位操作系统都是如何进行物理内存和虚拟内存的映射的。<br />
<a href="http://www.linuxfly.org/attachment/1168940954_0.gif" target="_blank"><img title="点击在新窗口中浏览此图片" src="http://www.linuxfly.org/attachment/1168940954_0.gif" border="0" alt="点击在新窗口中浏览此图片" width="500" /></a><br />
在上面图示中我们可以看到64位和32位Linux内核在寻址上有着显著的不同。<br />
在 32位架构中，比如IA-32，Linux内核可以直接寻址的范围只有物理内存的第一个<acronym title="Gigabyte">GB</acronym>（如果去掉保留部分还剩下896MB），访问内存必须被映射到 这小于1GB的所谓ZONE_NORMAL空间中，这个操作是由应用程序完成的。但是分配在ZONE_HIGHMEM中的内存页将导致性能的降低。<br />
在 另一方面，64位架构比如x86-64（也称作EM64T或者AMD64）。ZONE_NORMAL空间将扩展到64GB或者128GB（实际上可以更 多，但是这个数值受到操作系统本身支持内存容量的限制）。正如我们看到的，使用64位操作系统我们排除了因ZONE_HIGHMEM部分内存对性能的影响 的情况。<br />
<strong><span style="color: #4169e1;">实际中，在32位架构下，由于上面所描述的内存寻址问题，对于大内存，高负载应用，会导致死机或严重缓慢等问题。虽然使用hugemen核心可缓解，但采取x86_64架构是最佳的解决办法。</span></strong><br />
<strong>四、虚拟内存管理</strong><br />
因 为操作系统将内存都映射为虚拟内存，所以操作系统的物理内存结构对用户和应用来说通常都是不可见的。如果想要理解Linux系统内存的调优，我们必须了解 Linux的虚拟内存机制。应用程序并不分配物理内存，而是向Linux内核请求一部分映射为虚拟内存的内存空间。如下图所示虚拟内存并不一定是映射物理 内存中的空间，如果应用程序有一个大容量的请求，也可能会被映射到在磁盘子系统中的swap空间中。<br />
<a href="http://www.linuxfly.org/attachment/1168941286_0.gif" target="_blank"><img title="点击在新窗口中浏览此图片" src="http://www.linuxfly.org/attachment/1168941286_0.gif" border="0" alt="点击在新窗口中浏览此图片" width="500" /></a><br />
另外要提到的是，通常应用程序不直接将数据写到磁盘子系统中，而是写入缓存和缓冲区中。<strong><span style="color: #800080;">Bdflush守护进程将定时将缓存或者缓冲区中的数据写到硬盘上。</span></strong><br />
Linux内核处理数据写入磁盘子系统和管理磁盘缓存是紧密联系在一起的。<strong><span style="color: #ff0000;">相对于其他的操作系统都是在内存中分配指定的一部分作为磁盘缓存，Linux处理内存更加有效，默认情况下虚拟内存管理器分配所有可用内存空间作为磁盘缓存，这就是为什么有时我们观察一个配置有数G内存的Linux系统可用内存只有20MB的原因。</span></strong><br />
同 时Linux使用swap空间的机制也是相当高效率的，如上图所示虚拟内存空间是由物理内存和磁盘子系统中的swap空间共同组成的。如果虚拟内存管理器 发现一个已经分配完成的内存分页已经长时间没有被调用，它将把这部分内存分页移到swap空间中。经常我们会发现一些守护进程，比如getty，会随系统 启动但是却很少会被应用到。这时为了释放昂贵的主内存资源，系统会将这部分内存分页移动到swap空间中。<strong><span style="color: #ff0000;">上述就是Linux使用swap空间的机制，当swap分区使用超过50％时，并不意味着物理内存的使用已经达到瓶颈了，swap空间只是Linux内核更好的使用系统资源的一种方法。</span></strong><br />
<span style="color: #00008b;"><span style="text-decoration: underline;">简单理解：Swap usage只表示了Linux管理内存的有效性。对识别内存瓶颈来说，Swap In/Out才是一个比较又意义的依据，如果Swap In/Out的值长期保持在每秒200到300个页面通常就表示系统可能存在内存的瓶颈。下面的事例是好的状态：</span></span></p>
<div>
<div>引用</div>
<div># vmstat<br />
procs &#8212;&#8212;&#8212;&#8211;memory&#8212;&#8212;&#8212;&#8212;-     &#8212;swap&#8211;   &#8212;&#8211;io&#8212;-   &#8211;system&#8211;    &#8212;-cpu&#8212;-<br />
r  b   swpd   free    buff  cache        <strong><span style="color: #ff1493;">si   so</span></strong> bi    bo     in    cs      us sy id wa<br />
1  0   5696   6904  28192  50496    0    0      88   117   61    29    11  8 80  1</div>
</div>
<p><strong>五、模块化的I/O调度器</strong><br />
就 象我们知道的Linux2.6内核为我们带来了很多新的特性，这其中就包括了新的I/O调度机制。旧的2.4内核使用一个单一的I/O调度器，2.6内核 为我们提供了四个可选择的I/O调度器。因为Linux系统应用在很广阔的范围里，不同的应用对I/O设备和负载的要求都不相同，例如一个笔记本电脑和一 个10000用户的数据库服务器对I/O的要求肯定有着很大的区别。</p>
<div>
<div>引用</div>
<div>（1）．Anticipatory<br />
anticipatory I/O调度器创建假设一个块设备只有一个物理的查找磁头（例如一个单独的SATA硬盘），正如anticipatory调度器名字一 样，anticipatory调度器使用“anticipatory”的算法写入硬盘一个比较大的数据流代替写入多个随机的小的数据流，这样有可能导致写 I/O操作的一些延时。这个调度器适用于通常的一些应用，比如大部分的个人电脑。<br />
（2）．Complete Fair Queuing (CFQ)<br />
Complete Fair Queuing（CFQ）调度器是Red Flag DC Server 5使用的标准算法。<strong><span style="color: #dc143c;">CFQ调度器使用<acronym title="Quality of Service">QoS</acronym>策略为系统内的所有任务分配相同的带宽。CFQ调度器适用于有大量计算进程的多用户系统。</span></strong>它试图避免进程被饿死和实现了比较低的延迟。<br />
（3）．Deadline<br />
deadline调度器是使用deadline算法的轮询的调度器，提供对I/O子系统接近实时的操作，deadline调度器提供了很小的延迟和维持一个很好的磁盘吞吐量。如果使用deadline算法请确保进程资源分配不会出现问题。<br />
（4）．NOOP<br />
NOOP调度器是一个简化的调度程序它只作最基本的合并与排序。与桌面系统的关系不是很大，主要用在一些特殊的软件与硬件环境下，这些软件与硬件一般都拥有自己的调度机制对内核支持的要求很小，这很适合一些嵌入式系统环境。作为桌面用户我们一般不会选择它。</div>
</div>
<p><strong>六、网络子系统</strong><br />
新 的网络中断缓和（NAPI）对网络子系统带来了改变，提高了大流量网络的性能。Linux内核在处理网络堆栈时，相比降低系统占用率和高吞吐量更关注可靠 性和低延迟。所以在某些情况下，Linux建立一个防火墙或者文件、打印、数据库等企业级应用的性能可能会低于相同配置的Windows服务器。<br />
在 传统的处理网络封包的方式中，如下图蓝色箭头所描述的，一个以太网封包到达网卡接口后，如果MAC地址相符合会被送到网卡的缓冲区中。网卡然后将封包移到 操作系统内核的网络缓冲区中并且对CPU发出一个硬中断，CPU会处理这个封包到相应的网络堆栈中，可能是一个TCP端口或者Apache应用中。<br />
<a href="http://www.linuxfly.org/attachment/1168941826_0.gif" target="_blank"><img title="点击在新窗口中浏览此图片" src="http://www.linuxfly.org/attachment/1168941826_0.gif" border="0" alt="点击在新窗口中浏览此图片" width="500" /></a><br />
这是一个处理网络封包的简单的流程，但从中我们可以看到这个处理方式的缺点。正如我们看到的，<span style="color: #ffa500;">每 次适合网络封包到达网络接口都将对CPU发出一个硬中断信号，中断CPU正在处理的其他任务，导致切换动作和对CPU缓存的操作。你可能认为当只有少量的 网络封包到达网卡的情况下这并不是个问题，但是千兆网络和现代的应用将带来每秒钟成千上万的网络数据，这就有可能对性能造成不良的影响。</span><br />
正 是因为这个情况，NAPI在处理网络通讯的时候引入了计数机制。对第一个封包，NAPI以传统的方式进行处理，但是对后面的封包，网卡引入了POLL的轮 询机制：如果一个封包在网卡DMA环的缓存中，就不再为这个封包申请新的中断，直到最后一个封包被处理或者缓冲区被耗尽。这样就有效的减少了因为过多的中 断CPU对系统性能的影响。同时，NAPI通过创建可以被多处理器执行的软中断改善了系统的可扩展性。NAPI将为大量的企业级多处理器平台带来帮助，它<strong><span style="color: #ffa500;">要求一个启用NAPI的驱动程序</span></strong>。在今天很多驱动程序默认没有启用NAPI，这就为我们调优网络子系统的性能提供了更广阔的空间。<br />
<strong>七、理解Linux调优参数</strong><br />
因 为Linux是一个开源操作系统，所以又大量可用的性能监测工具。对这些工具的选择取决于你的个人喜好和对数据细节的要求。所有的性能监测工具都是按照同 样的规则来工作的，所以无论你使用哪种监测工具都需要理解这些参数。下面列出了一些重要的参数，有效的理解它们是很有用处的。<br />
（1）处理器参数</p>
<div>
<div>引用</div>
<div>·CPU utilization<br />
这是一个很简单的参数，它直观的描述了每个CPU的利用率。在xSeries架构中，如果CPU的利用率长时间的超过80％，就可能是出现了处理器的瓶颈。<br />
·Runable processes<br />
这个值描述了正在准备被执行的进程，在一个持续时间里这个值不应该超过物理CPU数量的10倍，否则CPU方面就可能存在瓶颈。<br />
·Blocked<br />
描述了那些因为等待I/O操作结束而不能被执行的进程，Blocked可能指出你正面临I/O瓶颈。<br />
·User time<br />
描述了处理用户进程的百分比，包括nice time。如果User time的值很高，说明系统性能用在处理实际的工作。<br />
·System time<br />
描述了CPU花费在处理内核操作包括IRQ和软件中断上面的百分比。如果system time很高说明系统可能存在网络或者驱动堆栈方面的瓶颈。一个系统通常只花费很少的时间去处理内核的操作。<br />
·Idle time<br />
描述了CPU空闲的百分比。<br />
·Nice time<br />
描述了CPU花费在处理re-nicing进程的百分比。<br />
·Context switch<br />
系统中线程之间进行交换的数量。<br />
·Waiting<br />
CPU花费在等待I/O操作上的总时间，与blocked相似，一个系统不应该花费太多的时间在等待I/O操作上，否则你应该进一步检测I/O子系统是否存在瓶颈。<br />
·Interrupts<br />
Interrupts 值包括硬Interrupts和软Interrupts，硬Interrupts会对系统性能带来更多的不利影响。高的Interrupts值指出系统可 能存在一个软件的瓶颈，可能是内核或者驱动程序。注意Interrupts值中包括CPU时钟导致的中断（现代的xServer系统每秒1000个 Interrupts值）。</div>
</div>
<p>（2）内存参数</p>
<div>
<div>引用</div>
<div>·Free memory<br />
相比其他操作系统，Linux空闲内存的值不应该做为一个性能参考的重要指标，因为就像我们之前提到过的，Linux内核会分配大量没有被使用的内存作为文件系统的缓存，所以这个值通常都比较小。<br />
·Swap usage<br />
这 个值描述了已经被使用的swap空间。Swap usage只表示了Linux管理内存的有效性。对识别内存瓶颈来说，Swap In/Out才是一个比较又意义的依据，如果Swap In/Out的值长期保持在每秒200到300个页面通常就表示系统可能存在内存的瓶颈。<br />
·Buffer and cache<br />
这个值描述了为文件系统和块设备分配的缓存。在Red Flag DC Server 5版本中,你可以通过修改/proc/sys/vm中的page_cache_tuning来调整空闲内存中作为缓存的数量。<br />
·Slabs<br />
描述了内核使用的内存空间，注意内核的页面是不能被交换到磁盘上的。<br />
·Active versus inactive memory<br />
提供了关于系统内存的active内存信息，Inactive内存是被kswapd守护进程交换到磁盘上的空间。</div>
</div>
<p>（3）网络参数</p>
<div>
<div>引用</div>
<div>·Packets received and sent<br />
这个参数表示了一个指定网卡接收和发送的数据包的数量。<br />
·Bytes received and sent<br />
这个参数表示了一个指定网卡接收和发送的数据包的字节数。<br />
·Collisions per second<br />
这个值提供了发生在指定网卡上的网络冲突的数量。持续的出现这个值代表在网络架构上出现了瓶颈，而不是在服务器端出现的问题。在正常配置的网络中冲突是非常少见的，除非用户的网络环境都是由hub组成。<br />
·Packets dropped<br />
这个值表示了被内核丢掉的数据包数量，可能是因为防火墙或者是网络缓存的缺乏。<br />
·Overruns<br />
Overruns表达了超出网络接口缓存的次数，这个参数应该和packets dropped值联系到一起来判断是否存在在网络缓存或者网络队列过长方面的瓶颈。<br />
·Errors<br />
这个值记录了标志为失败的帧的数量。这个可能由错误的网络配置或者部分网线损坏导致，在铜口千兆以太网环境中部分网线的损害是影响性能的一个重要因素。</div>
</div>
<p>（4）块设备参数</p>
<div>
<div>引用</div>
<div>·Iowait<br />
CPU等待I/O操作所花费的时间。这个值持续很高通常可能是I/O瓶颈所导致的。<br />
·Average queue length<br />
I/O请求的数量，通常一个磁盘队列值为2到3为最佳情况，更高的值说明系统可能存在I/O瓶颈。<br />
·Average wait<br />
响应一个I/O操作的平均时间。Average wait包括实际I/O操作的时间和在I/O队列里等待的时间。<br />
·Transfers per second<br />
描述每秒执行多少次I/O操作（包括读和写）。Transfers per second的值与kBytes per second结合起来可以帮助你估计系统的平均传输块大小，这个传输块大小通常和磁盘子系统的条带化大小相符合可以获得最好的性能。<br />
·Blocks read/write per second<br />
这个值表达了每秒读写的blocks数量，在2.6内核中blocks是1024bytes，在早些的内核版本中blocks可以是不同的大小，从512bytes到4kb。<br />
·Kilobytes per second read/write<br />
按照kb为单位表示读写块设备的实际数据的数量。</div>
</div>
<p><strong>八、附录</strong><br />
本文截取和修改自IBM的红皮书Tuning Red Hat Enterprise Linux on IBM eServer xSeries Servers。</p><h2  class="related_post_title">类似的文章</h2><ul class="related_post"><li>2009年10月21日 -- <a href="http://www.penglixun.com/tech/system/linux_harddisk_io_test.html" title="Linux硬盘读写性能测试">Linux硬盘读写性能测试</a> (0)</li><li>2012年01月23日 -- <a href="http://www.penglixun.com/tech/database/case_about_innodb_faster_than_oracle.html" title="一个InnoDB性能超过Oracle的调优Case">一个InnoDB性能超过Oracle的调优Case</a> (1)</li><li>2010年08月27日 -- <a href="http://www.penglixun.com/tech/system/linux_cache_discovery.html" title="Linux Cache 机制探究">Linux Cache 机制探究</a> (1)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.penglixun.com/tech/system/understand_linux_performance.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>为PHP添加数据库模块</title>
		<link>http://www.penglixun.com/tech/program/add_database_module_for_php.html</link>
		<comments>http://www.penglixun.com/tech/program/add_database_module_for_php.html#comments</comments>
		<pubDate>Thu, 09 Jul 2009 01:06:26 +0000</pubDate>
		<dc:creator>P.Linux</dc:creator>
				<category><![CDATA[程序设计]]></category>
		<category><![CDATA[Centos]]></category>
		<category><![CDATA[eGroupWare]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[PDO]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Suse]]></category>

		<guid isPermaLink="false">http://www.penglixun.com/PLX/Blog/?p=259</guid>
		<description><![CDATA[本文内容遵从CC版权协议, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://www.penglixun.com/tech/program/add_database_module_for_php.html 今天为工作室部署协同办公平... ]]></description>
			<content:encoded><![CDATA[<p><span style="color: #888888;">本文内容遵从<a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh" target="_blank">CC版权协议</a>, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明</br>网址: http://www.penglixun.com/tech/program/add_database_module_for_php.html </p>
<p></span>今天为工作室部署协同办公平台OA，经过一些选择，最终选择了eGroupWare作为平台，感觉还比较不错，开源阵营的存在确实为咱们做IT的带来了不少便利。（我极少贡献代码，惭愧……）</p>
<p><span id="more-259"></span></p>
<p>然后开始部署，首先在自己的CentOS上部署比较顺利，一次成功，在Suse上部署的时候，因为老师事先装好的Apache/<acronym title="Pre-Hypertext Processing">PHP</acronym>环境我不熟悉，摸索了一阵，不过还是弄好了。<br />
主要的问题就是把PDO_MySQL/PDO_OCI编译到<acronym title="Pre-Hypertext Processing">PHP</acronym>中。因为老师已经部署过了<acronym title="Pre-Hypertext Processing">PHP</acronym>，于是我采用外部扩展的方式添加PDO模块。<br />
经我研究貌似PDO_$1.so和$1.so同时需要，缺一不可，不知道是不是只有eGroupWare这样，还是用了某种方式就会。因为我自己测试的时候，只有mysql.so也能连接成功数据库，请看到的高手为我解释下PDO_$1.so和$1.so的关系，3Q~</p>
<p>然后编译的过程遇到的一些问题，在这里记录下来。<br />
首先编译OCI8，<br />
1、下载Oracle即时客户端程序包 — Basic： 运行 OCI、OCCI 和 JDBC-OCI 应用程序所需的所有文件<br />
①、打开以下网址（本文以32位版为例）：<br />
（Linux 32位版）http://www.oracle.com/technology/software/tech/oci/instantclient/htdocs/linuxsoft.html<br />
②、下载以下几个文件：<br />
oracle-instantclient11.1-basic-11.1.0.7.0-1.i386.rpm<br />
oracle-instantclient11.1-devel-11.1.0.7.0-1.i386.rpm<br />
oracle-instantclient11.1-sqlplus-11.1.0.7.0-1.i386.rpm</p>
<p>2、安装Oracle即时客户端程序包<br />
#rpm -ivh oracle-instantclient11.1-basic-11.1.0.7.0-1.i386.rpm oracle-instantclient11.1-devel-11.1.0.7.0-1.i386.rpm oracle-instantclient11.1-sqlplus-11.1.0.7.0-1.i386.rpm<br />
#echo “/usr/lib/oracle/11.1/client/lib/” &gt; /etc/ld.so.conf.d/oracle_client.conf<br />
#/sbin/ldconfig</p>
<p>3、安装OCI8 <acronym title="Pre-Hypertext Processing">PHP</acronym>扩展（使用<acronym title="Pre-Hypertext Processing">PHP</acronym>自带的OCI8，假设<acronym title="Pre-Hypertext Processing">PHP</acronym>程序安装在/usr/local/webserver/php/）<br />
#yum install libaio<br />
#wget http://pecl.php.net/get/oci8-1.3.5.tgz<br />
#tar zxvf oci8-1.3.5.tgz<br />
#cd oci8-1.3.5/<br />
#/usr/local/webserver/php/bin/phpize<br />
#CFLAGS=”-I/usr/include/oracle/11.1/client/”<br />
#CXXFLAGS=”-I/usr/include/oracle/11.1/client/”<br />
#./configure &#8211;with-php-config=/usr/local/php/bin/php-config &#8211;with-oci8=instantclient,/usr/lib/oracle/11.1/client/lib/<br />
#make<br />
#make install</p>
<p>4、修改<acronym title="Pre-Hypertext Processing">PHP</acronym>配置文件（/usr/local/webserver/php/etc/php.ini）<br />
extension = “/usr/local/webserver/php/lib/php/extensions/no-debug-non-zts-20060613/oci8.so”</p>
<p>5、重启Apache</p>
<p>编译PDO_OCI，<br />
1、安装 re2c<br />
wget http://downloads.sourceforge.net/re2c/re2c-0.12.3.tar.gz<br />
./configure<br />
make<br />
make install</p>
<p>2、安装 pdo_oci<br />
wget http://pecl.php.net/get/PDO_OCI-1.0.tgz<br />
tar xzvf PDO_OCI-1.0.tgz<br />
cd PDO_OCI-1.0<br />
/usr/local/php/bin/phpize</p>
<p>对刚安装的 oracle-instantclient11.1-basic 与 oracle-instantclient11.1-devel进行设置<br />
ln -s /usr/include/oracle/11.1 /usr/include/oracle/10.2.0.1<br />
ln -s /usr/lib/oracle/11.1 /usr/lib/oracle/10.2.0.1</p>
<p>./configure &#8211;with-pdo-oci=instantclient,/usr,10.2.0.1<br />
注意,按网上的教程./configure &#8211;with-pdo-oci=instantclient,<span style="color: #ff0000;">/usr/lib/oracle/11.1/client64</span>,11.1<br />
则会到<span style="color: #ff0000;">/usr/lib/oracle/11.1/client64</span><span style="color: #3366ff;">/lib/oracle/11.1/client/lib</span> 下面去寻找oci.h等header文件, 所以只能是<br />
./configure &#8211;with-pdo-oci=instantclient,/usr,11.1 但会报错 configure: error: Unsupported Oracle version! 11.1<br />
所以最终只能是<br />
./configure &#8211;with-pdo-oci=instantclient,/usr,10.2.0.1<br />
同理/usr/lib/client64</p>
<p>3、 安装后生成pdo_oci.so在下面目录<br />
/usr/local/php/lib/php/extensions/no-debug-non-zts-yyyymmdd/pdo_oci.so<br />
移动它到/usr/local/php/lib/php/extensions/目录下<br />
mv /usr/local/php/lib/php/extensions/no-debug-non-zts-yyyymmdd/pdo_oci.so ../</p>
<p>添加<br />
extension = pdo_oci.so<br />
extension = oci8.so</p>
<p>5)重新启动apache<br />
/usr/local/apache/bin/apachectl restart<br />
或<br />
service httpd restart</p><h2  class="related_post_title">类似的文章</h2><ul class="related_post"><li>2012年01月23日 -- <a href="http://www.penglixun.com/tech/database/case_about_innodb_faster_than_oracle.html" title="一个InnoDB性能超过Oracle的调优Case">一个InnoDB性能超过Oracle的调优Case</a> (1)</li><li>2010年01月18日 -- <a href="http://www.penglixun.com/tech/system/linux_compile_php_error.html" title="Linux下编译PHP的几种错误">Linux下编译PHP的几种错误</a> (1)</li><li>2009年11月17日 -- <a href="http://www.penglixun.com/tech/system/configure_all_function_cacti.html" title="配置全功能Cacti">配置全功能Cacti</a> (0)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.penglixun.com/tech/program/add_database_module_for_php.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>load average概念理解</title>
		<link>http://www.penglixun.com/tech/system/load_average_concept.html</link>
		<comments>http://www.penglixun.com/tech/system/load_average_concept.html#comments</comments>
		<pubDate>Sun, 24 May 2009 07:33:06 +0000</pubDate>
		<dc:creator>P.Linux</dc:creator>
				<category><![CDATA[操作系统]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[load average]]></category>
		<category><![CDATA[服务器]]></category>

		<guid isPermaLink="false">http://www.penglixun.com/PLX/Blog/?p=232</guid>
		<description><![CDATA[本文内容遵从CC版权协议, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://www.penglixun.com/tech/system/load_average_concept.html 草履虫跟我说服务器load average疯长, ... ]]></description>
			<content:encoded><![CDATA[<p><span style="color: #888888;">本文内容遵从<a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh" target="_blank">CC版权协议</a>, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明</br>网址: http://www.penglixun.com/tech/system/load_average_concept.html </p>
<p></span>草履虫跟我说服务器load average疯长, 我就查了下load average的概念。</p>
<p>load average说明:<br />
在Linux系统中，uptime、w、top等命令都会有系统平均负载load average的输出，那么什么是系统平均负载呢？<br />
　　系统平均负载被定义为在特定时间间隔内运行队列中的平均进程树。如果一个进程满足以下条件则其就会位于运行队列中：<br />
　　- 它没有在等待I/O操作的结果<br />
　　- 它没有主动进入等待状态(也就是没有调用&#8217;wait&#8217;)<br />
　　- 没有被停止(例如：等待终止)<br />
　　例如：<br />
　　[root@www2 init.d]# uptime<br />
　　7:51pm up 2 days, 5:43, 2 users, load average: 8.13, 5.90, 4.94<br />
　　命令输出的最后内容表示在过去的1、5、15分钟内运行队列中的平均进程数量。<br />
　　一般来说只要每个CPU的当前活动进程数不大于3那么系统的性能就是良好的，如果每个CPU的任务数大于5，那么就表示这台机器的性能有严重问题。对 于上面的例子来说，假设系统有两个CPU，那么其每个CPU的当前任务数为：8.13/2=4.065。这表示该系统的性能是可以接受的。<br />
load average也可以理解为每秒钟CPU等待运行的进程个数吧^_^</p><h2  class="related_post_title">类似的文章</h2><ul class="related_post"><li>2009年05月24日 -- <a href="http://www.penglixun.com/tech/system/tuning_redhat_enterprise_linux_in_ibm_system_x_server.html" title="RedHat Enterprise Linux在IBM System x服务器上的调优">RedHat Enterprise Linux在IBM System x服务器上的调优</a> (0)</li><li>2012年01月23日 -- <a href="http://www.penglixun.com/tech/database/case_about_innodb_faster_than_oracle.html" title="一个InnoDB性能超过Oracle的调优Case">一个InnoDB性能超过Oracle的调优Case</a> (1)</li><li>2010年08月27日 -- <a href="http://www.penglixun.com/tech/system/linux_cache_discovery.html" title="Linux Cache 机制探究">Linux Cache 机制探究</a> (1)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.penglixun.com/tech/system/load_average_concept.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RedHat Enterprise Linux在IBM System x服务器上的调优</title>
		<link>http://www.penglixun.com/tech/system/tuning_redhat_enterprise_linux_in_ibm_system_x_server.html</link>
		<comments>http://www.penglixun.com/tech/system/tuning_redhat_enterprise_linux_in_ibm_system_x_server.html#comments</comments>
		<pubDate>Sun, 24 May 2009 07:30:24 +0000</pubDate>
		<dc:creator>P.Linux</dc:creator>
				<category><![CDATA[操作系统]]></category>
		<category><![CDATA[IBM]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[RHEL]]></category>
		<category><![CDATA[服务器]]></category>
		<category><![CDATA[调优]]></category>

		<guid isPermaLink="false">http://www.penglixun.com/PLX/Blog/?p=230</guid>
		<description><![CDATA[一.理解Linux的性能我们可以在文章的开始就列出一个列表，列出可能影响Linux操作系统性能的一些调优参数，但这样做其实并没有什么价值。因为性能调优是一个非常困难的任务，它要求对硬件... ]]></description>
			<content:encoded><![CDATA[<p><span style="color: #888888;">本文内容遵从<a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh" target="_blank">CC版权协议</a>, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明</br>网址: http://www.penglixun.com/tech/system/tuning_redhat_enterprise_linux_in_ibm_system_x_server.html </p>
<p></span><strong>一.理解Linux的性能我们可以在文章的开始就列出一个列表，列出可能影响Linux操作系统性能的一些调优参数，但这样做其实并没有什么价值。因为性能调优是一个非常困难的任务，它要求对硬件、操作系统、和应用都有着相当深入的了解。如果性能调优非常简单的话，那些我们要列出的调优参数早就写入硬件的微码或者操作系统中了，我们就没有必要再继续读这篇文章了。</strong>当面对一个使用单独IDE硬盘的有20000用户的数据库服务器时，即使我们使用数周时间去调整I/O子系统也是徒劳无功的，通常一个新的驱动或者应用程序的一个更新却可以使这个服务器的性能得到明显的提升。正如我们前面提到的，不要忘记系统的性能是受多方面因素影响的。理解操作系统管理系统资源的方法将帮助我们在面对问题时更好的判断应该对哪个子系统进行调整。 <span id="more-230"></span></p>
<p>下面的部分对Linux操作系统的架构进行了简单的介绍，对Linux内核的完整的分析超出了我们这本红皮书的内容，感兴趣的读者可以寻找相关文档做更深入的研究。本书对Linux性能的调整主要针对Red Hat发行版本。</p>
<p><strong>1．Linux的CPU调度</strong></p>
<p>任何计算机的基本功能都十分简单，那就是计算。为了实现计算的功能就必须有一个方法去管理计算资源、处理器和计算任务（也被叫做线程或者进程）。非常感谢Ingo Molnar，他为Linux内核带来了O（1）CPU调度器，区别于旧有的O（n）调度器，新的调度器是动态的，可以支持负载均衡，并以恒定的速度进行操作。<br />
新调度器的可扩展性非常好，无论进程数量或者处理器数量，并且调度器本身的系统开销更少。新调取器的算法使用两个优先级队列。<br />
·活动运行队列<br />
·过期运行队列</p>
<p>调度器的一个重要目标是根据优先级权限有效地为进程分配CPU 时间片，当分配完成后它被列在CPU的运行队列中，除了 CPU 的运行队列之外，还有一个过期运行队列。当活动运行队列中的一个任务用光自己的时间片之后，它就被移动到过期运行队列中。在移动过程中，会对其时间片重新进行计算。如果活动运行队列中已经没有某个给定优先级的任务了，那么指向活动运行队列和过期运行队列的指针就会交换，这样就可以让过期优先级列表变成活动优先级的列表。通常交互式进程（相对与实时进程而言）都有一个较高的优先级，它占有更长的时间片，比低优先级的进程获得更多的计算时间，但通过调度器自身的调整并不会使低优先级的进程完全被饿死。新调度器的优势是显著的改变Linux内核的可扩展性，使新内核可以更好的处理一些有大量进程、大量处理器组成的企业级应用。新的O(1)调度器包含仔2.6内核中，但是也向下兼容2.4内核。</p>
<p align="center"><a href="http://www.serverol.com/upimages/tech/XPXP-6VU2R3_4_2007_1_11_21_51_34.gif" target="_blank"><img src="http://www.serverol.com/upimages/tech/XPXP-6VU2R3_4_2007_1_11_21_51_34.gif" border="0" alt="按此在新窗口浏览图片" width="553" height="363" /></a></p>
<p>新调度器另外一个重要的优势是体现在对NUMA(non-uniform memory architecture)和SMP（symmetric multithreading processors）的支持上，例如INTEL@的超线程技术。</p>
<p>改进的NUMA支持保证了负载均衡不会发生在CECs或者NUMA节点之间，除非发生一个节点的超出负载限度。Linux的CPU调度器没有使用大部分UNIX和Windows操作系统使用的进程－线程模式，它只使用了线程。在Linux中一个进程表示为一组线程，可以用线程组ID或者TDGID代替标准UNIX中的进程ID或者PID。然而大多数Linux命令例如ps和top都使用PIDs表达，因此在下面的文章中我们会经常使用进程和线程组。</p>
<p><strong>2．Linux的内存架构</strong></p>
<p>今天我们面对选择32位操作系统还是64位操作系统的情况。对企业级用户它们之间最大的区别是64位操作系统可以支持大于4GB的内存寻址。从性能角度来讲，我们需要了解32位和64位操作系统都是如何进行物理内存和虚拟内存的映射的。</p>
<p>在下面图示中我们可以看到64位和32位Linux内核在寻址上有着显著的不同。探究物理内存到虚拟内存的映射超出了本文研究的范围，因此这里我们只是着重研究一下Linux内存架构的特点。</p>
<p>在32位架构中，比如IA-32，Linux内核可以直接寻址的范围只有物理内存的第一个<acronym title="Gigabyte">GB</acronym>（如果去掉保留部分还剩下896MB），访问内存必须被映射到这小于1GB的所谓ZONE_NORMAL空间中，这个操作是由应用程序完成的。但是分配在ZONE_HIGHMEM中的内存页将导致性能的降低。<br />
在另一方面，64位架构比如x86-64（也称作EM64T或者AMD64）。ZONE_NORMAL空间将扩展到64GB或者128GB（实际上可以更多，但是这个数值受到操作系统本身支持内存容量的限制）。正如我们看到的，使用64位操作系统我们排除了因ZONE_HIGHMEM部分内存对性能的影响的情况。</p>
<p align="center"><a href="http://www.serverol.com/upimages/tech/XPXP-6VU2R3_5_2007_1_11_21_51_59.gif" target="_blank"><img src="http://www.serverol.com/upimages/tech/XPXP-6VU2R3_5_2007_1_11_21_51_59.gif" border="0" alt="按此在新窗口浏览图片" width="553" height="353" /></a></p>
<p><strong>3．虚拟内存管理</strong></p>
<p>因为操作系统将内存都映射为虚拟内存，所以操作系统的物理内存结构对用户和应用来说通常都是不可见的。如果想要理解Linux系统内存的调优，我们必须了解Linux的虚拟内存机制。应用程序并不分配物理内存，而是向Linux内核请求一部分映射为虚拟内存的内存空间。如下图所示虚拟内存并不一定是映射物理内存中的空间，如果应用程序有一个大容量的请求，也可能会被映射到在磁盘子系统中的swap空间中。</p>
<p>另外要提到的是，通常应用程序不直接将数据写到磁盘子系统中，而是写入缓存和缓冲区中。Bdflush守护进程将定时将缓存或者缓冲区中的数据写到硬盘上。</p>
<p>Linux内核处理数据写入磁盘子系统和管理磁盘缓存是紧密联系在一起的。相对于其他的操作系统都是在内存中分配指定的一部分作为磁盘缓存，Linux处理内存更加有效，默认情况下虚拟内存管理器分配所有可用内存空间作为磁盘缓存，这就是为什么有时我们观察一个配置有数G内存的Linux系统可用内存只有20MB的原因。</p>
<p>同时Linux使用swap空间的机制也是相当高效率的，如下图所示虚拟内存空间是由物理内存和磁盘子系统中的swap空间共同组成的。如果虚拟内存管理器发现一个已经分配完成的内存分页已经长时间没有被调用，它将把这部分内存分页移到swap空间中。经常我们会发现一些守护进程，比如getty，会随系统启动但是却很少会被应用到。这时为了释放昂贵的主内存资源，系统会将这部分内存分页移动到swap空间中。上述就是Linux使用swap空间的机制，当swap分区使用超过50％时，并不意味着物理内存的使用已经达到瓶颈了，swap空间只是Linux内核更好的使用系统资源的一种方法。</p>
<p align="center"><a href="http://www.serverol.com/upimages/tech/XPXP-6VU2R3_6_2007_1_11_21_53_33.gif" target="_blank"><img src="http://www.serverol.com/upimages/tech/XPXP-6VU2R3_6_2007_1_11_21_53_33.gif" border="0" alt="按此在新窗口浏览图片" width="546" height="362" /></a></p>
<p><strong>4．模块化的I/O调度器</strong></p>
<p>就象我们知道的Linux2.6内核为我们带来了很多新的特性，这其中就包括了新的I/O调度机制。旧的2.4内核使用一个单一的I/O调度器，2.6内核为我们提供了四个可选择的I/O调度器。因为Linux系统应用在很广阔的范围里，不同的应用对I/O设备和负载的要求都不相同，例如一个笔记本电脑和一个10000用户的数据库服务器对I/O的要求肯定有着很大的区别。</p>
<p>（1）Anticipatory</p>
<p>anticipatory I/O调度器创建假设一个块设备只有一个物理的查找磁头（例如一个单独的SATA硬盘），正如anticipatory调度器名字一样，anticipatory调度器使用“anticipatory”的算法写入硬盘一个比较大的数据流代替写入多个随机的小的数据流，这样有可能导致写I/O操作的一些延时。这个调度器适用于通常的一些应用，比如大部分的个人电脑。</p>
<p>（2）Complete Fair Queuing (CFQ)</p>
<p>Complete Fair Queuing（CFQ）调度器是Red Hat Enterprise Linux使用的标准算法。CFQ调度器使用<acronym title="Quality of Service">QoS</acronym>策略为系统内的所有任务分配相同的带宽。CFQ调度器适用于有大量计算进程的多用户系统。它试图避免进程被饿死和实现了比较低的延迟。</p>
<p>（3）Deadline</p>
<p>deadline调度器是使用deadline算法的轮询的调度器，提供对I/O子系统接近实时的操作，deadline调度器提供了很小的延迟和维持一个很好的磁盘吞吐量。如果使用deadline算法请确保进程资源分配不会出现问题。</p>
<p>（4）NOOP</p>
<p>NOOP调度器是一个简化的调度程序它只作最基本的合并与排序。与桌面系统的关系不是很大，主要用在一些特殊的软件与硬件环境下，这些软件与硬件一般都拥有自己的调度机制对内核支持的要求很小，这很适合一些嵌入式系统环境。作为桌面用户我们一般不会选择它。</p>
<p><strong>5．网络子系统</strong></p>
<p>新的网络中断缓和（NAPI）对网络子系统带来了改变，提高了大流量网络的性能。Linux内核在处理网络堆栈时，相比降低系统占用率和高吞吐量更关注可靠性和低延迟。所以在某些情况下，Linux建立一个防火墙或者文件、打印、数据库等企业级应用的性能可能会低于相同配置的Windows服务器。</p>
<p>在传统的处理网络封包的方式中，如下图蓝色箭头所描述的，一个以太网封包到达网卡接口后，如果MAC地址相符合会被送到网卡的缓冲区中。网卡然后将封包移到操作系统内核的网络缓冲区中并且对CPU发出一个硬中断，CPU会处理这个封包到相应的网络堆栈中，可能是一个TCP端口或者Apache应用中。</p>
<p>这是一个处理网络封包的简单的流程，但从中我们可以看到这个处理方式的缺点。正如我们看到的，每次适合网络封包到达网络接口都将对CPU发出一个硬中断信号，中断CPU正在处理的其他任务，导致切换动作和对CPU缓存的操作。你可能认为当只有少量的网络封包到达网卡的情况下这并不是个问题，但是千兆网络和现代的应用将带来每秒钟成千上万的网络数据，这就有可能对性能造成不良的影响。</p>
<p align="center"><a href="http://www.serverol.com/upimages/tech/XPXP-6VU2R3_7_2007_1_11_21_54_44.gif" target="_blank"><img src="http://www.serverol.com/upimages/tech/XPXP-6VU2R3_7_2007_1_11_21_54_44.gif" border="0" alt="按此在新窗口浏览图片" width="553" height="503" /></a></p>
<p>正是因为这个情况，NAPI在处理网络通讯的时候引入了计数机制。对第一个封包，NAPI以传统的方式进行处理，但是对后面的封包，网卡引入了POLL的轮询机制：如果一个封包在网卡DMA环的缓存中，就不再为这个封包申请新的中断，直到最后一个封包被处理或者缓冲区被耗尽。这样就有效的减少了因为过多的中断CPU对系统性能的影响。同时，NAPI通过创建可以被多处理器执行的软中断改善了系统的可扩展性。NAPI将为大量的企业级多处理器平台带来帮助，它要求一个启用NAPI的驱动程序。在今天很多驱动程序默认没有启用NAPI，这就为我们调优网络子系统的性能提供了更广阔的空间。</p>
<p><strong>6．Linux文件系统</strong></p>
<p>Linux作为一个开源操作系统的优势之一就是为用户提供了多种操作系统的支持。现代Linux内核几乎可以支持所有计算机系统常用的文件系统，从基本的FAT到高性能的文件系统例如JFS。因为Red Hat Enterprise Linux主要支持两种文件系统（ext2和ext3），我们将主要介绍它们的特点，对其他Linux文件系统我们仅做简要介绍。</p>
<p>（1）ext2</p>
<p>ext2文件系统是ext3文件系统的前身。是一个快速、简便的文件系统，它与目前大部分文件系统的显著不同就是ext2不支持日志。</p>
<p>（2）ext3，Red Hat默认的文件系统</p>
<p>自从Red Hat 7.2开始，安装默认的文件系统就是ext3。Ext3是应用广泛的ext2文件系统的更新版本，它加入了对日志的支持。下面列举了这个文件系统的一些特性。<br />
·可用性：ext3可以保证数据写入磁盘的一致性，万一出现了非正常的关机（电源的失效或者系统的崩溃），服务器不需要花费时间去校验数据的一致性，因此极大的减少了系统恢复的时间。</p>
<p>·数据完整性：加入特殊的日志功能，所有数据，包括文件数据和元数据都是有日志记录的。<br />
·速度：通过data=writeback参数，你可以根据应用的需要来调整数据的写入速度。<br />
·灵活性：从ext2转换到ext3文件系统是非常简单的并且不需要重新格式化硬盘。通过执行tune2fs命令和编辑/etc/fstab文件，你可以非常容易的将ext2文件系统更新到ext3文件系统。Ext3文件系统也可以禁用日志后作为ext2使用。利用一些第三方的工具软件可以更灵活的使用ext3文件系统，比如PartitionMagic可以编辑ext3分区。</p>
<p>（3）ReiserFS</p>
<p>ReiserFS是一个快速的日志文件系统，它优化了磁盘空间的使用、加快了故障恢复速度。今天ReiserFS是SUSE Linux默认的文件系统。</p>
<p>（4）JFS</p>
<p>JFS是一个完全64位的文件系统，它可以支持非常大的文件和分区。JFS是由IBM为AIX系统开发的，现在在<acronym title="GNU General Public License">GPL</acronym> license下以及可以使用了。JFS对大容量的分区和文件，尤其是HPC和数据库应用来说是一种理想的操作系统。如果你想了解更多关于JFS的信息，请访问下面链接<br />
<a href="http://jfs.sourceforge.net/" target="_blank"><span style="color: #ff3300;">http://jfs.sourceforge.net</span></a></p>
<p>(5)XFS <br />
XFS是SGI为IRIX系统开发的高性能的日志文件系统。它的特点和应用都和JFS相当接近。</p>
<p><strong>7．Proc文件系统</strong></p>
<p>proc文件系统不是一个实时文件系统，但是它的作用却非常大。它提供了一个运行中的内核的接口，并不存储实际的数据。Proc文件系统使系统管理员可以监控和调整内核运行状态。下图描述了一个proc文件系统的示例，大部分Linux性能调优工具都需要借助proc文件系统的信息来进行工作。</p>
<p align="center"><a href="http://www.serverol.com/upimages/tech/XPXP-6VU2R3_8_2007_1_11_21_56_25.gif" target="_blank"><img src="http://www.serverol.com/upimages/tech/XPXP-6VU2R3_8_2007_1_11_21_56_25.gif" border="0" alt="按此在新窗口浏览图片" width="391" height="770" /></a></p>
<p>在proc文件系统中，我们可以看到分别记录不同信息的多个子目录，但是proc目录下的大部分文件可读性都不是很强，建议最好使用可读性更强的工具例如vmstat等来查看proc中记录的信息。请牢记proc目录的相应目录结构。</p>
<p>·在/proc目录下的文件</p>
<p>proc根目录下保存着一些记录了系统信息的文件，这些文件你可以通过vmstat和cpuinfo等工具来读取。</p>
<p>·数字1到X</p>
<p>各个以数字为名称的文件夹，代表的是运行进程的PID。例如，目录1记录了init进程的一些统计信息。</p>
<p>·acpiapci是一个现代桌面和笔记本电脑的电源配置和管理接口，因为apci主要是一个个人电脑的技术，所以在一些服务器系统上经常被禁用。可以访问下面链接获得更多acpi的相关信息<a href="http://www.apci.info/" target="_blank"><span style="color: #ff3300;">http://www.apci.info</span></a></p>
<p>·bus</p>
<p>这个子目录记录了系统的总线子系统的信息，例如pci总线或者usb接口。</p>
<p>·irq</p>
<p>irq子目录下记录了系统的中断信息。</p>
<p>·net</p>
<p>net子目录记录了一些关于你的网卡的重要信息，比如接收的多点广播封包或者每个网卡的路由。</p>
<p>·scsi</p>
<p>scsi子目录包含了关于系统的scsi子系统的信息，例如连接的设备或者驱动的版本。ips子目录是记录关于IBM ServerRAID阵列卡信息的。</p>
<p>·sys</p>
<p>sys目录下包含了一些可以调整的内核参数。</p>
<p>·tty</p>
<p>tty子目录包含了系统虚拟终端的信息。</p>
<p><strong>8．理解Linux调优参数</strong></p>
<p>在我们介绍Linux系统的各种调优参数和性能监测工具之前，需要先讨论一些关于性能调优的参数。因为Linux是一个开源操作系统，所以又大量可用的性能监测工具。对这些工具的选择取决于你的个人喜好和对数据细节的要求。所有的性能监测工具都是按照同样的规则来工作的，所以无论你使用哪种监测工具都需要理解这些参数。下面列出了一些重要的参数，有效的理解它们是很有用处的。</p>
<p>（1）处理器参数</p>
<p>·CPU utilization</p>
<p>这是一个很简单的参数，它直观的描述了每个CPU的利用率。在xSeries架构中，如果CPU的利用率长时间的超过80％，就可能是出现了处理器的瓶颈。</p>
<p>·Runable processes</p>
<p>这个值描述了正在准备被执行的进程，在一个持续时间里这个值不应该超过物理CPU数量的10倍，否则CPU方面就可能存在瓶颈。</p>
<p>·Blocked</p>
<p>描述了那些因为等待I/O操作结束而不能被执行的进程，Blocked可能指出你正面临I/O瓶颈。</p>
<p>·User time</p>
<p>描述了处理用户进程的百分比，包括nice time。如果User time的值很高，说明系统性能用在处理实际的工作。</p>
<p>·System time</p>
<p>描述了CPU花费在处理内核操作包括IRQ和软件中断上面的百分比。如果system time很高说明系统可能存在网络或者驱动堆栈方面的瓶颈。一个系统通常只花费很少的时间去处理内核的操作。</p>
<p>·Idle time</p>
<p>描述了CPU空闲的百分比。</p>
<p>·Nice time</p>
<p>描述了CPU花费在处理re-nicing进程的百分比。</p>
<p>·Context switch</p>
<p>系统中线程之间进行交换的数量。</p>
<p>·Waiting</p>
<p>CPU花费在等待I/O操作上的总时间，与blocked相似，一个系统不应该花费太多的时间在等待I/O操作上，否则你应该进一步检测I/O子系统是否存在瓶颈。</p>
<p>·Interrupts</p>
<p>Interrupts值包括硬Interrupts和软Interrupts，硬Interrupts会对系统性能带来更多的不利影响。高的Interrupts值指出系统可能存在一个软件的瓶颈，可能是内核或者驱动程序。注意Interrupts值中包括CPU时钟导致的中断（现代的xServer系统每秒1000个Interrupts值）。</p>
<p>（2）内存参数</p>
<p>·Free memory</p>
<p>相比其他操作系统，Linux空闲内存的值不应该做为一个性能参考的重要指标，因为就像我们之前提到过的，Linux内核会分配大量没有被使用的内存作为文件系统的缓存，所以这个值通常都比较小。</p>
<p>·Swap usage</p>
<p>这个值描述了已经被使用的swap空间。Swap usage只表示了Linux管理内存的有效性。对识别内存瓶颈来说，Swap In/Out才是一个比较又意义的依据，如果Swap In/Out的值长期保持在每秒200到300个页面通常就表示系统可能存在内存的瓶颈。</p>
<p>·Buffer and cache</p>
<p>这个值描述了为文件系统和块设备分配的缓存。注意在Red Hat Enterprise Linux 3和更早一些的版本中，大部分空闲内存会被分配作为缓存使用。在Red Hat Enterprise Linux 4以后的版本中,你可以通过修改/proc/sys/vm中的page_cache_tuning来调整空闲内存中作为缓存的数量。</p>
<p>·Slabs</p>
<p>描述了内核使用的内存空间，注意内核的页面是不能被交换到磁盘上的。</p>
<p>·Active versus inactive memory</p>
<p>提供了关于系统内存的active内存信息，Inactive内存是被kswapd守护进程交换到磁盘上的空间。</p>
<p>（3）网络参数</p>
<p>·Packets received and sent</p>
<p>这个参数表示了一个指定网卡接收和发送的数据包的数量。</p>
<p>·Bytes received and sent</p>
<p>这个参数表示了一个指定网卡接收和发送的数据包的字节数。</p>
<p>·Collisions per second</p>
<p>这个值提供了发生在指定网卡上的网络冲突的数量。持续的出现这个值代表在网络架构上出现了瓶颈，而不是在服务器端出现的问题。在正常配置的网络中冲突是非常少见的，除非用户的网络环境都是由hub组成。</p>
<p>·Packets dropped</p>
<p>这个值表示了被内核丢掉的数据包数量，可能是因为防火墙或者是网络缓存的缺乏。</p>
<p>·Overruns</p>
<p>Overruns表达了超出网络接口缓存的次数，这个参数应该和packets dropped值联系到一起来判断是否存在在网络缓存或者网络队列过长方面的瓶颈。</p>
<p>·Errors</p>
<p>这个值记录了标志为失败的帧的数量。这个可能由错误的网络配置或者部分网线损坏导致，在铜口千兆以太网环境中部分网线的损害是影响性能的一个重要因素。</p>
<p>（4）块设备参数</p>
<p>·Iowait</p>
<p>CPU等待I/O操作所花费的时间。这个值持续很高通常可能是I/O瓶颈所导致的。</p>
<p>·Average queue length</p>
<p>I/O请求的数量，通常一个磁盘队列值为2到3为最佳情况，更高的值说明系统可能存在I/O瓶颈。</p>
<p>·Average wait</p>
<p>响应一个I/O操作的平均时间。Average wait包括实际I/O操作的时间和在I/O队列里等待的时间。</p>
<p>·Transfers per second</p>
<p>描述每秒执行多少次I/O操作（包括读和写）。Transfers per second的值与kBytes per second结合起来可以帮助你估计系统的平均传输块大小，这个传输块大小通常和磁盘子系统的条带化大小相符合可以获得最好的性能。</p>
<p>·Blocks read/write per second</p>
<p>这个值表达了每秒读写的blocks数量，在2.6内核中blocks是1024bytes，在早些的内核版本中blocks可以是不同的大小，从512bytes到4kb。</p>
<p>·Kilobytes per second read/write</p>
<p>按照kb为单位表示读写块设备的实际数据的数量。</p>
<p> </p>
<p><strong>二．性能监测工具</strong><strong>Linux开放和灵活的特性使得它有很多的性能监测软件，这些工具中有的是传统UNIX系统的Linux版本，其他是专门为Linux设计的工具，大部分Linux性能监测工具都是基于proc虚拟文件系统的。</strong>在这一章里我们介绍一些常用性能监测工具和讨论一些有用的命令。所有我们讨论的工具，除了Capacity Manager，都是Red Hat Enterprise Linux (RHEL)所提供的，不需要从网络下载或者其他途径得到。</p>
<p> </p>
<p>1．uptime</p>
<p>Uptime命令的显示结果包括服务器已经运行了多长时间，有多少登陆用户和对服务器性能的总体评估（load average）。load average值分别记录了上个1分钟，5分钟和15分钟间隔的负载情况，load average不是一个百分比，而是在队列中等待执行的进程的数量。如果进程要求CPU时间被阻塞（意味着CPU没有时间处理它），load average值将增加。另一方面，如果每个进程都可以立刻得到访问CPU的时间，这个值将减少。</p>
<p>load average的最佳值是1，这说明每个进程都可以立刻被CPU处理。在不同的系统间这个值也是不同的，例如一个单CPU的工作站，load average为1或者2都是可以接受的，但是在一个多CPU的系统中这个值通常为8或者10。</p>
<p>你可以使用uptime判断一个性能问题是出现在服务器上还是网络上。例如，如果一个网络应用运行性能不理想，运行uptime检查系统负载是否比较高，如果不是这个问题更可能出现在你的网络上。</p>
<p>Uptime命令执行示例</p>
<p align="center"><a href="http://www.serverol.com/upimages/tech/ibm_linux_systemx_0_2007_1_23_20_40_10.gif" target="_blank"><img src="http://www.serverol.com/upimages/tech/ibm_linux_systemx_0_2007_1_23_20_40_10.gif" border="0" alt="按此在新窗口浏览图片" width="553" height="31" /></a></p>
<p>Tip:你可以用w命令代替uptime，w命令也可以提供目前登陆用户的信息。</p>
<p>2．Dmesg</p>
<p>Dmesg的主要功能是显示内核信息，当硬件或者内核中加载的模块出现问题的时候dmesg可以提供一些有用的信息。另外，利用dmesg你可以查看有哪些硬件安装在你的服务器上。在每次启动的时候，Linux检查硬件并且记录这些信息。你可以使用/bin/dmesg命令来查看这些信息。</p>
<p align="center"><a href="http://www.serverol.com/upimages/tech/ibm_linux_systemx_1_2007_1_23_20_41_13.gif" target="_blank"><img src="http://www.serverol.com/upimages/tech/ibm_linux_systemx_1_2007_1_23_20_41_13.gif" border="0" alt="按此在新窗口浏览图片" width="553" height="489" /></a></p>
<p>3．Top</p>
<p>Top命令显示了实际CPU使用情况，默认情况下，它显示了服务器上占用CPU的任务信息并且每5秒钟刷新一次。你可以通过多种方式分类它们，包括PID、时间和内存使用情况。<br />
下图是一个top命令结果的示例，</p>
<p align="center"><a href="http://www.serverol.com/upimages/tech/ibm_linux_systemx_2_2007_1_23_20_42_22.gif" target="_blank"><img src="http://www.serverol.com/upimages/tech/ibm_linux_systemx_2_2007_1_23_20_42_22.gif" border="0" alt="按此在新窗口浏览图片" width="553" height="400" /></a></p>
<p>你可以使用renice命令为一个进程分配新的优先级。如果一个进程宕掉或者占用了太多的内存，可以使用kill命令杀死进程。下面是输出值的介绍，<br />
PID：进程标识<br />
USER；进程所有者的用户名<br />
PRI：进程的优先级<br />
NI：nice级别<br />
SIZE：进程占用的内存数量（代码＋数据＋堆栈）<br />
<acronym title="Really Simple Syndication">RSS</acronym>；进程使用的物理内存数量<br />
SHARE；该进程和其他进程共享内存的数量<br />
STAT：进程的状态：S＝休眠状态，R＝运行状态，T＝停止状态，D＝中断休眠状态，Z＝僵尸状态<br />
%CPU：共享的CPU使用<br />
%MEM；共享的物理内存<br />
TIME：进程占用CPU的时间<br />
COMMAND：启动任务的命令行（包括参数）</p>
<p>Top命令有下面几个有用的热键，包括<br />
t：是否显示概要信息<br />
m：是否显示内存信息<br />
A：通过不同的系统资源情况分类显示结果，对快速判断系统中影响性能的进程十分有效<br />
f：输入一个top的交互式的配置画面<br />
o：激活交换式的分类的选择</p>
<p>进程的优先级和nice级别</p>
<p>进程优先级是一个决定进程被CPU执行优先顺序的参数，内核会根据需要调整这个值。Nice值是一个对优先权的限制。进程优先级的值不能低于nice值。（nice值越低优先级越高）</p>
<p>进程优先级是无法去手动改变的，只有通过改变nice值去间接的调整进程优先级。如果一个进程运行的太慢了，你可以通过指定一个较低的nice值去为它分配更多的CPU资源。当然，这意味着其他的一些进程将被分配更少的CPU资源，运行更慢一些。Linux支持nice值的范围是19（低优先级）到-20（高优先级），默认的值是0。如果需要改变一个进程的nice值为负数（高优先级），必须使用su命令登陆到root用户。下面是一些调整nice值的命令示例，<br />
以nice值-5开始程序xyz<br />
#nice –n -5 xyz<br />
改变已经运行的程序的nice值<br />
#renice level pid<br />
将pid为2500的进程的nice值改为10<br />
#renice 10 2500</p>
<p>僵尸进程</p>
<p>当一个进程被结束，在它结束之前通常需要用一些时间去完成所有的任务（比如关闭打开的文件），在一个很短的时间里，这个进程的状态为僵尸状态。在进程完成所有关闭任务之后，会向父进程提交它关闭的信息。有些情况下，一个僵尸进程不能关闭它自己，这时这个进程状态就为z（zombie）。不能使用kill命令杀死僵尸进程，因为它已经标志为“dead”。如果你无法摆脱一个僵尸进程，你可以杀死它的父进程，这个僵尸进程也就消失了。然而，如果父进程是init进程，你不能杀死init进程，因为init是一个重要的系统进程，这种情况下你只能通过一次重新启动来摆脱僵尸进程。</p>
<p>4．iostat</p>
<p>iostat是sysstat的一部分，如果你没有安装这个包，在Red Hat Enterprise Linux光盘中找到sysstat的rpm包进行安装。Iostat显示自系统启动后的平均CPU时间（与uptime类似），它也可以显示磁盘子系统的使用情况，iostat可以用来监测CPU利用率和磁盘利用率。下图是一个命令输出的示例，</p>
<p align="center"><a href="http://www.serverol.com/upimages/tech/ibm_linux_systemx_3_2007_1_23_20_43_41.gif" target="_blank"><img src="http://www.serverol.com/upimages/tech/ibm_linux_systemx_3_2007_1_23_20_43_41.gif" border="0" alt="按此在新窗口浏览图片" width="553" height="190" /></a></p>
<p>CPU利用率分四个部分：<br />
%user：user level（应用）的CPU占用率情况<br />
%nice：加入nice优先级的user level的CPU占用率情况<br />
％sys：system level（内核）的CPU占用情况<br />
%idle：空闲的CPU资源情况<br />
磁盘占用率有下面几个部分：<br />
Device：块设备名<br />
Tps：设备每秒进行传输的数量（每秒的I/O请求）。多个单独的I/O请求可以被组成一个传输操作，因为一个传输操作可以是不同的容量。<br />
Blk_read/s, Blk_wrtn/s：该设备每秒读写的块的数量。块可能为不同的容量。块的大小一般为1024、2048、4048byte。例如，块设备/dev/sda1的块大小可以通过下面命令查看<br />
# dumpe2fs -h /dev/sda1 |grep -F ”Block size”<br />
会得到类似下面的输出<br />
dumpe2fs 1.34 (25-Jul-2003)<br />
Block size: 1024</p>
<p>Blk_read, Blk_wrtn：自系统启动以来读写的块设备的总量。</p>
<p>5．Vmstat</p>
<p>Vmstat命令提供了对进程、内存、页面I/O块和CPU等信息的监控，vmstat可以显示检测结果的平均值或者取样值，取样模式可以提供一个取样时间段内不同频率的监测结果。下面是一个vmstat命令的输出结果的示例。<br />
注：在取样模式中需要考虑在数据收集中可能出现的误差，将取样频率设为比较低的值可以尽可能的减小误差的影响。</p>
<p align="center"><a href="http://www.serverol.com/upimages/tech/ibm_linux_systemx_4_2007_1_23_20_44_35.gif" target="_blank"><img src="http://www.serverol.com/upimages/tech/ibm_linux_systemx_4_2007_1_23_20_44_35.gif" border="0" alt="按此在新窗口浏览图片" width="553" height="65" /></a></p>
<p>下面介绍一下各列的含义<br />
·process（procs）<br />
r：等待运行时间的进程数量<br />
b：处在不可中断睡眠状态的进程<br />
w：被交换出去但是仍然可以运行的进程，这个值是计算出来的<br />
·memoryswpd：虚拟内存的数量<br />
free：空闲内存的数量<br />
buff：用做缓冲区的内存数量<br />
·swap<br />
si：从硬盘交换来的数量<br />
so：交换到硬盘去的数量<br />
·IO<br />
bi：向一个块设备输出的块数量<br />
bo：从一个块设备接受的块数量<br />
·system<br />
in：每秒发生的中断数量， 包括时钟<br />
cs：每秒发生的context switches的数量<br />
·cpu(整个cpu运行时间的百分比)<br />
us：非内核代码运行的时间（用户时间，包括nice时间）<br />
sy：内核代码运行的时间（系统时间）<br />
id：空闲时间，在Linux 2.5.41之前的内核版本中，这个值包括I/O等待时间<br />
等待I/O操作的时间，在Linux 2.5.41之前的内核版本中这个值为0</p>
<p>Vmstat命令提供了大量的附加参数，可以参考vmstat的man手册去查询所有的参数，下面列举几个十分有用的参数。<br />
·m：显示内核的内存利用率<br />
·a：显示内存页面信息，包括活跃和不活跃的内存页面<br />
·n：显示报头行，这个参数在使用取样模式并将命令结果输出到一个文件时非常有用。例如root#vmstat –n 2 10以2秒的频率显示10输出结果<br />
·当使用-p {分区}时，vmstat提供对I/O结果的统计</p>
<p>6.ps和pstree</p>
<p>ps和pstree命令是系统分析最常用的基本命令，ps命令提供了一个正在运行的进程的列表，列出进程的数量取决于命令所附加的参数。例如ps –A 命令列出所有进程和它们相应的进程ID（PID），进程的PID是使用其他一些工具之前所必须了解的，例如pmap或者renice。<br />
在运行java应用的系统上，ps –A 命令的输出很容易就会超过屏幕的显示范围，这样就很难得到所有进程的完整信息。这时，使用pstree命令可以以树状结构来显示所有的进程信息并且可以整合子进程的信息。Pstree命令对分析进程的来源十分有用。下面是命令的示例，</p>
<p align="center"><a href="http://www.serverol.com/upimages/tech/ibm_linux_systemx_5_2007_1_23_20_48_45.gif" target="_blank"><img src="http://www.serverol.com/upimages/tech/ibm_linux_systemx_5_2007_1_23_20_48_45.gif" border="0" alt="按此在新窗口浏览图片" width="553" height="175" /></a></p>
<p>7.Numastat</p>
<p>随着NUMA架构的不断发展，例如eServer xSeries 445及其后续产品eServer xSeries 460，现在NUMA架构已经成为了企业级数据中心的主流。然而，NUMA架构在性能调优方面面临了新的挑战，例如内存分配的问题在NUMA系统之前并没人感兴趣，Red Hat Enterprise Linux 4提供了一个监测NUMA架构的工具。Numastat命令提供了本地内存与远程内存使用情况的对比和各个节点的内存使用情况。Numa_miss列显示分配失败的本地内存，numa_foreign列显示分配远程内存（访问速度慢）信息，过多的调用远程内存将增加系统的延迟从而影响整个系统的性能。使运行在一个节点上的进程都访问本地内存将极大的改善系统的性能。</p>
<p align="center"><a href="http://www.serverol.com/upimages/tech/ibm_linux_systemx_6_2007_1_23_20_49_43.gif" target="_blank"><img src="http://www.serverol.com/upimages/tech/ibm_linux_systemx_6_2007_1_23_20_49_43.gif" border="0" alt="按此在新窗口浏览图片" width="553" height="159" /></a></p>
<p>8.sar</p>
<p>sar程序是sysstat安装包的一部分，如果你没有安装这个包，在Red Hat Enterprise Linux的源文件中寻找这个rpm包进行安装，sar命令用于收集、报告和保存系统的信息。Sar命令由三个应用组成：sar，用与显示数据；sa1和sa2，用于收集和存储数据。关于sar工具的详细参数说明可以参考man手册。</p>
<p>为了以后分析日志，可以使用sa1和sa2配置系统获得并且记录日志信息。为了实现这个目的，如下图例所示向/etc/crontab中加入相应的内容。注意默认的情况下cron每天都会定时的运行sar命令，如果系统安装了sar相应的安装包。</p>
<p align="center"><a href="http://www.serverol.com/upimages/tech/ibm_linux_systemx_7_2007_1_23_20_50_21.gif" target="_blank"><img src="http://www.serverol.com/upimages/tech/ibm_linux_systemx_7_2007_1_23_20_50_21.gif" border="0" alt="按此在新窗口浏览图片" width="553" height="145" /></a></p>
<p>sar命令所生成的数据保存在/var/log/sa/目录下，数据按照时间保存，可以根据时间来查询相应的性能数据。例如，显示21号的网络信息使用下面的命令sar -n DEV -f sa21|less，命令结果如下，</p>
<p align="center"><a href="http://www.serverol.com/upimages/tech/ibm_linux_systemx_8_2007_1_23_20_51_2.gif" target="_blank"><img src="http://www.serverol.com/upimages/tech/ibm_linux_systemx_8_2007_1_23_20_51_2.gif" border="0" alt="按此在新窗口浏览图片" width="553" height="101" /></a></p>
<p>你也可以使用sar在命令行下得到一个实时的执行结果，收集的数据可以包括CPU利用率、内存页面、网络I/O等等。如下例所示，</p>
<p align="center"><a href="http://www.serverol.com/upimages/tech/ibm_linux_systemx_9_2007_1_23_20_51_48.gif" target="_blank"><img src="http://www.serverol.com/upimages/tech/ibm_linux_systemx_9_2007_1_23_20_51_48.gif" border="0" alt="按此在新窗口浏览图片" width="553" height="135" /></a></p>
<p>9．KDE System Guard</p>
<p>KDE System Guard (KSysguard)是一个KDE的任务管理器和性能监测工具。它是一个客户端/服务器结构的应用，因此可以监测本地或者远程主机。</p>
<p align="center"><a href="http://www.serverol.com/upimages/tech/ibm_linux_systemx_10_2007_1_23_20_52_32.gif" target="_blank"><img src="http://www.serverol.com/upimages/tech/ibm_linux_systemx_10_2007_1_23_20_52_32.gif" border="0" alt="按此在新窗口浏览图片" width="523" height="388" /></a></p>
<p>图形界面中可以用左侧的Sensor选择显示的信息，一个Sensor可以返回一个简单的值或者更复杂的信息例如表格。针对每一类信息都提供了一个或多个显示信息，这些显示信息可以保存或者互相独立的在工作表中加载。<br />
KSysguard窗口中包括菜单栏、工具栏和状态栏，页面浏览和工作区。当你第一次打开时，可以看到默认的情况：本地主机做为localhost列在Sensor浏览里，在工作区中有两个表格。每个Sensor监测某些系统参数，所有的Sensor显示可以在工作区中以拖拽的形式操作，有下面三个选项：<br />
·可以在工作区中删除和代替Sensor<br />
·可以编辑工作表的属性以增加显示的行数和列数<br />
·可以建立新的工作表并且加入新的Sensor以满足应用的需要</p>
<p>下面介绍一下工作区，如下图所示工作区中显示两张表，<br />
·system load：在启动KSysguard中默认显示的<br />
·process Table</p>
<p align="center"><a href="http://www.serverol.com/upimages/tech/ibm_linux_systemx_11_2007_1_23_20_53_20.gif" target="_blank"><img src="http://www.serverol.com/upimages/tech/ibm_linux_systemx_11_2007_1_23_20_53_20.gif" border="0" alt="按此在新窗口浏览图片" width="546" height="363" /></a></p>
<p>System load工作表中包括四个Sensor窗口，cpu负载、平均负载、物理内存和交换空间。多个Sensor可以被显示在一个窗口中，如果想查看窗口中正在监测的分Sensor信息，将鼠标移到图标上，相应的说明会显示出来。也可以在图标上点鼠标右键选择Properties，然后选择页面表，就可以看到相应的说明信息。</p>
<p align="center"><a href="http://www.serverol.com/upimages/tech/ibm_linux_systemx_12_2007_1_23_20_54_0.gif" target="_blank"><img src="http://www.serverol.com/upimages/tech/ibm_linux_systemx_12_2007_1_23_20_54_0.gif" border="0" alt="按此在新窗口浏览图片" width="475" height="322" /></a></p>
<p>点击Process Table表将显示所有在服务器上运行进程的信息，这个表默认显示的是系统CPU的利用率，但是它可以通过选择其他分页来显示其他信息。</p>
<p align="center"><a href="http://www.serverol.com/upimages/tech/ibm_linux_systemx_13_2007_1_23_20_54_59.gif" target="_blank"><img src="http://www.serverol.com/upimages/tech/ibm_linux_systemx_13_2007_1_23_20_54_59.gif" border="0" alt="按此在新窗口浏览图片" width="496" height="398" /></a></p>
<p>因为环境或者应用的需要，你可能有多种不同的Sensor需要监测，实现这个最好的方法就是自定义一个工作表。下面就简单的指导一下如何根据需要建立自定义的工作表。<br />
（1）．创建一个空的工作表，点击File → New。</p>
<p align="center"><a href="http://www.serverol.com/upimages/tech/ibm_linux_systemx_14_2007_1_23_20_55_43.gif" target="_blank"><img src="http://www.serverol.com/upimages/tech/ibm_linux_systemx_14_2007_1_23_20_55_43.gif" border="0" alt="按此在新窗口浏览图片" width="239" height="233" /></a></p>
<p>（2）．输入标题、工作表的行数和列数，也就是监测窗口的数量，在例子中是4个。当信息输入完成后，点击ok建立空工作表。</p>
<p align="center"><a href="http://www.serverol.com/upimages/tech/ibm_linux_systemx_15_2007_1_23_20_56_46.gif" target="_blank"><img src="http://www.serverol.com/upimages/tech/ibm_linux_systemx_15_2007_1_23_20_56_46.gif" border="0" alt="按此在新窗口浏览图片" width="553" height="397" /></a></p>
<p>(3)．在窗口左边将需要的Sensor拖到右边的窗口中。<br />
(4)．点击File → Save保存新的工作表。</p>
<p align="center"><a href="http://www.serverol.com/upimages/tech/ibm_linux_systemx_16_2007_1_23_20_58_1.gif" target="_blank"><img src="http://www.serverol.com/upimages/tech/ibm_linux_systemx_16_2007_1_23_20_58_1.gif" border="0" alt="按此在新窗口浏览图片" width="553" height="428" /></a></p>
<p>如果想要了解关于KDE System Guard的更多信息请访问下面的链接<br />
<a href="http://docs.kde.org/en/3.2/kdebase/ksysgaurd" target="_blank"><span style="color: #ff3300;">http://docs.kde.org/en/3.2/kdebase/ksysgaurd</span></a></p>
<p>10．Gnome System Monitor</p>
<p>虽然没有KDE System Guard那么强大的功能，Gnome桌面环境也有自己的图形化的性能监测工具。Gnome System Monitor可以图形化的显示系统性能相关的参数，所有的统计结果都是实时的，如果需要长时间的统计结果需要通过其他的性能监测工具来实现。</p>
<p>11．free</p>
<p>free命令显示系统的所有内存的使用情况，包括空闲内存、被使用的内存和交换内存空间。Free命令显示也包括一些内核使用的缓存和缓冲区的信息。下面是命令结果的示例，</p>
<p align="center"><a href="http://www.serverol.com/upimages/tech/ibm_linux_systemx_17_2007_1_23_20_59_49.gif" target="_blank"><img src="http://www.serverol.com/upimages/tech/ibm_linux_systemx_17_2007_1_23_20_59_49.gif" border="0" alt="按此在新窗口浏览图片" width="553" height="81" /></a></p>
<p>当使用free命令的时候，需要记住linux的内存结构和虚拟内存的管理方法，比如空闲内存数量的限制，还有swap空间的使用并不标志一个内存瓶颈的出现。<br />
Free命令有用的参数：<br />
·-b,-k,-m和-g分别按照bytes, kilobytes, megabytes, gigabytes显示结果。<br />
·-l区别显示low和high内存<br />
·-c {count}显示free输出的次数</p>
<p>12．Pmap</p>
<p>pmap命令显示一个或者多个进程使用内存的数量，你可以用这个工具来确定服务器上哪个进程占用了过多的内存从而导致内存瓶颈。<br />
命令格式：pmap <br />
关于pmap命令的详细语法可以使用下面命令查询<br />
pmap -?</p>
<p align="center"><a href="http://www.serverol.com/upimages/tech/ibm_linux_systemx_18_2007_1_23_21_0_35.gif" target="_blank"><img src="http://www.serverol.com/upimages/tech/ibm_linux_systemx_18_2007_1_23_21_0_35.gif" border="0" alt="按此在新窗口浏览图片" width="553" height="92" /></a></p>
<p>13．Strace</p>
<p>strace截取和记录进程的系统调用信息，还包括进程接受的命令信号。这是一个有用的诊断和调试工具，系统管理员可以通过strace来解决程序上的问题。<br />
命令格式，需要指定需要监测的进程ID，下图是一个命令结果的示例。<br />
strace -p <br />
使用下面命令可以获得关于strace的完整语法信息<br />
strace -?<br />
注：当针对某个进程执行strace命令时，对该进程的运行性能将产生很大的影响，所以这个命令仅仅应该用在收集数据的时候。</p>
<p align="center"><a href="http://www.serverol.com/upimages/tech/ibm_linux_systemx_19_2007_1_23_21_1_29.gif" target="_blank"><img src="http://www.serverol.com/upimages/tech/ibm_linux_systemx_19_2007_1_23_21_1_29.gif" border="0" alt="按此在新窗口浏览图片" width="553" height="151" /></a></p>
<p>14．ulimit</p>
<p>这个命令是基于bash的，可以通过ulimit来控制系统资源的使用，使用-a参数列出所有可调的参数。<br />
ulimit –a</p>
<p align="center"><a href="http://www.serverol.com/upimages/tech/ibm_linux_systemx_20_2007_1_23_21_2_10.gif" target="_blank"><img src="http://www.serverol.com/upimages/tech/ibm_linux_systemx_20_2007_1_23_21_2_10.gif" border="0" alt="按此在新窗口浏览图片" width="553" height="210" /></a></p>
<p>-H和-S参数可以对指定的资源进行软限制和硬限制，如果超过了软限制，系统管理员会接收到一个警告，在达到硬限制的时候命令就会提示报错。<br />
例如，为系统打开文件的数量设定一个硬限制<br />
ulimit -Hn 4096<br />
为打开文件设定一个软限制<br />
ulimit -Sn 1024<br />
查看硬限制和软限制的值<br />
ulimit -Hn<br />
ulimit -Sn<br />
这是一个很有用的命令，例如现在想在系统启动时对Oracle用户进行限制，在/etc/security/limits.conf中加入如下两行：<br />
soft nofile 4096<br />
hard nofile 10240<br />
另外确保/etc/pam.d/system-auth文件有下面内容<br />
session required /lib/security/$ISA/pam_limits.so<br />
这一行确保系统会执行这个限制。<br />
如果要查看ulimit命令的详细语法，可以执行<br />
ulimit -?</p>
<p><strong>15．Mpstat</strong></p>
<p>mpstat命令是sysstat包的一部分，如果没有安装sysstat包，可以在Red Hat Enterprise Linux安装源文件中找到并且安装这个rpm包。Mpstat命令用于监测一个多CPU系统中每个可用CPU的情况。Mpstat命令可以显示每个CPU或者所有CPU的运行情况，同时也可以像vmstat命令那样使用参数进行一定频率的采样结果的监测。下面是使用mpstat -P ALL命令的显示结果的示例，</p>
<p align="center"><a href="http://www.serverol.com/upimages/tech/ibm_linux_systemx_21_2007_1_23_21_3_1.gif" target="_blank"><img src="http://www.serverol.com/upimages/tech/ibm_linux_systemx_21_2007_1_23_21_3_1.gif" border="0" alt="按此在新窗口浏览图片" width="553" height="126" /></a></p>
<p>关于完整的命令语法请用下面命令查看<br />
mpstat -?</p>
<p>16. Capacity Manager</p>
<p>Capacity Manager是IBM Director系统管理的一个附加组件，可以提供对不同平台下的多个系统进行长期的性能监测。除了对性能的监测，Capacity Manager还包括对容量的计划，提供对系统将来可能的容量的分析和建议。Capacity Manager可以输出多种文件格式包括<acronym title="HyperText Markup Language">HTML</acronym>, <acronym title="eXtensible Markup Language">XML</acronym>和<acronym title="Graphics Interchange Format">GIF</acronym>。IBM Director可以被应用在不同操作系统平台下，这样就为在异构环境下对数据的收集和分析提供了有力的工具。</p>
<p>如果使用Capacity Manager，必须在系统中安装相关的rpm包。安装完成后在IBM Director Console中选择Capacity Manager →Monitor Activator</p>
<p align="center"><a href="http://www.serverol.com/upimages/tech/ibm_linux_systemx_22_2007_1_23_21_5_42.gif" target="_blank"><img src="http://www.serverol.com/upimages/tech/ibm_linux_systemx_22_2007_1_23_21_5_42.gif" border="0" alt="按此在新窗口浏览图片" width="391" height="284" /></a></p>
<p>拖拽Monitor Activator图标到一个单独的或者一组已经安装相应程序的系统，在接下来的窗口中可以选择多种子系统进行监测。Capacity Manager在Linux下会有少部分功能受一些参数的限制。</p>
<p align="center"><a href="http://www.serverol.com/upimages/tech/ibm_linux_systemx_23_2007_1_23_21_6_44.gif" target="_blank"><img src="http://www.serverol.com/upimages/tech/ibm_linux_systemx_23_2007_1_23_21_6_44.gif" border="0" alt="按此在新窗口浏览图片" width="553" height="287" /></a></p>
<p>Monitor Activator窗口在右边的窗口中显示相关系统目前的状态，在左边的窗口中显示显示可用的性能监测。添加一个新的监测，选择相应的监测图标点击On。改变将在Monitor Activator窗口关闭后马上生效，配置完成后，IBM Director将开始收集并且存储所要求的性能数据。如果要为收集的信息创建一个报告，选择Capacity Manager → Report Generator并且拖拽操作你想监测的单个或者一组系统，IBM Director将显示下面的界面，</p>
<p align="center"><a href="http://www.serverol.com/upimages/tech/ibm_linux_systemx_24_2007_1_23_21_7_38.gif" target="_blank"><img src="http://www.serverol.com/upimages/tech/ibm_linux_systemx_24_2007_1_23_21_7_38.gif" border="0" alt="按此在新窗口浏览图片" width="553" height="434" /></a></p>
<p>在这里根据你的需要选择是立刻执行或者指定时间执行。在生产环境中，在固定的时间收集Capacity Manager报告是一个比较好的方法，我们可以选择在每周末系统并不繁忙的时候产生一次系统报告。一旦报告收集完成将存储在IBM Director服务器上，可以通过Report Viewer任务来查看。<br />
下图是一个报告结果的示例</p>
<p align="center"><a href="http://www.serverol.com/upimages/tech/ibm_linux_systemx_25_2007_1_23_21_8_49.gif" target="_blank"><img src="http://www.serverol.com/upimages/tech/ibm_linux_systemx_25_2007_1_23_21_8_49.gif" border="0" alt="按此在新窗口浏览图片" width="546" height="340" /></a></p>
<p>在Report Viewer窗口中可以选择需要查看的不同性能参数，Capacity Manager的结果可以被输出为<acronym title="HyperText Markup Language">HTML</acronym>或者<acronym title="eXtensible Markup Language">XML</acronym>文件，为了分析需要可以被显示在内部的web服务器上。</p>
<p> </p>
<p><strong>三.操作系统的调优Linux发行版本和Linux内核提供了大量的参数和设定来帮助系统管理员调优系统使之发挥最大的性能。这一章描述了调优Red Hat Enterprise Linux AS系统的步骤和理解使用Linux系统的一些技能</strong>，包括<br />
·Linux的内存管理<br />
·Linux的页面管理<br />
·文件系统和它对性能的影响<br />
·禁用非必须的守护进程<br />
·使用sysctl调优参数</p>
<p><strong></strong><strong>3.1 调优之前准备</strong></p>
<p>在我们没有开始讨论调优工作之前，一些好的调优的手段对我们是很重要的，下面列出一些相关的提示。<br />
·在调优任何Linux系统之前，计划一个适合的调优进程。<br />
·不要在一个生产系统上进行调优测试。<br />
·在调优进程中不要同时改变多个调优参数。<br />
·反复测试可能改变系统性能的参数，有时可以用统计数据来验证结果。<br />
·记录成功的参数并且和社区分享它们，无论你认为它们多么繁琐。</p>
<p><strong>3.2 安装</strong></p>
<p>在理想的情况下，对一个系统的调优应该开始在一个非常早的阶段，一个系统应该按照应用预想的工作量来设计。我们能理解大多数情况下系统管理员都是在一个已经安装的系统遇到性能瓶颈的情况下才开始性能调优工作的，但我们还是要介绍下在系统初始化安装的过程中可能的调优操作。</p>
<p>理想情况下，下面问题应该在Linux系统开始安装之前考虑<br />
·需要什么版本的Red Hat Linux？<br />
在收集商业和应用的需求之后，我们需要决定选择哪种Linux版本。企业版做为一种特殊的Linux发行版本通常有商业的合约。如果你选择Red Hat Enterprise Linux还需要考虑下面几点：<br />
选择企业版本Linux还是自定义版本Linux?<br />
在某些科学实验环境中，通常可以接收运行一个没有支持的Linux版本，例如Fedora。但是对一个企业级的应用来说，我们强烈推荐一个有支持的Linux版本，例如Red Hat Enterprise Linux。<br />
企业级Linux版本？<br />
Red Hat Enterprise Linux有两个不同的版本：Enterprise Server和Advanced Server。这两个版本的区别主要在扩展性方面，Enterprise Server限制在支持2个CPU和16GB内存，因此当使用一些类似web服务器和分布式架构时Enterprise Server是一个正确的选择。Red Hat Enterprise Linux 的Advanced Server版本支持32个CPU和64GB内存。<br />
随着x86-64架构的到来（包括AMD64和EM64T），客户也面对着选择32bit或者64bit操作系统的问题。我们的基准测试结果显示Linux系统在x86-64CPU上运行64bit系统会有着更出色的性能表现，除了性能，我们还应该考虑到扩展性和未来应用的需要。使用64bit操作系统还提供了可以同时运行32bit应用（i386）和64bit（x86-64）应用的优势。考虑到上述方面，我们通常建议用户在x86-64架构上使用64bit操作系统，除非因为应用的原因导致不能部署在64bit系统上。<br />
·如何进行分区的规划？<br />
在Linux社区中，对磁盘子系统的分区经常引起很大的讨论。磁盘子系统分区的规划通常都是由应用的需要、系统管理的考虑和个人喜好决定的，基本没有性能的考虑。在这里我们唯一给出的建议就是如果可能尽量使用swap分区，swap分区相对于swap文件的性能会有提升，因为不需要文件系统方面的开销。Swap分区建立很简单并且可以添加附加的swap分区甚至swap文件。</p>
<p>·应该使用什么文件系统？<br />
Red Hat Enterprise Linux在安装时提供文件系统的选择很有限，默认只有两种可用的文件系统：ext2和ext3。Red Hat Enterprise Linux安装程序默认选择的文件系统是ext3，这在大多数情况下都是可以接收的，但我们也鼓励你考虑使用ext2文件系统。对一些比较小的文件系统可能并不过分的关注数据一致性（例如：web群集服务器），或者系统对性能提出了严格的要求（例如：高性能计算环境），在上述情况下使用ext2文件系统可能会带来性能上的帮助，因为ext2不需要维护日志的系统开销，即使ext3文件系统在这方面进行了很大的改变，这仍然是一个显著的不同。同时也可以考虑到ext2文件系统可以很容易的升级到ext3文件系统。</p>
<p>·安装包的选择：最小安装或者完全安装？<br />
在Red Hat Enterprise Linux安装过程中，系统管理员面对选择最小安装或者完全安装。有些人更愿意选择完全安装为了避免在以后安装rpm包时面对依存关系的问题。但需要考虑到下面的问题，与性能无关，很重要的一点是在选择完全安装或者几乎完全安装会对系统的安全产生负面的影响。在生产系统上安装一些开发工具会对系统的安全产生负面的影响。安装比较少的安装包，可以节省更多的磁盘空间，磁盘的空余空间越大性能越好。一些智能的软件包安装工具会自动的解决安装包的依存问题，例如Red Hat Packet Manager、rpm或者yum。所以我们建议仅仅安装与应用相关的必需安装的软件包。</p>
<p>·SELinux（仅针对Red Hat Enterprise Linux 4）<br />
在Red Hat Enterprise Linux安装过程中，Anaconda安装程序默认选择安装SELinux，然而SELinux会对系统的性能产生负面的影响，所以要谨慎的决定你的系统是否需要SELinux所提供的附加的安全支持。在后面会对SELinux做进一步的介绍。</p>
<p>·运行级别的选择<br />
安装阶段最后一个选择是系统默认的运行级别。我们强烈建议你为服务器系统选择默认运行级别为3，除非你有特殊的需要将默认的运行级别设为5（图形用户模式）。通常在数据中心的服务器不需要<acronym title="Graphical User Interface">GUI</acronym>图形用户界面进行操作，因为考虑到运行级别5的<acronym title="Graphical User Interface">GUI</acronym>带来的系统开销。</p>
<p><strong>3.3 守护进程</strong></p>
<p>Red Hat Enterprise Linux默认安装完成后，一些可能并不是必须的守护进程会启用。禁用非必要的进程会减少系统的内存开销，同时也可以减少系统的安全隐患，可以释放更多的内存空间、减少系统的启动时间、减少CPU处理的进程数量。<br />
默认情况下，很多守护进程可以安全的在系统下停止和禁用。下表列出了Red Hat Enterprise Linux安装的一些守护进程，如果不是必须的你可以考虑禁用这些进程，注意下表列出的对Red Hat Enterprise Linux3和4的区别。</p>
<p align="center"><a href="http://www.serverol.com/upimages/tech/redhat_2007_2_10_18_32_47.JPG" target="_blank"><img src="http://www.serverol.com/upimages/tech/redhat_2007_2_10_18_32_47.JPG" border="0" alt="按此在新窗口浏览图片" width="553" height="540" /></a></p>
<p>注：关闭xfs服务后，服务器上的X window将不能被启动。在使用startx命令启动X window之前应该首先启动xfs进程。</p>
<p>在Red Hat Enterprise Linux系统中，系统管理员可以使用/sbin/chkconfig命令很方便的修改各种守护进程的启动选项，下面命令列出了所有当前运行的守护进程<br />
/sbin/chkconfig –list|grep on</p>
<p>如果你想某个守护进程在下次服务器启动时不再自动启动，使用root执行下面两个命令可以达到相同的效果，不同之处是第二个命令在所有运行级别都会禁用此进程，而使用–level参数可以指定选择的运行级别。<br />
/sbin/chkconfig –level 2345 sendmail off<br />
/sbin/chkconfig sendmail off<br />
注：大家经常以为使用chkconfig做出改变之后必须在下一次重新启动才能生效，其实改变执行运行级别的操作可以实现同重新启动一样的效果。代替浪费时间的重新启动，简单的改变运行基本到1再改变回3或者5就可以改变配置。</p>
<p>还有另外一个有用的命令/sbin/service，通过这个命令系统管理员可以立刻更改已注册服务的状态。下面的例子是查看sendmail服务的状态，<br />
/sbin/service sendmail status<br />
立刻停止sendmail服务<br />
/sbin/service sendmail stop<br />
service命令在需要立刻改变服务状态的情况下是非常有效的，因为使用chkconfig命令必须在改变运行级别或者重新启动后才能生效，但是使用service命令关闭的守护进程在重新启动服务器后又会启动。</p>
<p>如下图所示系统还提供了基于<acronym title="Graphical User Interface">GUI</acronym>的修改守护进程的工具，图形界面中点击Main Menu → System Settings → Server Settings →Services或者执行下面命令<br />
/usr/bin/redhat-config-services</p>
<p align="center"><a href="http://www.serverol.com/upimages/tech/rehat1_2007_2_10_18_33_57.gif" target="_blank"><img src="http://www.serverol.com/upimages/tech/rehat1_2007_2_10_18_33_57.gif" border="0" alt="按此在新窗口浏览图片" width="462" height="344" /></a></p>
<p><strong>3.4 改变运行级别</strong></p>
<p>如果可能，尽量不要在Linux服务器上运行图形用户界面，通常大多数系统管理员都喜欢更有效的通过命令行方式完成系统的管理任务。如果你喜欢使用图形界面，一些有用的基于web的工具可以帮助你，例如webmin,Linuxconf和SWAT。<br />
Tip：即使<acronym title="Graphical User Interface">GUI</acronym>在本地禁用了，你仍然可以使用ssh加-X参数远程连接到服务器上。</p>
<p>如果必须要使用<acronym title="Graphical User Interface">GUI</acronym>图形用户界面，在需要使用时启动<acronym title="Graphical User Interface">GUI</acronym>然后关闭比一直启动<acronym title="Graphical User Interface">GUI</acronym>更合适一些。在大多数情况下运行级别都设为3，即在机器启动的时候不运行X window。如果需要启动X window，在命令提示符下使用startx命令。<br />
查看当前运行级别可以使用runlevel命令，命令结果显示前一个运行级别和当前运行级别。<br />
在运行级别之间进行切换，使用init命令。例如，切换到运行级别3，使用init 3命令。</p>
<p>Linux常用的运行级别:</p>
<p>0 关机，不要将默认运行级别设为0，否则机器启动进程完成后马上就会关机。<br />
1 单用户模式<br />
2 多用户，没有NFS，和运行级别3的区别是没有网络连接支持<br />
3 完全多用户模式<br />
4 未用<br />
5 X11图形用户界面模式<br />
6 重新启动，不要将默认运行级别设为6，否则机器将不停的重新启动。</p>
<p>编辑/etc/inittab文件中下面内容可以改变系统默认的运行级别，<br />
id:3:initdefault:</p>
<p align="center"><a href="http://www.serverol.com/upimages/tech/rehat2_2007_2_10_18_35_29.gif" target="_blank"><img src="http://www.serverol.com/upimages/tech/rehat2_2007_2_10_18_35_29.gif" border="0" alt="按此在新窗口浏览图片" width="553" height="320" /></a></p>
<p><strong>3.5 限制本地终端</strong></p>
<p>默认的情况下，系统打开了六个本地虚拟终端：通过F1到F6可以访问不同的终端。虚拟终端所占用的内存数量可以忽略不计，然而我们试图得到系统最大的性能，另外减少运行进程的数量可以简化解决问题和进程分析的过程，所以这里建议将本地终端的数量限制为两个。可以通过在/etc/inittab中将mingetty相关行注释掉来实现限制本地终端，下图是将本地终端限制为2个的示例。</p>
<p align="center"><a href="http://www.serverol.com/upimages/tech/rehat3_2007_2_10_18_36_12.gif" target="_blank"><img src="http://www.serverol.com/upimages/tech/rehat3_2007_2_10_18_36_12.gif" border="0" alt="按此在新窗口浏览图片" width="553" height="247" /></a></p>
<p><strong>3.6 SELinux</strong></p>
<p>Red Hat Enterprise Linux 4引入了一个新的安全模型Security Enhanced Linux（SELinux），在面对高级别的安全需求的时候它是一个有效的手段。SELinux提供了新的强制认证的安全策略，替代了传统Linux所使用的有局限性的标准访问安全策略。SELinux强制进行用户和进程级别的安全认证，因此任何一个进程的安全漏洞都只会影响此进程所占有的资源，而不会影响整个系统。SELinux的工作与虚拟机有些相似，例如如果一个恶意攻击者用root权限嵌入了Apache应用，也仅仅只有Apache进程的资源会被影响。</p>
<p align="center"><a href="http://www.serverol.com/upimages/tech/rehat4_2007_2_10_18_36_54.gif" target="_blank"><img src="http://www.serverol.com/upimages/tech/rehat4_2007_2_10_18_36_54.gif" border="0" alt="按此在新窗口浏览图片" width="553" height="263" /></a></p>
<p>然而加强安全策略也会对系统的性能产生影响，用户或者进程对系统资源的每次访问都必须被SELinux控制，对访问权限的检查可能会造成大约10%的系统开销。SELinux对一些对安全方面有很高要求的服务器比如防火墙和web服务器会有很高的价值，但是对一些对性能要求比较高的服务器就不会选择启用SELinux，例如数据库服务器。<br />
通常最容易的方法就是在安装系统的时候选择不安装SELinux。但经常是系统已经按照默认的参数安装好了，忽略了SELinux对系统性能的影响。在系统安装完成后，可以通过在GRUB boot loader中的运行内核行中加入selinux=0参数来禁用SELinux.。下图是示例，</p>
<p align="center"><a href="http://www.serverol.com/upimages/tech/rehat5_2007_2_10_18_37_34.gif" target="_blank"><img src="http://www.serverol.com/upimages/tech/rehat5_2007_2_10_18_37_34.gif" border="0" alt="按此在新窗口浏览图片" width="553" height="125" /></a></p>
<p>如果你决定在Linux服务器上使用SELinux，可以通过调整参数来使它更适合应用环境。在一个运行的系统上，检查是否Linux Security Modules（LSM）缓存允许超过默认的Access Vector Cache（AVC）。检查/selinux/avc/hash_stats中最长chain的长度，任何超过10个signals的都可能是存在的瓶颈。<br />
如果系统面临一个Access Vector Cache的瓶颈（例如，一个很大量的防火墙负载），尝试修改/selinux/avc/cache_threshold的值，稍微来加大这个值来重新检查hash状态。</p>
<p><strong>3.7 编译内核</strong></p>
<p>创建和编译自定义的内核对系统性能的影响通常比我们想象的小的多，现代的Linux发行版本的内核通常都是模块化的，加载的内核可能只使用其中的一部分。重新编译内核可以减少内核的大小和内核的系统开销，修改源码中的某些参数也可能对系统的性能产生影响。然而使用自己编译的非标准内核是不在Red Hat Enterprise Linux支持范围内的，很多ISV的应用和IBM硬件对Red Hat Enterprise Linux的支持对非标准内核也是无效的。这里我们要说的是，通过自定义内核可以获得一些性能上的提升，但是你同时需要面对在非支持内核下运行企业级应用说带来的风险。当然这些都是针对一些商业应用来说的，如果你感兴趣的是一个科学实验性质的应用比如高性能运算，那么选择自定义内核也是选择之一。<br />
另外不要试图使用一些特殊的编译器来进行编译内核，比如-C09。因为Linux内核的源码已经手工调整为适于GNU C编译器。用特殊的编译器可能会降低内核运行的效率并且导致一些错误的代码。注意除非你真的清楚你在做什么，否则对内核参数的不当修改反而可能导致系统性能的下降。</p>
<p><span>3.8 改变内核参数</span><br />
<span>虽然对大多数用户我们不建议更改和重新编译内核源代码,但是Linux内核提供了另一种方法来调整内核参数。Proc文件系统提供了一个运行的内核的接口，可以被用来检测和修改内核参数。</span><br />
<span>如果要查看目前的内核的参数，可以在/proc/sys目录下用cat命令选择相应的文件。下面的例子里我们查看系统目前的内存overcommit strategy参数。输出0代表在应用分配到内存之前系统一直检测可用内存信息，我们可以通过echo命令来改变默认的值，值1在例子中的含义是内核在分配内存之前不进行检查确认内存分配情况。</span><br />
<img src="http://blog.zhangjianfeng.com/wp-admin/%5Ccn%5Csupport%5Ctscdoc%5Cimages%5CXPXP-6ZN2KA_3.gif" border="0" alt="" width="658" height="78" /></p>
<p><span>例子中用cat和echo改变内核参数是快速和有效的，可以用在任何有proc文件系统的系统中，但这种方法有下面两个不足</span><br />
<span>·echo命令不能执行参数的一致性检查。</span><br />
<span>·所有对内核的改变在系统重新启动后都会失去。</span><br />
<span>Sysctl命令可以帮助系统管理员克服上述的问题，</span><br />
<span>另外，Red Hat Enterprise Linux 3和4提供了一个图形化的工具来修改sysctl参数，执行下面的命令启动此工具</span><br />
<span>/usr/bin/redhat-config-proc</span><br />
<img src="http://blog.zhangjianfeng.com/wp-admin/%5Ccn%5Csupport%5Ctscdoc%5Cimages%5CXPXP-6ZN2KA_4.gif" border="0" alt="" width="600" height="422" /></p>
<p><span>注：默认情况下内核已经加载了不需要重新启动系统生效sysctl修改结果的模块，然而如果你在安装系统时去掉了对此模块的支持，那么在使用sysctl修改后就不得不重新启动系统来使所做的修改生效。</span></p>
<p><span>3.8.1 内核参数对应目录</span><br />
<span>控制内核运行的参数存储在/proc目录下，可以简单通过查看/proc目录树下的文件来查看关于内核、处理器、内存、网络和其他部分的内核参数的配置情况。系统下运行的每个进程在proc下都有一个对应的以PID命名的目录。下表列出了一些目录存储的内核信息</span></p>
<table border="1">
<tbody>
<tr valign="top">
<td width="284"><span>文件/目录</span></td>
<td width="284"><span>信息</span></td>
</tr>
<tr valign="top">
<td width="284"><span>/proc/sys/abi/*</span></td>
<td width="284"><span>用于提供对外部二进制的支持，不是传统的Linux，比如SCO UnixWare 7、SCO OpenServer和SUN Solaris 2。默认情况下是安装的，也可以在安装过程中移除。</span></td>
</tr>
<tr valign="top">
<td width="284"><span>/proc/sys/fs/*</span></td>
<td width="284"><span>用于增加操作系统支持的文件系统和控制磁盘配额。</span></td>
</tr>
<tr valign="top">
<td width="284"><span>/proc/sys/kernel/*</span></td>
<td width="284"><span>为了调优目的，你可以启用热添加、操作共享内存、指定PID文件最大数量和syslog中的debug级别。</span></td>
</tr>
<tr valign="top">
<td width="284"><span>/proc/sys/net/*</span></td>
<td width="284"><span>调优网络，IPV4和IPV6。</span></td>
</tr>
<tr valign="top">
<td width="284"><span>/proc/sys/vm/*</span></td>
<td width="284"><span>管理缓存和缓冲区。</span></td>
</tr>
</tbody>
</table>
<p><span>3.8.2 使用sysctl命令</span><br />
<span>sysctl命令使用/proc/sys目录树下的文件名做为参数，例如，改变内核参数shmmax的值，可以通过对/proc/sys/kernel/shmmax文件使用cat命令显示当前值并且使用echo命令进行修改。</span><br />
<span>#</span><strong><span>cat /proc/sys/kernel/shmmax</span></strong><br />
<span>33554432</span><br />
<span>#</span><strong><span>echo 33554430 &gt; /proc/sys/kernel/shmmax</span></strong><br />
<span>#</span><strong><span>cat /proc/sys/kernel/shmmax</span></strong><br />
<span>33554430</span></p>
<p><span>然而使用上述命令容易出现错误，所以我们建议使用sysctl命令因为sysctl命令在更改之前会进行一致性的检查，示例如下</span><br />
<span>#</span><strong><span>sysctl kernel.shmmax</span></strong><br />
<span>kernel.shmmax = 33554432</span><br />
<span>#</span><strong><span>sysctl -w kernel.shmmax=33554430</span></strong><br />
<span>kernel.shmmax = 33554430</span><br />
<span>#</span><strong><span>sysctl kernel.shmmax</span></strong><br />
<span>kernel.shmmax = 33554430</span></p>
<p><span>这个改变必须在一次重新启动后才会生效，如果你想长期改变参数，可以通过修改/etc/sysctl.conf文件加入附加的行来实现</span><br />
<span>kernel.shmmax = 33554439</span></p>
<p><span>在下一次重新启动后，改变的参数文件将被读取，如果你不想重新启动系统可以通过执行下面命令来使改变生效</span><br />
<span>#sysctl -p</span><br />
<span>3.9 内核参数</span><br />
<span>Linux 2.4和2.6内核包括了一些可以优化系统性能的内核参数，下表列出了一些与性能相关的内核参数</span></p>
<table border="1">
<tbody>
<tr valign="top">
<td width="199"><span>参数</span></td>
<td width="369"><span>描述和例子</span></td>
</tr>
<tr valign="top">
<td width="199"><span>net.ipv4.inet_peer_gc_maxtime</span></td>
<td width="369"><span>在较低的内存压力下garbage collector(gc)忽略存储内存池的频率，默认值是120</span><br />
<span>sysctl -w net.ipv4.inet_peer_gc_maxtime=240</span></td>
</tr>
<tr valign="top">
<td width="199"><span>net.ipv4.inet_peer_gc_mintime</span></td>
<td width="369"><span>设置garbage collector可以清除内存的最小时间，如果你的服务器负载比较重，可以尝试增加这个值，默认值是10</span><br />
<span>sysctl -w net.ipv4.inet_peer_gc_mintime=80</span></td>
</tr>
<tr valign="top">
<td width="199"><span>net.ipv4.inet_peer_maxttl</span></td>
<td width="369"><span>Inet入口的最大存活时间，在这个时间之后新入口将过期，默认值是600</span><br />
<span>sysctl -w net.ipv4.inet_peer_maxttl=500</span></td>
</tr>
<tr valign="top">
<td width="199"><span>net.ipv4.inet_peer_minttl</span></td>
<td width="369"><span>Inet入口的最小存活时间，这个时间必须比net.ipv4.inet_peer_threshold参数小，默认值是120</span><br />
<span>sysctl -w net.ipv4.inet_peer_minttl=80</span></td>
</tr>
<tr valign="top">
<td width="199"><span>net.ipv4.inet_peer_threshold</span></td>
<td width="369"><span>设定inet的存储容量，当这个限制达到后，入口将被丢掉，使用net.ipv4.inet_peer_gc_mintime限制超时限制，默认值是65644</span><br />
<span>sysctl -w net.ipv4.inet_peer_threshold=65644</span></td>
</tr>
<tr valign="top">
<td width="199"><span>vm.hugetlb_pool</span></td>
<td width="369"><span>通常在使用Oracle或者DB2等数据库时会用到这个值，默认值是0</span><br />
<span>sysctl -w vm.hugetlb_pool=4608</span></td>
</tr>
<tr valign="top">
<td width="199"><span>vm.inactive_clean_percent</span></td>
<td width="369"><span>指定应该被清除的非活动内存的百分比，默认值是5%</span><br />
<span>sysctl -w vm.inactive_clean_percent=30</span></td>
</tr>
<tr valign="top">
<td width="199"><span>vm.pagecache</span></td>
<td width="369"><span>指定多少内存应该被用为页面缓存，这个参数对Oracle和DB2等数据库来说是很重要的，默认值是1 15 100。</span><br />
<span>参数的三个值的含义：</span><br />
<span>·做为页面缓存的最小内存百分比，默认是1%</span><br />
<span>·缓存的初始化数量，默认是15%</span><br />
<span>·做为页面缓存的最大内存百分比，默认是100%</span><br />
<span>sysctl -w vm.pagecache=1 50 100</span></td>
</tr>
</tbody>
</table>
<p><span>下表是一些不常使用的性能相关的内核参数</span></p>
<table border="1">
<tbody>
<tr valign="top">
<td width="284"><span>参数</span></td>
<td width="284"><span>描述和例子</span></td>
</tr>
<tr valign="top">
<td width="284"><span>kernel.panic_on_oops</span></td>
<td width="284"><span>启用内核对crash进程的检测和处理，kernel.panic参数必须设为1。该参数默认值为1（启用）</span><br />
<span>sysctl -w kernel.panic_on_oops=0</span></td>
</tr>
<tr valign="top">
<td width="284"><span>kernel.pid_max</span></td>
<td width="284"><span>可以分配的最大的PID，默认值是32768</span><br />
<span>sysctl -w kernel.pid_max=65536</span></td>
</tr>
<tr valign="top">
<td width="284"><span>net.ipv4.tcp_tw_recycle</span></td>
<td width="284"><span>主要的tcp连接状态有ESTABLISHED,TIME_WAIT和CLOSED,这个参数可以快速的再生TIME_WAIT连接，默认是0（禁用）</span><br />
<span>sysctl -w net.ipv4.tcp_tw_recycle=0</span></td>
</tr>
<tr valign="top">
<td width="284"><span>vm.overcommit_ratio</span></td>
<td width="284"><span>允许过载使用的内存百分比，默认是50％。</span><br />
<span>sysctl -w vm.overcommit_ratio=17</span></td>
</tr>
</tbody>
</table>
<p><span>3.10 调优处理器子系统</span><br />
<span>在一个hand-held设备或者一个科学运算群集环境中，处理器子系统是性能优劣的关键。在过去的十年中莫尔定律使处理器子系统比其他子系统或者了更快的发展，所以现在很少有性能瓶颈出现在处理器子系统上，除非特殊情况下处理器的数量是系统唯一的性能目标。我们经常看到一些intel架构的服务器的CPU利用率一直低于10％，这里我们要说的是了解处理器级别的性能瓶颈和了解可以改变CPU性能的调优参数是十分重要的。</span><br />
<span>在高端Xeon服务器上，我们可以选择是否启用超线程技术（Hyper-Threading）。超线程意味着每个物理CPU在操作系统下将被认成两个CPU，这个技术是基于并行多线程技术（symmetric multithreading，SMT）的完全被Linux内核所支持。使用SMT技术可以在一个CPU上同时执行两个进程或者线程（也被称为线程级别的并行）。如果操作系统和应用软件都支持并行操作，那么在不增加CPU时钟频率的情况下也可以提高系统的性能。</span><br />
<span>例如在一个启用了超线程的4路服务器上，使用像top这样的监测工具可以看到8个CPU</span></p>
<p><span>关于超线程注意以下几点</span><br />
<span>·启用超线程需要SMP内核支持</span><br />
<span>·安装在服务器上的CPU越多，超线程对性能带来的提高就越少。</span><br />
<span>-两个物理CPU：性能提高15-25％</span><br />
<span>-四个物理CPU：性能提高1-13%</span><br />
<span>-八个物理CPU：性能提高0-5%</span><br />
<span>关于超线程的更多信息可以在下面链接查询</span><br />
<span style="color: #0000ff;"><a href="http://www.intel.com/business/bss/products/hyperthreading/server/">http://www.intel.com/business/bss/products/hyperthreading/server/</a></span><br />
<span>EM64T是基于Intel IA-32架构的CPU64bit扩展技术，这意味着CPU可以扩展寻址更多的内存空间并且可以同时支持64bit应用和现存的32bit应用。关于EM64T的更详细的信息可以查看下面链接</span><br />
<span style="color: #0000ff;"><a href="http://www.intel.com/technology/64bitextensions/">http://www.intel.com/technology/64bitextensions/</a></span></p>
<p><span>3.10.1 正确的选择内核</span><br />
<span>Red Hat Enterprise Linux AS包括几个内核版本，为了性能方面的考虑，请确认为系统选择了最合适的内核</span></p>
<table border="1">
<tbody>
<tr valign="top">
<td width="284"><span>内核类型</span></td>
<td width="284"><span>描述</span></td>
</tr>
<tr valign="top">
<td width="284"><span>SMP</span></td>
<td width="284"><span>内核支持SMP和超线程</span></td>
</tr>
<tr valign="top">
<td width="284"><span>Hugemem</span></td>
<td width="284"><span>支持超过12GB的内存，包括支持NUMA</span></td>
</tr>
<tr valign="top">
<td width="284"><span>Standard</span></td>
<td width="284"><span>单处理器机器</span></td>
</tr>
</tbody>
</table>
<p><span>3.10.2 中断处理</span><br />
<span>CPU处理的优先级最高的任务之一就是中断。中断可以被一个子系统发起，例如一个网卡。硬中断使CPU停止目前的工作并且执行一个context switch，这个操作令CPU必须将缓存清空来执行新的任务（我们可以认为CPU的缓存是一个工作区，当新任务需要被执行时必须清空缓存）。下面两个原则会让中断处理更有效，</span><br />
<span>·绑定中断到CPU</span><br />
<span>系统管理员可以将中断和一个或者一组CPU进行绑定（当然这个操作对于一个单CPU系统是没有作用的）。为了改变IRQ的关联，需要进入/proc/irq/%{相应中断号}目录中修改smp_affinity文件的内容，例如讲IRQ19与第三个CPU进行关联，可以使用下面命令服务</span><br />
<img src="http://blog.zhangjianfeng.com/wp-admin/%5Ccn%5Csupport%5Ctscdoc%5Cimages%5CXPXP-6ZN2KA_6.gif" border="0" alt="" width="704" height="43" /></p>
<p><span>·使用物理CPU来处理中断</span><br />
<span>在SMT系统中，例如支持超线程的Inter Xeon CPU，建议绑定中断到物理CPU从而避免中断使用虚拟CPU。在一个开启超线程功能的两路系统中，物理CPU通常被分配较低的CPU编号，CPU ID 0和2更可能是物理CPU，而CPU ID 1和3通常是超线程技术的虚拟CPU。如果你不使用smp_affinity标识，你可能要担心中断处理会被分配给虚拟CPU。</span></p>
<p><span>3.10.3 NUMA系统</span><br />
<span>非一致性内存访问（NUMA）系统已经获得了越来越大的市场份额，虽然现在的Linux发行版本的内核可以更好的适应NUMA系统，但是应用程序并不都适用与NUMA系统。一个非NUMA系统可能导致性能的降低。在numactl安装包中的新的numastat程序可以帮助你检查进程在NUMA架构下的运行情况。为了帮助定位瓶颈，numastat工具提供了统计信息存储在/sys/devices/system/node/%节点数/numastat中。</span></p>
<p><span>3.11 调优内存子系统</span><br />
<span>调优内存子系统是一个艰难的工作，它要求持续的监控系统的性能并且确保对参数的调整不会对其他子系统产生消极影响。如果你选择修改虚拟内存参数（在/proc/sys/vm中），我们建议你每次只改变一个参数然后检测调优效果如何。大多数Linux系统下的应用都不直接将数据写入磁盘，而是写入由虚拟内存管理器维护的文件系统缓存中，并且最终会刷新数据。当使用IBM ServeRAID控制器或者IBM TotalStorage磁盘系统时，你应该尝试减少刷新的次数，有效的增加每个刷新的I/O流量。高性能的磁盘控制器可以有效的处理更大的I/O流量。</span><br />
<span>3.11.1 配置bdflush</span><br />
<span>调优虚拟内存子系统可以帮助改善整个文件系统的性能。内核进程bdflush是负责处理缓冲区里的dirty数据。再/proc系统中改变参数将立刻生效但是再下一次重启后将被恢复。为了长期有效的改变内核参数可以通过使用echo或者sysctl命令来修改/etc/rc.d/local中的文件来实现。</span><br />
<span>配置Linux内核如何刷新缓冲区中的dirty数据可以使刷新算法可以适用不同的磁盘子系统。磁盘缓冲区是用来缓存要存储在硬盘上的数据，相比内存访问速度比较慢。因此如果服务器使用这类存储会对洗头的性能产生影响。通过修改/proc/sys/vm/bdflush参数可以更改磁盘缓冲区刷新频率，可以避免磁盘冲突问题。编辑bdflush参数可以使用echo命令或者sysctl命令，下面主要介绍使用sysctl的方法，sysctl命令示例，</span></p>
<p><span>在Linux 2.4内核中/proc/sys/vm/bdflush中的九个参数含义如下</span><br />
<span>nfract：dirty缓冲在缓冲区中的最大百分比。超过这个值将bdflush进程刷新硬盘。当可用内存比较少的情况下，将引发大量的磁盘I/O。为了均衡磁盘I/O，可以保持一个比较低的值。</span><br />
<span>Ndirty：bdflush进程一次写入磁盘的最大dirty缓冲块数量。这个值比较大将导致I/O急剧增加，如果这个比较小，bdflush进程执行不够从而可能导致内存的瓶颈。</span><br />
<span>Dummy2 ：未使用</span><br />
<span>Dummy3：未使用</span><br />
<span>Interval：kupdate工作和刷新的最小频率，默认值是5秒。最小值是0秒最大值是600秒。</span><br />
<span>Age_buffer：缓冲数据写到磁盘之前操作系统等待的最大时间。默认值是30秒，最小值是1秒最大值是6000秒。</span><br />
<span>Nfract_sync：dirty缓存激活bdflush进程同步的百分比。默认值是60%。</span><br />
<span>Nfract_stop：dirty缓存停止bdflush进程的百分比。默认值是20%。</span><br />
<span>Dummy5：未使用</span></p>
<p><span>3.11.2 配置kswapd</span><br />
<span>配置kswapd daemon，指定Linux的内存交换页数量sysctl -w vm.kswapd=”1024 32 64&#8243;三个参数的描述如下：– tries_base 相当于内核每次所交换的“页”的数量的四倍。对于有很多交换信息的系统，增加这个值可以改进性能。– tries_min 是每次kswapd swaps出去的pages的最小数量。– swap_cluster 是kswapd 即刻写如的pages数量。数值小，会提高磁盘I/O的性能；数值大可能也会对请求队列产生负面影响。如果要对这些参数进行改动，请使用工具vmstat检查对性能的影响。其它可以改进性能的虚拟内存参数为：_ buffermem_ freepages_ overcommit_memory_ page-cluster_ pagecache_ pagetable_cache</span></p>
<p><span>3.11.3 设定内核的交换动作</span><br />
<span>在Linux 2.6内核的虚拟内存管理器中为管理员提供了简单的调整交换空间的方法。调整交换分区的参数存储在/proc/sys/vm/swappiness中，可以通过这个参数来定义如何将内存页面交换到磁盘上。在1.3章节中我们讨论了Linux虚拟内存管理器和交换空间的使用，描述了Linux即使在依然有足够可用内存的情况下依然会移动不被接受的内存页面到swap空间。通过改变/proc/sys/vm/swappiness中的百分比你可以根据系统配置的需要控制这个操作。如果不想频繁的进行页面交换可以设置较低的值。但是对一些保持sleep状态很长时间的进程来说，页面交换将带了性能的提升。改变这个参数可以使用echo或者sysctl命令，示例如下：</span></p>
<p><span>3.11.4 HugeTLBfs</span><br />
<span>这个内存管理特性对需要使用大量虚拟地址空间的应用是非常有价值的，尤其是对数据库应用。</span><br />
<span>CPU的Translation Lookaside Buffer (TLB)是一个小的缓存用来存储虚拟到物理地址的映射信息。通过使用TLB，一次交换可以在不经过内存页面表入口的情况下完成。然而为了保持交换尽可能快，TLB容量通常都十分小，大内存应用需要更多的TLB空间。HugeTLBfs特性允许应用使用比平时更大的内存空间，以便单独的TLB可以映射更大的地址空间。一个HugeTLBfs登陆的大小是可变的。例如，在Itanium@2系统中，一个大页面可能是普通系统的1000倍。这个特性启用了TLB可以映射1000倍的虚拟地址空间在没有TLB缓存失败的情况下。简单的说，这个特性为应用程序提供了一个文件系统接口。</span></p>
<p><strong><span>3.12 调优文件系统</span></strong><br />
<span>最终所有数据都是要存储在硬盘上的，硬盘访问的速度通常都是毫秒级别的，这个速度与内存和PCI设备纳秒和微秒级别的访问速度要慢上千倍。Linux文件系统是在硬盘上进行数据存储和管理的方法。</span><br />
<span>Linux有多种可用的文件系统，它们的性能和可扩展性各有特点。除了存储和管理硬盘上的数据，文件系统也负责保持数据的一致性。新的Linux发行版本包括日志文件系统做为默认安装的一部分。日志可以在系统宕机时保持数据的一致性，所有对文件系统元数据的修改都被维护在一个单独的日志中，并且可以在系统宕机后恢复数据的一致状态。日志也可以加快恢复时间，因为在系统重新启动不需要进行文件系统检查的操作。另一方面，你也需要平和性能和数据完整性之间的关系，但使用在数据中心或者企业级应用中的Linux服务器对高可用性是有着严格的要求的。在这部分我们介绍Red Hat Enterprise Linux AS默认的和其他文件系统的一些简单的调优方法。</span></p>
<p><span>3.12.1 安装Linux系统前的硬件准备</span><br />
<span>目前的Linux发行版本都有文档来要求安装系统的硬件配置的最小要求,比如最小的CPU频率和内存大小，也会提供完全安装系统所需的最小的磁盘空间。然而这些文档都没有提供如何初始化磁盘子系统，因为Linux服务器可以适应各种不同的应用环境，所以我们需要面对的第一个问题是：需要安装的Linux服务器的应用环境是什么？</span><br />
<span>服务器的磁盘子系统是系统性能的主要组成部分，判断I/O子系统是否会对系统性能产生直接影响首先需要理解服务器所运行的应用。下面例子帮助我们理解I/O子系统和应用的关系，</span><br />
<span>磁盘I/O对性能影响很大的服务器例子：</span><br />
<span>·一个文件和打印服务器必须快速的在用户和磁盘子系统间移动数据，因为文件服务器的目</span><br />
<span>的就是分发文件到各个客户端，服务器对磁盘上的数据有大量的访问操作。</span><br />
<span>·一个数据库服务器最终目的是查找和处理存储在磁盘上的数据。即使有足够的内存，大多数数据库服务器还是需要执行大量的磁盘I/O操作来进行内存和硬盘之间的数据交换。</span><br />
<span>磁盘I/O对性能影响很小的服务器例子：</span><br />
<span>·一个邮件服务器的功能是对电子邮件进行存储和发送，通常会产生大量的网络通信负载，在这样的服务器里网络是更重要的参数。</span><br />
<span>·一个web服务器的功能是提供对web页面的访问支持（包括静态的、动态的或者两者都有），对这样的服务器来讲，网络和内存子系统是更好的调优选择。</span></p>
<p><span>磁盘技术的选择</span><br />
<span>在安装部署服务器之前需要了解应用的规模，目前不同磁盘子系统技术所适合的应用环境也是不相同的，下表列出了在ibm xSeries服务器上所用到的磁盘技术和相关特性。</span></p>
<table border="1">
<tbody>
<tr valign="top">
<td width="142"><span>技术</span></td>
<td width="142"><span>价格</span></td>
<td width="142"><span>功能</span></td>
<td width="142"><span>限制和容量</span></td>
</tr>
<tr valign="top">
<td width="142"><span>EIDE</span></td>
<td width="142"><span>低价格</span></td>
<td width="142"><span>直连存储；例如低端服务器的本地硬盘（x305）</span></td>
<td width="142"><span>是用来连接内部存储的增强型IDE，每个EIDE控制器支持两个硬盘</span></td>
</tr>
<tr valign="top">
<td width="142"><span><acronym title="Small Computer System Interface">SCSI</acronym></span></td>
<td width="142"><span>低价格</span></td>
<td width="142"><span>直连存储：中端或者高端服务器的本地存储（x346，x365）</span></td>
<td width="142"><span>虽然scsi标准有超过10年的发展历史，但目前高端服务器的I/O需求已经超过了scsi的能力，scsi技术的限制包括线缆长度，总线上连接服务器数量,传输速度，总线上可访问的设备数量等，这些都影响了集群系统的可扩展性。</span></td>
</tr>
<tr valign="top">
<td width="142"><span>Serial ATA(SATA)</span></td>
<td width="142"><span>低价格</span></td>
<td width="142"><span>中端数据存储应用</span></td>
<td width="142"><span>从2002年发展起来的SATA新标准在硬盘/主板接口上继承了EIDE的技术，是点对点的传输协议，为每个设备提供了一个单独的通道。在顺序磁盘访问应用上SATA可以与<acronym title="Small Computer System Interface">SCSI</acronym>相比，在随机磁盘访问上稍逊于<acronym title="Small Computer System Interface">SCSI</acronym>技术，SATA技术也支持<acronym title="Redundant Array of Inexpensive Disks">RAID</acronym>功能。</span></td>
</tr>
<tr valign="top">
<td width="142"><span>iSCSI</span></td>
<td width="142"><span>适中的价格</span></td>
<td width="142"><span>中端存储，例如文件或者web服务器</span></td>
<td width="142"><span>iSCSI技术主要适合中端存储和远程启动需要，主要的优点是相对较低的成本和无盘服务器，也提供了基于TCP/<acronym title="Internet Protocol">IP</acronym>/以太网的可扩展性和可靠性。同时TCP/<acronym title="Internet Protocol">IP</acronym>的高延迟也对性能产生了一些影响。</span></td>
</tr>
<tr valign="top">
<td width="142"><span>Fibre Channel</span></td>
<td width="142"><span>高价格</span></td>
<td width="142"><span>企业级存储，例如数据库</span></td>
<td width="142"><span>提供了低延迟和高吞吐量能力并且克服了scsi技术的一些限制，通过光纤链路线缆距离可以扩展到10km，2Gbps传输速度，提供冗余链路改善可靠性，理论上可以连接1600万个设备，在loop拓扑中，127个存储设备或者服务器可以共享同一个光纤通道连接，允许部署更大规模的集群。</span></td>
</tr>
</tbody>
</table>
<p><span>关于ibm存储的更多信息请访问下面链接</span><br />
<span style="color: #0000ff;"><a href="http://www.ibm.com/storage">http://www.ibm.com/storage</a></span></p>
<p><span>磁盘的数量</span><br />
<span>磁盘的数量会对系统的性能产生重要的影响，因为每个硬盘都会对整个系统的吞吐量做出贡献。在配置服务器硬盘数量的时候，磁盘的容量要求通常被作为唯一的参考。吞吐量要求经常没有被很好的考虑甚至被完全忽略。一个性能良好的磁盘子系统的关键是最优化可以提供I/O请求的读写操作。</span><br />
<span>通过<acronym title="Redundant Array of Inexpensive Disks">RAID</acronym>(redundant array of independent disks)技术，可以将I/O请求分成条带化处理，在Linux环境下部署<acronym title="Redundant Array of Inexpensive Disks">RAID</acronym>有两种选择：软件<acronym title="Redundant Array of Inexpensive Disks">RAID</acronym>和硬件<acronym title="Redundant Array of Inexpensive Disks">RAID</acronym>。你可以通过Linux发行版本自带的软件<acronym title="Redundant Array of Inexpensive Disks">RAID</acronym>来配置，如果需要，也能升级使用更有效率的硬件<acronym title="Redundant Array of Inexpensive Disks">RAID</acronym>解决方案。在Linux 2.4内核中，软件阵列的实现是通过md设备驱动来实现的，这个驱动的实现是不依靠设备类型的，因此可以灵活的部署多种磁盘子系统，比如EIDE或者<acronym title="Small Computer System Interface">SCSI</acronym>磁盘都可以配置软件阵列。软件<acronym title="Redundant Array of Inexpensive Disks">RAID</acronym>支持的阵列级别有<acronym title="Redundant Array of Inexpensive Disks">RAID</acronym>-0(条带化)，<acronym title="Redundant Array of Inexpensive Disks">RAID</acronym>-1(镜像)和RAID5（带校验位的条带化），可以在初始化安装的过程中或者使用mdadm工具进行配置。</span><br />
<span>如果必须部署一个硬件<acronym title="Redundant Array of Inexpensive Disks">RAID</acronym>阵列，你的系统需要一个<acronym title="Redundant Array of Inexpensive Disks">RAID</acronym>控制器，在这种情况下磁带子系统包括物理磁盘和控制器，IBM提供了完整的磁盘控制器产品线。</span><br />
<span>注：通常增加硬盘是最有效的改变服务器性能的方法之一。</span><br />
<span>3.12.2 其他日志文件系统</span><br />
<span>下面是Linux可用的文件系统，但在Red Hat Enterprise Linux安装过程中并不可用。</span><br />
<span>·ReiserFS</span><br />
<span>ReiserFS是一个快速日志文件系统，特点是可以提供优化的磁盘利用率和快速的crash恢复，是SUSE LINUX默认的文件系统。</span><br />
<span>·JFS</span><br />
<span>JFS是一个全64bit的文件系统可以支持更大的文件和分区。JFS是由IBM为AIX系统开发的，现在可用于<acronym title="GNU General Public License">GPL</acronym> license。在HPC和数据库应用中JFS是一个理想的文件系统，因为可以提供更大的分区和文件容量。</span><br />
<span>·XFS</span><br />
<span>XFS是一个SGI开发的高性能的日志文件系统。特性和使用与IBM的JFS很相似。</span></p>
<p><span>3.12.3 在2.4内核中调整elevator算法</span><br />
<span>磁盘I/O elevator算法是Linux 2.4内核的一个特性，通过调整elevator算法的读写值可以增加延迟时间使I/O请求在队列中等待更多的时间，从而使得I/O调度器可以有更多的时间来完成I/O操作，可以提高系统的吞吐量。</span></p>
<p><span>如果你的Linux服务器应用于大量的磁盘I/O操作的环境，在吞吐量和延迟方面找到一个合理的平衡点是很重要的。Linux文件系统使用块设备，因此改变块读写的频率可以改善未经系统的性能。一个方针是，较小的缓存和平衡的高延迟读写对I/O操作比较重的服务器是有益的。</span><br />
<span>像其他系统的调优参数一样，对elevator算法的调整是一个重复的过程。你需要对现有磁盘性能做出评估，然后做出改变，最后再测试出改变参数所产生的影响。下面是使用/sbin/elvtune命令去查看当前参数值随后做出改变的例子：</span><br />
<span>Red Hat建议您将读延迟（-r）调整为写延迟(-w)的一半。如果对算法进行的调整，需要把/sbin/elvtune调用加到/etc/rc.d/rc.local文件中以确定在下次系统重新启动后改变依然生效。</span><br />
<span>下面是查看默认值并且做出改变的示例</span></p>
<p><span>3.12.4在Linux 2.6内核中选择正确的I/O elevator算法</span><br />
<span>对大多数应用来说，complete fair queuing(CFQ) elevator算法是一个合适的选择，它已经对一个典型的多用户、多处理器环境做了相应的优化。但是，一些特定的环境下选择其他的I/O elevator可能会获得更好的效果。</span><br />
<span>·智能的磁盘子系统</span><br />
<span>benchmark测试结果显示NOOP elevator在高端服务器环境下可以给性能带来有趣的变化，当使用IBM ServeRAID或者TotalStorage DS系列磁盘子系统的情况下，缺少命令能力的NOOP elevator显示出了它的优势，因为智能磁盘子系统例如IBM ServeRAID和TotalStrrage DS系统磁盘子系统用自己的I/O命令能力弥补了NOOP elevator的缺点。企业级的磁盘子系统通常包括多个<acronym title="Small Computer System Interface">SCSI</acronym>或者光纤通道磁盘，每个磁盘都有独立的磁盘头和数据条带。对操作系统来说正确的处理如此复杂的I/O特性子系统是很困难的，因此你会观察到在获得性能相同的情况下使用NOOP I/O elevator会带来更少的系统资源开销。</span><br />
<span>·数据库系统</span><br />
<span>因为大多数数据库应用需要进行大量的寻址操作，所以在选择deadline elevator的情况下会获得更好的性能体现。</span><br />
<span>·虚拟机</span><br />
<span>虚拟机系统，无论是VMware或者zSeries上的VM都只在虚拟层和下面的硬件层进行通信，因此虚拟机不知道它被指派的磁盘设备是一个单独的<acronym title="Small Computer System Interface">SCSI</acronym>磁盘设备或者是多个光纤磁盘组成的磁盘阵列设备。虚拟层只关注必需的I/O记录和与物理设备之间的通信。因此，我们建议为虚拟机选择使用NOOP elevator以确保更少的系统资源开销。</span><br />
<span>·单独ATA或者SATA磁带子系统</span><br />
<span>如果你选择使用单独ATA或者SATA的磁盘子系统，考虑使用anticipatory I/O elevator会获得比较好的性能。</span></p>
<p><span>3.12.5 访问时间更新</span><br />
<span>Linux文件系统当文件被创建、更新和访问的情况下都会进行记录，默认情况操作包括更新最近读取时间属性(last-time-read)当文件被读写的时候，因为写操作是一个“昂贵”的操作，排除不必要的I/O操作可以提升整个系统的性能。Mount文件系统的时候加入noatime和nodirtime选项可以避免inode时间访问记录被更新，如果文件和目录的更新时间对你的应用来说并不关键，比如一个web服务器环境，系统管理员应该选择mount文件系统附上noatime和nodirtime选项来改善性能，可以将改变写入/etc/fstab来实现长期的改变，下面是一个更新/etc/fstab的示例：</span></p>
<p><span>tips：通常为/var建立独立的分区并且mount附上noatime选项是一个好的建议。</span></p>
<p><span>3.12.6 增加操作文件数量</span><br />
<span>系统有一个重要的参数就是允许操作文件的数量，标准的Linux配置的数量可能过低从而影响性能。查看/proc/sys/file-nr对比全部指派文件数量和最大文件操作数量（第一个或最后一个值）。可以通过改变/proc/sys/fs/file-max来改变这个参数的值。</span></p>
<p><span>3.12.7 选择ext3文件系统的目录模式</span><br />
<span>ext3文件系统有三个可选的日志模式，可以通过在mount命令的附加data项来进行改变。</span><br />
<span>·data=journal</span><br />
<span>journal选项通过将文件数据和元数据都设置为日志模式，提供了最高级别的数据一致性保障。同时也带来了较高的性能开销。</span><br />
<span>·data=ordered（default）</span><br />
<span>顺序方式写入，文件数据先写入然后是元数据。</span><br />
<span>·data=writeback</span><br />
<span>提供最快的访问速度,但是牺牲了数据的一致性。元数据仍然被记录到日志，从而确保元数据的完整。文件数据会在系统崩溃之后恢复到原先的状态。</span></p>
<p><span>三种方法可以改变日志模式：</span><br />
<span>·使用mount 命令：</span><br />
<span>mount -o data=writeback /dev/sdb1 /mnt/mountpoint 这里/dev/sdb1 是挂载的文件系统</span></p>
<p><span>·在/etc/fstab文件的选项中：</span><br />
<span>/dev/sdb1 /testfs ext3 defaults,journal=writeback 0 0</span></p>
<p><span>·更改root分区的data=ordered，更改上述/etc/fstab 文件，执行mkinitrd命令来扫描/etc/fstab 文件并创建新的印象文件。升级grub或lilo指向新的印象文件。更多有关Ext3的介绍，请参考下面链接：</span><br />
<a href="http://www.redhat.com/support/wpapers/redhat/ext3/"><span style="color: #0000ff;">http://www.redhat.com/support/wpapers/redhat/ext3/</span></a></p>
<p><span>3.12.8 <acronym title="Small Computer System Interface">SCSI</acronym>设备的Tagged command queuing(TCQ)</span><br />
<span><acronym title="Small Computer System Interface">SCSI</acronym>磁盘的Tagged command queuing (TCQ)，产生于<acronym title="Small Computer System Interface">SCSI</acronym>-2标准，是一种将到达<acronym title="Small Computer System Interface">SCSI</acronym>驱动器的指令序列进行打标签和重新排序的方法。对于繁重、随机访问的I/O负荷，这种方法通过对I/O请求的重排序，使驱动器磁头位置最优化，改进I/O性能。</span><br />
<span>一些IBM xSeries服务器集成了Adaptec AIC-7xxx <acronym title="Small Computer System Interface">SCSI</acronym>控制器。执行命令：cat /proc/scsi/aic7xxx/0来检查当前TCQ的设置，可以在/usr/src/linux-2.4/drivers/scsi/README.aic7xxx中查看scsi设备设定的细节。</span><br />
<span>不必重新编译内核。可以在/etc/modules.conf中添加如下两行内容，指定参数aic7xxx=global_tag_depth:xx， </span><br />
<span>注：如果在/etc/modules.conf里更改了initrd中的模块，需要使用mkinitrd命令重新生成initrd image。</span></p>
<p><span>3.12.9 Block sizes大小</span><br />
<span>数据块大小是对磁盘读写的最小单位，直接影响服务器性能。如果服务器处理的多为小文件，那么较小的数据块尺寸会更有效。反之，如果服务器处理的多为大文件，大的数据尺寸块会提高系统性能。如果要改变数据块的大小必须重新格式化磁盘。做了<acronym title="Redundant Array of Inexpensive Disks">RAID</acronym>的磁盘，stripe size 就是数据块的容量（光纤盘采用segment）。根据应用的不同合理选择正确的块大小，通常的原则是顺序读写应使用大的块容量，象数据库这样的随机读写操作使用等同于记录大小的块容量更合适。</span><br />
<span>Red Hat Enterprise Linux允许的block sizes有1K，2K和4K。</span></p>
<p><span>3.12.10 分区设置的原则</span><br />
<span>一个分区是磁盘上一组连续的数据块，就好像是独立的磁盘一样。Red Hat Enterprise Linux 3默认只安装三个简单的分区，在Red Hat Enterprise Linux 4中通过使用逻辑卷提供了更灵活的分区划分。</span><br />
<span>关于Linux磁盘分区的优化存在许多的争论。如果只有一个根分区的话，对于将来要增加新分区时会比较麻烦。而分区太多对文件系统的管理又会变的复杂。Linux安装过程中，允许创建多个分区。</span><br />
<span>创建多个磁盘分区的好处：</span><br />
<span>·文件系统出色的颗粒度属性使安全性得到改进。例如，允许所有用户和进程容易地访问/var和/tmp分区，并防止恶意访问。通过将这些分区分布到不同的磁盘，可在不影响系统正常运行的情况下对一些分区进行重建和恢复。</span><br />
<span>·某块磁盘故障导致的数据丢失不影响其他磁盘的数据，改进数据完整性。</span><br />
<span>·全新的安装或升级不影响其它分区。</span><br />
<span>·更有效的备份过程</span></p><h2  class="related_post_title">类似的文章</h2><ul class="related_post"><li>2009年05月24日 -- <a href="http://www.penglixun.com/tech/system/load_average_concept.html" title="load average概念理解">load average概念理解</a> (0)</li><li>2012年01月23日 -- <a href="http://www.penglixun.com/tech/database/case_about_innodb_faster_than_oracle.html" title="一个InnoDB性能超过Oracle的调优Case">一个InnoDB性能超过Oracle的调优Case</a> (1)</li><li>2010年08月27日 -- <a href="http://www.penglixun.com/tech/system/linux_cache_discovery.html" title="Linux Cache 机制探究">Linux Cache 机制探究</a> (1)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.penglixun.com/tech/system/tuning_redhat_enterprise_linux_in_ibm_system_x_server.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[回顾]清华申请退学博士作品：完全用Linux工作</title>
		<link>http://www.penglixun.com/life/feeling/all_works_in_linux.html</link>
		<comments>http://www.penglixun.com/life/feeling/all_works_in_linux.html#comments</comments>
		<pubDate>Mon, 16 Mar 2009 01:27:20 +0000</pubDate>
		<dc:creator>P.Linux</dc:creator>
				<category><![CDATA[心灵感触]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[博士]]></category>
		<category><![CDATA[清华]]></category>
		<category><![CDATA[王垠]]></category>
		<category><![CDATA[退学]]></category>

		<guid isPermaLink="false">http://www.penglixun.com/PLX/blog/?p=102</guid>
		<description><![CDATA[本文内容遵从CC版权协议, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://www.penglixun.com/life/feeling/all_works_in_linux.html 按: 尽管我们已经不习惯看长篇大论, ... ]]></description>
			<content:encoded><![CDATA[<p><span style="color: #888888;">本文内容遵从<a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh" target="_blank">CC版权协议</a>, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明</br>网址: http://www.penglixun.com/life/feeling/all_works_in_linux.html </p>
<p></span><strong>按: 尽管我们已经不习惯看长篇大论, 但我还是要说, 这是一篇值得你从头读到尾的长篇文章.<br />
2005年9月22日，清华在读博士生王垠在水木社区BLOG上发表了《清华梦的粉碎&#8211;写给清华大学的退学申请》明确要求退学, </strong>引起社会各界广泛争论. 他创作的长篇文章《完全用Linux工作》, <strong>洋洋两万多字, 从不同角度居高临下的阐述了他眼中Linux完全优越于Windows的各种理由, </strong>这篇文章并不简单的是一篇论述”Windows能做的事Linux都能做”这样的文章, 通篇洋溢着一个彻底批判 Windows 平台基础的计算机哲学, 计算机应用和计算机教育体系的人的万丈豪情, 尽管可能偏激, 也不乏详细的推理论述. <strong>今天我们重温本文, 一方面也是因为CB上喜爱和推广Linux的人士很多, 有时也会爆发小规模论战, 我们希望能通过对本文的研究与讨论, 来窥测国内部分Linux推广者的心态, 同时为大家提供更宽广的讨论空间.</strong><br />
<span id="more-102"></span><br />
我已经半年没有使用 Windows 的方式工作了。Linux 高效的完成了我所有的工作。</p>
<p>GNU/Linux 不是每个人都想用的。如果你只需要处理一般的事务，打游戏，那么你不需要了解下面这些了。</p>
<p>我不是一个狂热的自由软件份子，虽然我很喜欢自由软件。这篇文章也不是用来推行自由软件运动的，虽然我觉得自由软件运动是非常好的。</p>
<p>这篇文章也不是用来比较 Linux 和 Windows 内核效率，文件系统，网络服务的。我现在是作为一个用户而不是一个开发者来说话的，我们的讨论是基于操作，应用层面的。是为了告诉大学里还不了解，或者不理解 UNIX 的科学工作者和大学生，UNIX 比 Windows 更适合用于科学研究工作，请大家理解 UNIX 的工作方式，不要用 Windows 的标准来要求 Linux，而要用一个科学工作者的标准来要求自己，用UNIX 的思想来武装自己。</p>
<p>我显然是反对在大学，特别是理工科专业推广 Windows 的。我也反对在对”娃娃”们的计算机启蒙教育中使用 Windows。因为<em> Windows 不论从技术上，经济上，思想风格上都是与我们培养高科技人才的目标格格不入的。Windows 的流行属于历史遗留问题，爷爷一级的人当然已经不可救药，但是我们不应该让下一代继续走上歧途。</em></p>
<p><strong>UNIX 不是计算机专家的专利</strong></p>
<p>当我建议一些非计算机专业的人用 Linux 的时候，很多人说：”UNIX 是计算机系的人用的，我们不能理解。” “UNIX 是男孩用的，我们女孩不用。”</p>
<p>但是其实世界上的大多数科学家和工程师几乎用的都是 UNIX 作为他们的电脑工具。就因为它简单，可靠，稳定，强大，有趣。甚至很多时候 UNIX 就是唯一的选择。</p>
<p>你说：”我们都会用 UNIX 的话，你们计算机专业的人还用来干什么？” 很容幸的告诉你，计算机专业的有一部分人就是专门为你们提供这样强大而方便的计算机工具的。如果他们制造的工具只有自己会用的话，那这个工具还有什么用？</p>
<p>理解 GNU/Linux 不要用 Windows 的标准来要求 Linux。</p>
<p>由于GNU/Linux这个词太长，下面如果没有特别指明，”Linux”就是指GNU/Linux”。</p>
<p>在这个年代，恐怕没有人需要我来介绍 Linux 是什么了吧？如果你觉得”Linux 只不过是跟 DOS 差不多的东西”，那请问问你旁边的 Linux 用户，Linux 到底是什么？</p>
<p>那为什么我还要写一篇这样的文章？因为，我发现还有很多人不不理解 Linux 和 UNIX，虽然他们也在用它，但是他们有时会问：”为什么 Linux 不能像 Windows 那样 ……？”，”怎么Redhat Linux不能 mount NTFS 分区！”，”Linux 下用什么整理硬盘？”，”什么时候OpenOffice才能完全兼容Word文件啊？”，”现在还有什么Windows能干的事情Linux干不了的？ “……</p>
<p><em>他们有40G的硬盘，却只为 Linux 分配了2G空间，有时还抱怨”这个东西怎么占这么多硬盘！” 似乎 Windows 该占用大部分硬盘。他们把重要的数据装在Windows的分区，似乎信不过Linux。他们总是到处寻找新奇的，好看的<acronym title="Graphical User Interface">GUI</acronym>程序，对命令行的东西一概不屑一顾。他们对Drag&amp;Drop，菜单配置，自动升级非常感兴趣。他们如果找到一个很像 Windows 程序的 Linux 程序，一定会很高兴的说：”哈哈！Linux 也能……了！”如果Linux在某种测试中胜过Windows，他们会高兴得跳起来。他们没有办法用Linux 解决问题的时候，甚至用Wine来运行Windows程序。有时实在没办法，只好重起到Windows，或者干脆省得麻烦，在 Windows 下装一个 VMWare 虚拟一个 Linux 玩。</em></p>
<p>你如果出现了上面的情况，说明你的思想受到了 Windows 的某种潜移默化的影响和误导。你没有能够从本质上理解存在于 Linux 身上的 UNIX 思想。你支持 Linux，你喜欢 Linux，你能从中感觉到快乐，这非常好。你现在只需要明白的是：Linux 从来就不是一个玩具，它是天才UNIX的后代。UNIX 是自晶体管发明以来最伟大的发明，它从诞生那一天开始就比 Windows 的设计出色。</p>
<p>你要体会什么叫做”设计”，一个糟糕的设计并不是到后来缝缝补补就可以变好的，而一个出色的设计，不但可以以不变应万变，而且可以影响到后来者。一个出色的设计配上一个出色的实现，那就是非常出色的发明。Linux 就是这样的一个出色的发明。<em>Linux 并不需要追赶 Windows，也不需要打垮微软。它的最终目标是改变整个计算机世界，还人们自由，给人们乐趣和方便。</em></p>
<p>Unix 是简单的，你不需要成为一个天才也能理解这种简单。</p>
<p>UNIX 的设计者 Dennis Ritchie 说：”Unix is simple. It just takes a genius to understand its simplicity.” 但是我不这么认为，因为我不是一个天才，但是我却勇敢的把 Windows 完全删除掉，遇到不明白的事情的时候努力用 UNIX 的方式去解决，而不是寻求 Windows 的帮助。现在我体会到了 UNIX 的思想和好处，我可以用比 Windows 高效几倍的效率工作。因为我相信这样的信念：”Windows 能办到的事 Linux 一定能办到，而且办的更好。”</p>
<p>这小节开头的话应该改成：”Unix 是简单的，你不需要成为一个天才或是计算机专家。但是在这个冲斥着 Windows 错误观念的世界，你需要信念和勇气才能理解它的简单。” 我下面就告诉你一些我理解到的东西。首先，你要知道的是微软在国际科学领域是根本没有地位的。</p>
<p><strong>微软的地位</strong></p>
<p>微软的名声在欧洲和美国的大学里，特别是在计算机系里之坏，大家可能有所耳闻。我认识的 <acronym title="Massachusetts Institute of Technology">MIT</acronym>，Stanford 的教授，贝尔实验室的专家，甚至一个欧洲小国的高中计算机老师都绝口不提微软的名字。在他们眼里，微软只是一个没有真技术，专靠在落后国家商业宣传和垄断经营的小公司。这个”小”并不是说它人少，钱少，而是说它先进技术少。</p>
<p>我上次和王益合作写了一个算法演示程序，那个算法是贝尔实验室一位科学家Steven Fortune很天才的发明，为了程序能够被身边大多数人使用，我们选择了 VC+MFC 作为平台。我在分析算法时还得到 Fortune 很热情的鼓励，寄给我一份资料，还多次回信耐心的给我讲解了很多细节。但是程序完成之后，我把样品发给 Fortune，他回信说：”对不起。我机器上没有 MFC。” 话说的很客气，但是我已经感觉到了他对 Windows的不屑。然后我把 MFC 静态编译进程序再发给他，他就没有再回信了。他显然不是瞧不起我，而是确实有难处。</p>
<p>你能感觉到这位科学家对微软和 Windows 是什么态度了吧？<em>不是反感，而是他心里根本没有 Windows 这个东西</em>！微软在高科技领域没有发展，那么它怎么生存呢？到发展中国家去发展一下，他们的人民还对电脑一无所知，我说不定甚至可以打入大学的计算机系呢。我送他们软件，我捐钱盖大楼，我出钱找图灵奖获得者来演讲，让他们觉得我们都是科学家！</p>
<p>好了，现在全国的大学包括清华，几乎所有人机器必装盗版 Win2000，Office XP，学校的选课系统是非<acronym title="Internet Explorer">IE</acronym>不能正确浏览，论文用 Word 编辑，演示用ppt做，email 的通知附件是 doc 文件，你不用 Word 打不开，连 863 项目都用 VC 写程序了。我很久以前就看到一份报纸说，”微软为什么不严厉打击盗版？” 这篇文章说，微软非但不打击中国的盗版行为，而且有放任之趋势。放长线吊大鱼，<a href="http://www.cnbeta.com/articles/62988.htm" target="_blank">“以后我要你们加倍的来还我！” </a>确实如此，它的目的快实现了。</p>
<p><strong>Windows 笼罩下的中国计算机教育</strong></p>
<p>说句丢脸的话，比尔盖茨很久以前是我的偶像……</p>
<p>在中国，比尔盖茨被很多人奉为神圣，”少年电脑天才”，甚至有的人提到他的名字就做出”抱拳对天”的姿势。很多人谈到微软的”新技术”，”高科技” 都是眉飞色舞。各种”VC编程圣经”，”深入了解 Visual C++”之类的书，在开头几页都会出现非常肉麻的字眼，”在那团团的混沌中，一个开天辟地的精灵，Windows 1.0，诞生了……”</p>
<p>微软的软件被这么多人盗用，那么人们是怎样使用这些盗版程序的呢？先看看电脑培训班，教的都是一些 DOS 命令，打字，Windows 基本操作，Word 文档处理，PowerPoint，高级班可能有 Excel，Access…… 参加各种微软认证考试，MCSE，MSDE 的人络绎不绝。考试辅导班都贴出了”280元，考过为止”之类的字样。考试参考资料更是昂贵，有些电脑书店整整两书架都是”Microsoft Press”的东西。我有个同学参加认证考试，每门考试都要200多元。而且你一次考不过可以再考，又要交钱。他后来还津津乐道跟我说，看我，花了 XXXX(一个四位数)元考过了微软认证，得到一张比尔盖茨亲笔签名的证书和价值6000元的 Windows XP 内部发行版。</p>
<p>“电脑要从娃娃抓起”，我们再来看看娃娃们学的是什么。大部分家长给孩子买了电脑之后，他们首先就会装一个盗版的 Windows，然后买来盗版的游戏开始玩。如果哪个孩子会用 Delphi 编程序，那可不得了。报社记者，电视台争相报导，说，某某学校的初中生某某，在别人都还在玩电脑游戏这种”初级阶段”的时候就已经用 Delphi 写程序了。镜头还瞄准了他显示器上面的像框中的比尔盖茨头像！</p>
<p>我刚进入大学计算机系时还不懂得什么是操作系统，因为我以前只用过”中华学习机”。看到新入学的同学们各个谈论的都是 “Windows 95&#8243;，”VC”…… 我简直觉得我落后了好几十年一样，整个一土人，根本跟他们答不上话。好不容易找到一个比较熟的同学问了一下：”你们天天谈论的瘟95是什么啊？”答： “win95就是一个操作系统，跟DOS是一类。”"朵死是什么？” “你连DOS都不知道是什么？别在计算机系混了。” 学校上课当然不讲VC编程之类的东西，但是上 Pascal 的老师有一次就说：”嗨，我们学校真是落后。现在别人都用 C, C++，甚至 VC 了，我们还在讲 Pascal。不知道什么时候才能有VC课啊。你们出去也是要用VC的，只好自学了。” 于是，有些同学很多时候上课都捧着一本很重的”Windows 编程大全”之类的书，根本没有听课。吃饭时就念念有词的跟我说，”代码的优化是无止境的”，”匈牙利命名法真是伟大的发明” …… 这就是中国很多大学计算机系的情况。</p>
<p>感觉到无知了？这不是偶然的，而是微软长久以来埋下的伏笔。它要让无知的大家都把它奉为神圣，它要让支持UNIX，Xwindow的人一旦说 UNIX 好，Xwindow 好的时候，都被一群人围着说教：”这个 Windows 也能做到”，”你对 Windows 有偏见”，”微软才是主流啊”，”你敢瞧不起 win2k？”，”.NET 就是世界潮流”，”微软的毕竟是新技术”，”有钱就是有技术”…… 甚至在一番论战比较后败下来还是要说：”Windows 性能差点，但是易用性强”，”Windows 是老百姓用的，要求别那么”，”微软那么有钱，以后想超过 UNIX 还不容易吗？”……</p>
<p><strong>发达国家的计算机教育</strong></p>
<p>我前段时间在 USENET 发文问有关 Scheme 语言的问题时，认识了一位丹麦人。他解决了我所有的问题，并且建议我阅读一些很”深奥”的有关程序语言语法，文法的书，他告诉我很多网站可以学习 LISP，Scheme，人工智能，算法。他叫我看 Jonathan Rees 的论文 “Syntactic Closures”。他还打包给我寄过来一份 <acronym title="Massachusetts Institute of Technology">MIT</acronym> 的 “How to Design Programs”。他说他在自己的 PC 机上装的是 Linux，他用 Emacs 编辑，运行Scheme 程序。他对 Emacs 的了解和爱好真是使人惊讶。他大学本科毕业时做的毕业设计是一个 Scheme 解释器。这对于我来说是望尘末及了。</p>
<p>他是那么的不厌其烦，我的每一个问题他都详细的回答。我有时都觉得过于详细了，怎么这么耐心啊？我觉得他似乎是我的高中老师。他是什么样的人呢？我好奇的打听了他的情况。原来，他是丹麦一所普通高中的计算机老师。</p>
<p>他说他在高中里讲授程序设计和算法，计算机语言文法。他说用 Scheme，他的学生不用再为内存泄漏等程序语言本身的问题而烦恼，而专注于问题和算法本身。有利于培养学生解决问题的能力，特别是用计算机解决数学问题的能力。</p>
<p>天哪！为什么欧洲出现那么多数学家，几何学家？你看看别人重视的是什么！我们的计算机教育如果继续这样下去，只会沿着弯路越走越远！</p>
<p><strong>微软和它的朋友们的如意算盘</strong></p>
<p>下面来看看微软的收入是怎么来的。首先，Windows 98系列操作系统，一个就是 100多美元，每次升级又是几乎同样的价钱。Windows NT 还要贵几倍，而且有用户数目限制，5个用户的，10个用户的…… 以后如果要增加用户数目还要按比例付钱。</p>
<p>花了如此多钱买来的操作系统就能用了吗？它竟然连压缩程序都没有提供！你装上Windows 之后一般第一件事就是去下载一个 WinZip 吧，”只要 29 美元”。Windows会中病毒啊，马上花 70 美元买一个 Norton AntiVirus 吧。还有黑客呢？再买一个Norton Internet Security 好了，100 美元。系统需要优化，磁盘需要整理，买一个Norton System Works 是你最佳的解决方案，100美元。</p>
<p>可是你现在还是不能干正事啊！你想要一个 Word, PowerPoint？那就买一套 Office XP 吧，一起买便宜些，$459.90。</p>
<p>那些程序不会用啊！那些菜单怎么设置，到底有什么功能啊？看”帮助”也学不会。买本书看看吧，我推荐”Special Edition Using Microsoft Office XP”，不贵，$27.99。这本书里面大部分是屏幕抓图，还是买一本旧的比较划算，$17.85。</p>
<p>你如果只是当个秘书，上面的差不多还凑合了。可是你有更高的追求，你想成为 Windows程序员。首先买一个 Visual Studio.NET 吧，要不然怎么编译程序。$494.95。</p>
<p>为了紧跟微软动向，世界潮流，不能不注册个 <acronym title="Microsoft Developer Network">MSDN</acronym> 什么的吧？这个贵一点，不过物有所值啊，$2,799。</p>
<p>嗯，你现在已经是上层阶级，白领人士了。你现在可以像这样”自由”的，”安全”的生活了。</p>
<p><strong>为什么要反对使用 Windows</strong></p>
<p>很多人都说不应该完全否定 Window，Windows 也有它的长处。不应该骂微软。</p>
<p>对。 Windows 容易操作，适合普通用户。如果微软把它自己定位在 P&amp;G，Philips 那样的地位，能够给我们的百姓提供周到的，完善的，价廉物美的服务。那我肯定是很喜欢它的。但是从上面的种种情况说明，微软是一个野心极大的国际垄断组织！它的产品没有一个是不出问题的：Windows 不稳定，容易中病毒，而微软不为大家免费提供杀毒软件。我就是要让你们花钱买我的朋友 Symantec 的杀毒软件，谁叫你们已经上了我的贼船？这叫什么售后服务啊！</p>
<p><em>你买来微软的程序，安装的时候一般都有一个协议，说：” 由于微软的程序造成你的数据损坏或丢失，微软概不负责。” 我想很多人肯定觉得这个不合理，不想按那个 “I accept”。但是你的软件买都买来了，钱都花了，现在一按 “I decline”，安装程序马上就会退出。你只好被迫点击了 “I accept”！这不是不平等条约吗？</em></p>
<p>我已经目睹了好几个朋友的文档被 Microsoft Word 损坏，有的是编辑了十多天的30多页的论文，有的是费了很大工夫做出来的个人简历，那个朋友为此失去了到自己向往的P&amp;G 工作的机会。就在他要投简历的前一个晚上，就在那一瞬间…… 不知道他痛哭的时候有没有想起要投诉微软，可是谁叫我们用的都是盗版呢，况且你还点击了 “I accept”。</p>
<p>微软仗势已经占有大部分PC市场，制定不符合国际标准的”微软的标准”，以不合理的方式压制其它公司的软件，这个问题已经在美国司法部闹了很久了。他甚至在 Windows系列操作系统中放置能够通过网络泄漏用户信息的代码，以至于 Windows 刚进入澳大利亚时被澳大利亚政府禁止使用。</p>
<p>有些人说：”微软毕竟开创了一个历史，造就了今天的 IT 行业。”<em> 但是，如果没有微软，我们今天早就用上非常稳定，非常可靠，非常方便，非常”傻瓜”的软件了！微软是阻挡信息技术发展的罪魁祸首。</em></p>
<p>微软的程序的工作方式(注意，我只是说操作方式，病毒的事情另外算)确实适合于一般家庭，上上网，发发邮件，打打游戏都不错。可是微软却要把自己包装成什么 “高科技”企业，要在世界各地设置”研究院”，在大学计算机系赠送不适合用于科研的 Windows产品，甚至出钱请图灵奖得主来中国畅谈”二十一世纪的计算”，还在大会上宣传自己的 .NET 技术。非要把别人认为自己是科学的，自己是领导世界高科技的。但是呢？它什么高科技也没有。欧洲，美国，哪一个关键部门在用微软的东西？NASA? DOE? CERN?你仔细想一想，微软的程序对人类到底有什么重大作用？</p>
<p><strong>什么是 Windows 能干而 Linux 干不了的事情？&#8212;</strong><br />
“Windows 能干而 Linux 干不了的事情，那就是不需要干的事情。”</p>
<p><em>有个朋友看我半年没有用 Windows，有时就会问我：”你只用 Linux，有没有发现有些Windows 能处理的事情 Linux 干不了？”&#8212;<br />
我回答说：”Windows 能干而 Linux 干不了的事情，那就是不需要干的事情。”</em></p>
<p><strong>Windows 能做的有益的事情 Linux 都能做&#8212;</strong><br />
Windows 下的某些功能确实是我们需要的，那么 Linux 的开发者们和用户也需要这种功能，他们就会去实现这种功能，而且比 Windows 的方式好得多。由于大多数科学家，工程师用的都是 Linux 或者某种商业 UNIX, 所以几乎所有商业的科学工程程序，比如Matlab, Mathematica, AutoCAD, Candence的，Synopsys的，Avant! 的……全都是先有UNIX 的版本(包括Linux)，然后再考虑移植给 Windows，甚至根本不移植给Windows，因为 Windows 的机器一般没有足够的能力运行这样的程序。你不要以为只有 Windows 才有 PSpice, UNIX 的 HSpice 要好得多，而且可以运行在大型主机上。当然它们不是免费的，但是它们值那个价钱。</p>
<p>但是 Windows 下有些东西在 Linux 下没有很相似的，或者你找到很多类似的，但是它们每一个比起 Windows 的那个程序都要差很多，那么原因有两种可能性：</p>
<p>有一个完全类似的程序，但是由于它乍一看不漂亮，被你忽略了。而其它程序虽然看起来很漂亮，但是它们是一些初学编程的人写的。现在由于 Gtk, Qt 的诞生，Linux 下开发图形界面程序极其简单，很多初中生甚至小学生都可以随手编出一些漂亮不中用的程序。如果你整天寻找这样的程序挑来挑去，永远也找不到你满意的。当然也有一流的程序用 Gtk 和 Qt，比如 GVIM 就可以用 Gtk 作为图形界面，我还知道 Synopsys 一些程序用了 Qt。</p>
<p>我曾经也犯过这样的错误，从外表区分一切。结果优秀的 FVWM, lftp, Mutt, wget 都被我忽略过。当我找回它们的时候，我是那么的羞愧不已，它们现在都是我的朋友 我第一次看到 FVWM 觉得它只不过是一个有很厚很难看边框的东西。可是现在，我的同学看到 FVWM 都说：”哇！真漂亮。”</p>
<p>有另一种完全不同的方式可以达到相同的目的，甚至更好。</p>
<p>很多人很关心 Open Office, Star Office, AbiWord, &#8230; 他们多么盼望有一天某一个Linux 程序能够完全兼容的打开一个复杂的 doc 文档。但是你永远也不可能有那一天。为什么呢？因为微软为了占有市场，必定不会让其它系统的程序能够完全兼容它的文档格式。它一定会不断变化 doc 文档的内部结构，隐藏一些秘密，让其它公司的程序打开 doc 文档时总是有某种问题，从而你必需购买 Microsoft Office 和 Windows。</p>
<p><em>你应该想一下，那么多的高智商的大学教授，科学家，学生，他们用的都是 Linux 或者其它类型的 UNIX，他们没有 Word 可用，怎么处理文档呢？这么多年没有一个像Open Office 的程序出现，难道大家没有办法写文档吗？</em></p>
<p>显然不是这样。你看看那些高水平的学术杂志，论文，那些大学教授的网页，那些漂亮的幻灯片，它们是什么做的？原来 UNIX 用户早就有非常方便的 troff, LaTeX, <acronym title="Standard General Markup Language">SGML</acronym>等东西可以处理文档，而且它们比起 Word 都要高明的多。Word 显然被这些大拿忽略了，以至于很久以来没有人想在 Linux 下开发一个类似 Word 的程序，除非某些公司想抢微软的饭碗。</p>
<p>很多人留着 Windows 在硬盘上的原因无非是为了用 Word 和 PowerPoint。我见过一个教授，他的 Windows 笔记本电脑上除了 PowerPoint 什么都没有。有一天演示的时候，他指着堆乱字符说：”对不起，这是一个公式……怎么每次都是这样……” 其实有比PowerPoint 好几百倍的东西可以制造幻灯片，你可以用最简单的方法制造世界一流效果的论文和幻灯片。你待会儿可以看看我的TeX网页，你就会知道为什么我可以完全离开 Windows。</p>
<p><strong>Windows 能做的那些没用的事情 Linux 永远做不好</strong></p>
<p><strong>电脑游戏</strong><br />
有些人说 Linux 下不能玩 Windows 下所能得到的所有游戏。的确，Linux 下虽然也有少量的游戏，比如 Quake。但是它没有 Counter Strike, 没有 Star Craft, ……</p>
<p>并不是说电脑游戏不该玩，但是应该适可而止。电脑是用来处理事务，帮助你学习，解决问题的工具，而不是一个玩具！整天沉迷于电脑游戏中，而不出去感觉外面的世界，你会变得越来越冷酷，越来越缺乏人情味。你与真实的世界越来越远。</p>
<p>你可以在 CS 里杀人，你可以在 Tomb Raider 里探险，你甚至可以在 Tony Hawk&#8217;s Pro Skaters 里滑板…… 但是 It&#8217;s not real！你虽然有很高的”反恐技巧”，但是遇到歹徒的时候，你是那么的怯懦；你虽然控制 Laura 伸手敏捷，但是你打篮球的时候怎么总是被人断球？你虽然可以轻易的在 THPS 里作出一个 “360 kickflip to hangten grind to fakie”，但是你踩在自己的滑板上的时候还不会 ollie！</p>
<p>说回来，如果你偶尔玩一下电脑游戏未尝不可。但是世界上有远比 Windows + PC 更好的游戏方式。Sony 的 PlayStation2, SEGA 的 DreamCast, Nintendo 的 N64，Namco的街机……每一个都比 Windows 游戏精彩，每一个都有如此高的3D性能，以至于Pentium4, Itanium + GForce4 都无法与它们比美！</p>
<p><em>Linux 的用户们都是关心解决世界的关键问题的份子，他们哪里有时间用自己的机器来玩游戏啊？他们每天用Linux高效的做完自己的工作就到阳光下享受自然去了。要玩游戏也是玩一些类似推箱子，贪吃蛇之类的智力小游戏。所以，你知道为什么 Linux 几乎没有游戏了吧？</em><br />
<strong><br />
“整理硬盘，优化系统”<br />
</strong><br />
这是一个非常有意思的话题，仅次于有关”病毒”的话题。相信很多 Windows 用户都有整理硬盘的经历。在很多 Windows 用户眼里，”硬盘用久了，会出现碎片，速度会减慢，需要一个程序来整理，整理硬盘的时候不要做其它工作”，这好像是天经地义的事情。</p>
<p>我也曾经津津有味的看着 Norton Defrag 一点一点的把我的硬盘排序，调整，用图形的方式显示出来，然后报告100% 没有碎片。你的硬盘现在已经达到最佳状态。” 我现在才发觉我那时是多么的幼稚。</p>
<p>Linux 和 UNIX 用户似乎从来没有”整理硬盘”这种说法呢？你觉得很奇怪吗？如果你觉得很奇怪，那说明你的思想在某种程度上被微软的垃圾程序禁锢了。你需要明白，UNIX 的大型主机很多必须是一天24小时，一年365又1/4天不停运转的，要是每个星期都要整理一次硬盘，在整理的时候几乎不能干任何事情，那是绝对行不通的！</p>
<p>Linux 机器根本不用整理硬盘，这就是为什么没有看到过 Linux 用户整理硬盘。Linux 的文件系统是比 Windows 的 FAT, FAT32, NTFS 高明得多的文件系统，它们不但可以对文件设置权限，实施完全的保护，而且可以”越用越整齐”，”越用碎片越少”！你应该把文件大部分放在 Linux 的分区，而不是 Windows 分区，因为它比 Windows分区可靠得多。<br />
<em><br />
还有更滑稽的事情就是有很多”Norton System Doctor”，”Windows 优化大师”，”超级兔仔注册表魔法” 之类的程序存在，而且价格昂贵。似乎一个操作系统本来应该有很多问题，需要别的厂商做程序来”优化”它，而且为了得到优化，你需要付钱！这些问题 Linux 根本就没有，所以不需要什么优化。Linux 内核本身就是高度优化的。</em></p>
<p><strong>IDE</strong></p>
<p>有些人在抱怨为什么 Linux 没有一个良好的 IDE 开发环境。Linux 现在已经有一些IDE 了，但是总是有很多问题。你是不是正在寻找，正在期望 Linux 某一天可以有一个VC那样的开发环境？你有没有发现你正在进入微软给你设下的怪圈？你为什么一定要用 IDE？你说：”IDE 开发迅速，调试方便，适合大型程序……” 那说明微软的程序在你脑子里已经比较根深蒂固，你需要好好清醒一下了，看看我来告诉你。</p>
<p><em>高明的 UNIX 程序员不用 IDE，IDE 从来就是给初级 Windows 程序员用的。</em></p>
<p>你看看大型的 UNIX 程序，包括 Linux 内核，各种网络服务程序，Xwindow 程序在内，哪一个是 IDE 搞出来的？我们实验室的 EDA 程序也没有一个是 IDE 弄的，我还知道Candence, Synopsys，Mentor 的高性能的图形界面 EDA 程序也都不是 IDE 写的。你信不信，微软的人在写 Windows 本身的时候也根本不用 IDE。微软内部程序员最喜欢的编辑器其实是 VIM，用 VIM 的微软程序员上次向乌干达的可怜儿童捐助了1000多美元，这是值得称赞的。</p>
<p>有一次某杂志采访一些出名的 Linux 内核程序员，包括 Linus 在内，没有一个人用IDE，有的人用 VIM，有的用 Emacs，只有 Linus 说”GNU Emacs is evil”，但是其实他用的是一种跟 Emacs 有同样键绑定功能的 MicroEmacs。大家都是用编辑器编辑了程序文件，然后用 make 这样的自动工具调用 gcc 编译器完成编译工作的。甚至高级的 Windows 程序员也不用 IDE，他们可以从命令行调用 cl，nmake 来编译自己的程序。虽然这样的 Windows 程序员很少，但是他们却是最了解 Windows，最高明的Windows 程序员。</p>
<p>为什么 UNIX 程序员不用 IDE？明白了这个道理你就能体会到 UNIX 的设计思想了。首先，一个 IDE 集成了编辑器，编译器，汇编器，调试器，跟踪器…… 这个编辑器功能肯定比不上 VIM 或 Emacs，编译器比不上 GCC，汇编器比不上 as，调试器比不上 gdb，ddd, 跟踪器比不上 strace, ltrace, truss。你得到的是一套整合的低能的程序。如果你对调试器的功能不满意，你只好换用另外一套 IDE，但是这套 IDE 的热键，菜单，编辑器功能，按钮…… 跟原来那个有很大不同。你不得不花很多时间来熟悉新的环境，而不能保持原来的某些东西。</p>
<p>而在 UNIX 下就不一样了。你可以用你最喜欢的 VIM 编辑程序，你在 VIM 里可以调用GNU make，make 可以调用 gcc, ld, &#8230; make 的出错信息可以被 VIM 捕获，VIM 能帮你在源程序里定位。你如果喜欢 icc, 你可以让 make 用 icc 而不是 gcc。你如果觉得 gdb 跟踪变量时比较麻烦，你可以用 ddd 来显示各种数据结构之间的关系。你还可以在 Emacs 里调用 gdb，那样就可以同步显示源代码了。而且 VIM 和 Emacs 还可以编辑很多其它东西，比如信件，LaTeX 文档，<acronym title="HyperText Markup Language">HTML</acronym>，配置文件…… 你不用另外找一个什么编辑器来干这些杂活了。很多程序比如 Mutt, tin 都可以在内部使用 VIM，这样就更方便了。实际上 make 在其它方面还能帮你很多忙，我的每一个比较大型的 LaTeX文档都是用 make 维护的。</p>
<p><strong>Linux 能干的高精尖的事情 Windows 都干不了</strong></p>
<p>当然有很多事情是Linux/UNIX的专利了。因为 Windows 只能装在 PC 机上，好像以前也有 Alpha 可以使用 Windows NT，但是就是没见到有人用。PC 机的能力是很低的，像我们编程序处理 NP-Hard 问题的人，用 Windows 的机器显然速度不够，而且有时一个问题算上几天甚至几个星期，Windows 机器是以”死机”著称的，我们怎么能放心？所以几乎所有科学计算程序，EDA 程序，高性能图像处理程序都不是 Windows 的。他们有时也会移植一些给 Windows，但是常常降低那些程序的能力。你比较过 Windows 版本的 Mathematica 和 Linux 的有什么区别吗？</p>
<p>IBM 制造的最大的并行计算机有 8000 多个处理器，Windows 不可能有能力管理这么多处理器，它用的是什么操作系统？答案是 Linux。</p>
<p>《泰坦尼克号》电影里的三维动画，那么细腻逼真，Windows机器能做出来吗？不行。那也是 Linux 机器做的。</p>
<p>民航总局用来训练地情人员的虚拟现实训练设备，Windows 当然无能为力。那都是商业的 IRIX 机器。</p>
<p>UNIX 是最早支持 TCP/<acronym title="Internet Protocol">IP</acronym> 网络协议的系统。它上面有很多可以互相协作的网络服务程序，它们经过多年的使用和修订，已经达到比较完善的程度。而就在1997年，微软的比尔盖茨还在扬言：”Internet 是没有前途的。” 微软的这个”远见卓识”大家应该都已见识，它后来加上的网络服务程序<acronym title="Internet Information Services">IIS</acronym>漏洞之多，让公安部都频频发出警报，大家也是见识了的。</p>
<p><em>其实你知道了，Windows 没有一样有用的事情能比 UNIX 干的更好。</em></p>
<p><strong>Linux 干不了的有用的事情 Windows 照样干不了</strong><br />
当然 Linux 不是万能的。它也有不能干的事情，电脑也有干不了的事情。但是 Linux干不了的事情，Windows 肯定也干不了。这些事情就是我们需要探索，需要努力的事情了。在你探索的过程中，Linux 必定是你的好伙伴。</p>
<p>不要把Linux和Xwindow掩盖起来！不要把我们的用户当成傻瓜。</p>
<p>什么？你早就知道 Windows 是垃圾？噢！你怎么不早说呢！害我废话这么多。嘿嘿。</p>
<p><strong>“好了。你知道 Windows 是垃圾，你现在用什么”</strong></p>
<p>“Linux + Xwindow”</p>
<p>“那我问你，Xwindow 是什么样的？”</p>
<p>“不就是跟 Windows 差不多吗？只不过 &#8216;Start&#8217; 按钮比较方，而且上面不是一个Windows 标志，而是一个脚丫子。点击一下居然还有很漂亮的中文菜单。我喜欢！”</p>
<p>“你知道什么是&#8217;根窗口&#8217;吗？”</p>
<p>“不知道。从来没听说过呢？”</p>
<p>“根窗口就是遮盖整个屏幕的那个最大的窗口。”</p>
<p>“哪儿有什么窗口啊！我没有看到呢？”</p>
<p>你发现了问题吗？这些 Linux 用户说是在用 Linux 和 Xwindow，但是他们对 Linux和 Xwindow 几乎完全不了解。很多人用了那么久 Xwindow 都不知道根窗口是什么东西，不知道其实按钮也是窗口，不知道窗口管理器和其它程序有什么关系，大家都以为窗口上面的按钮是程序自己放上去的，不知道窗口? quot;class name”，”resource name”是什么东西。他们也不知道 .Xdefaults 是用来干什么的。特别是他们很多人都不知道 Xwindow 的字体是如何命名的，什么是 fontset，有了一个新的字体也不知道怎么安装。</p>
<p>他们被遮在 Linux 之上的一层一层的包装迷惑了，他们等待有图形界面的工具来帮助完成一切事情，他们认为 Linux 跟 Windows 一样，只是麻烦一点。他们知道 Linux内核很好，但是他们感觉不到 Linux 和 Xwindow 在操作层面的天生的先进性，随后不久就把 Linux 完全删除掉了。你发现没有，要用户理解 UNIX 和 Xwindow 的操作层面的先进性，才是留住用户的最好办法。如果用户体会不到操作时的方便和高效，内核再好他们也不会理会。</p>
<p>但是用摹仿 Windows 的作法来吸引用户，永远会失败的。因为 Linux 如果摹仿Windows那一套低效率的方式，那么 Linux 的这套”低效率方式”永远比不上Windows 的那一套”低效率方式”。那么用户就会说：”这个 Linux，没有一样比的上 Windows。”</p>
<p>Linux 天生就是继承了 UNIX 的高效的工作方式，为什么我们要把它掩盖起来？我们为什么只告诉用户 KDE 的菜单怎么用？我们为什么不能像早期的 Xwindow 书籍那样第一节就告诉用户什么是 X server, 什么是 X client，什么是 Window Manager, 什么是根窗口。第二章就告诉用户窗口有哪些属性，什么是 classname, resource name, hint，怎样使用 .Xdefaults, xrdb ……</p>
<p>在这里我又不得不说一下那些 Linux 的发行公司和写书的人，他们把 Linux 和Xwindow 包装起来，却没有从基本上告诉用户 Xwindow 的工作原理。很多书籍讲授的层次就是在Gnome, KDE 的菜单操作的层次，靠大量抓图来占篇幅，”繁荣”Linux 书籍市场。</p>
<p>现在很多人已经把能够利用别人的库写出一个好看的程序作为自己编程水平的象征。在这”图形化”，”可视化” 的年代，你如果还在用 troff, LaTeX 写文档，你还在用VIM 自己编辑 <acronym title="HyperText Markup Language">HTML</acronym>，用 Mutt 处理邮件，你还在用文本模式的 gdb 调试程序，你还在用Xlib 写程序, 你还在用 tin 上 USENET，你还在自己写 Makefile，写机器代码，你还在玩 Clossal Cave 这样的字符模式冒险游戏，那你就是老古董。</p>
<p>其实这种思想是错误的。虽然你是一个坚决的 Linux 支持者，但是你的思想是 Windows的思想。你认为图形界面，菜单，按钮就可以解决一切问题，就可以给你高效方便。你还是没能摆脱微软给你的潜移默化的东西。你其实离不开 Windows 那样的环境，你迟早会删掉自己的 Linux。</p>
<p><strong><acronym title="Graphical User Interface">GUI</acronym> vs. CLI</strong><br />
做一个坚定不移的”两面派”</p>
<p>大家看到这个标题是不是热血沸腾？两派大虾都可以围攻我了：</p>
<p><acronym title="Graphical User Interface">GUI</acronym>派用户：”哇！我一看你这小子就是 CLI 的。要不然自己写什么 Makefile？用什么Mutt？”</p>
<p>CLI派用户：”切～ 你还用 X！高手都不用 X。你是 <acronym title="Graphical User Interface">GUI</acronym> 那边的。”</p>
<p>可怜的我：”555～～ 你们都不要我～～ <acronym title="Graphical User Interface">GUI</acronym> 和 CLI 就那么水火不容吗？”</p>
<p>计算机界这样的门派之分还很多。很有特点的就是 CLI 和 <acronym title="Graphical User Interface">GUI</acronym> 了。CLI (Command LIne)的狂热份子声称永远不用 X。我上次在实验室看到一个同学用一个 SecureCRT 登录到Sun 机器，然后用一个 vanilla vi 编辑程序，我建议他启动一个 GVIM 过来显示在Exceed 上可以有语法加亮。但是他坚决反对，说：”高手不用X。你想想，要是我在一个很慢的网络连接怎么用 X？而且好多服务器没有装 X 程序。”</p>
<p>但是我们实验室的网速可够快，Windows 机器都有 Exceed 啊，而且 Sun 机器有全套X 客户程序包括 GVIM。他说他是 CLI 的坚决拥护者，但是他却在用 Windows，他后来打开了好几个 SecureCRT，每次从文本框输入地址，用户名和密码，从下拉菜单选择”SSH2&#8243;，然后点击”Connnect”。他还不断的夸SecureCRT 是”网络管理员投票选出的最受欢迎的登录方式”。老天，SecureCRT 本身就是个 <acronym title="Graphical User Interface">GUI</acronym> 啊，他其实没有明白Xwindow 的好处。</p>
<p>你说我是 <acronym title="Graphical User Interface">GUI</acronym> 的？我虽然很少在 console 下工作。但是我对 bash, VIM 很熟悉，我可以让 bash 按照我的键绑定方式来工作。我可以在 rxvt 里使用 Mutt 来收发 email。我的每个桌面上都常常堆放着一打不同大小的 rxvt。我用 VIM 编辑 LaTeX。我自己写Makefile 来维护 LaTeX 文档。我有时用 mpg321 来放 mp3。我上BBS用的我自己写的expect 脚本。 好了，CLI 派的朋友可以收我做盟友了</p>
<p>你说我是 CLI 的老古董？我的 FVWM 被我配置为可以”手写操作”，我只要画一个”r”就可以启动 rxvt，我只要画一个 “U” 就可以启动 GVIM，…… 我用 GVIM 语法加亮模式编辑程序，我用 Mozilla 浏览网页，…… <acronym title="Graphical User Interface">GUI</acronym> 派的现在好像认我做朋友了</p>
<p>好了。CLI 派的朋友，虽然我很喜欢命令行，但是我有时在屏幕上左右画一下就可以执行:</p>
<p>Module FvwmConsole -terminal rxvt -geometry 45&#215;5-0+0 -bg gold -fg midnightblue -fn “-adobe-courier-medium-r-*-*-14-*-*-*-*-*-*-*”<br />
你是不是现在又想把我逐出师门？</p>
<p><acronym title="Graphical User Interface">GUI</acronym> 派的朋友，虽然我很喜欢窗口。但是我可以在 FvwmConsole 里输入：</p>
<p>All (rxvt) MoveToDesk<br />
把我所有的 rxvt 移动到我现在工作的桌面。”这家伙，怎么这么快就叛变了！”</p>
<p>其实何必分什么 <acronym title="Graphical User Interface">GUI</acronym> 和 CLI，UNIX 和 Xwindow 都是工业标准，它们从设计那天开始就有非常灵活的用法，各个程序，不管是 <acronym title="Graphical User Interface">GUI</acronym> 还是命令行的都可以互相协作。UNIX 和X 是一家，何必搞的那么偏激，非此即彼？你从我上面的行为可以看出 <acronym title="Graphical User Interface">GUI</acronym> 和 CLI的模糊界线吗？我就是坚定不移的”两面派”。</p>
<p><strong>UNIX 是简单的&#8211;</strong><br />
“我相信简单就是最好，如果太复杂，我是不能理解的。” -Seymour Cray</p>
<p><em>很多第一次用 Linux 的人会惊奇的发现，Linux 的程序居然不”安装”就可以运行，程序拷贝到随便那个目录都可以用，而不是一定要占用你第一个分区的空间。程序的设置只是一些简简单单的文本文件。你根本不需要什么”注册表修改器” 就可以改变系统的设置。这就叫做简单，但是简单就是美。虽然这只是 UNIX 简单性的一个肤浅的认识，你已经体会到了某些东西。</em></p>
<p>但是简单并不意味着功能弱，并不意味着落后。相反，简单意味着强大，意味着生命力。</p>
<p>我不会再继续阐述我理解到的”UNIX 的简单”，因为这个需要自己去体会。</p>
<p><strong>UNIX 是永恒的</strong><br />
有人说：”Plan9 会取代 UNIX，Mach 会取代 Linux 内核。”</p>
<p>但是你如果是一个深入体会了 UNIX 的人，你就会知道：UNIX 的思想是永恒的，不管时过境迁，Plan9 是否代替 UNIX，UNIX 的灵魂都会在 Plan9 身上现形！</p>
<p>我为同一个设备写过 Linux 内核和 Windows VxD 驱动程序。写 Linux 驱动程序时，我对 UNIX 设计的完美的一致性，远见性所折服。UNIX 用同样界面的 read(), write()系统调用就可以对不同的对象：普通文件，设备文件，管道，管道文件，socket，……进行统一的读写操作。我跟本不需要写一个测试用的应用程序就可以对我的设备驱动进行测试，因为 cat, cp, dd, 它们也使用了同样的 read(), write()，设备和普通文件在应用程序眼里没有区别。在那个还没有 Smalltalk, 没有 C++ 的年代，UNIX 的设计者已经使用了所谓的 “面向对象方法”。对，C 语言也可以实现面向对象。</p>
<p>UNIX的系统调用几十年都没有很大变化，这非但不是顽固，不进步的象征，反而是UNIX 的远见卓识的体现！这就跟 TeX程序几十年都不变的情况差不多。这些才是真正的永恒的 master piece!你应该改变所有软件都必需从 0.1, 1.0, 1.1, 1.2, 2.0, &#8230;, 3.0, 3.1,95, 98, 2000, XP, &#8230; 不断升级的想法。</p>
<p><em>Windows 就不同了，它在最开头只是一个 DOS之上的图形包装而已。后来为了兼容以前的糟糕设计，不得不加上很多累赘。我写VxD 驱动程序的时候就深有体会，Windows 95 程序对设备的操作只有用DeviceIoControl，我不得不写了两个应用程序来对设备驱动进行测试。Windows内核的不一致性和隐密性使我非常恼火。不过 Windows WDM驱动程序现在也有了 ReadFile, WriteFile，…… 那说明什么？那说明Windows 在向 UNIX 学习，或者有可能是某个 UNIX设计人员在微软打了几天临工，顺手加了几个UNIX的东西进去。这样做是没有用的，Windows从一开始就是非常糟糕的设计，它的历史的包袱太沉重了，缝缝补补有什么用？它只能永远的被UNIX 甩在身后！</em></p>
<p><strong>UNIX 是强大的</strong><br />
让聪明人干任何他们想干的事情。</p>
<p>UNIX 的一个特点就是非常高的灵活性，Xwindow也具有这种灵活性。这种灵活性体现在哪里呢？</p>
<p>UNIX 的程序一般都有很多参数，不管你现在用的着用不着，总有人需要某些参数。它们的行为很多都可以用配置文件来改变。比如GNU bash, 通常缺省的命令行输入方式是 Emacs 方式，但是只要我编辑一个.inputrc 文件，就可以把它变成 vi的输入方式，而且我还可以自己绑定键序列到某些操作。我可以用 shopt来设置它的很多特点，比如是否进行通配符扩展，是否可以把一个变量当作一个目录来cd，是否可以自动纠正某些明显的目录名打字错误……</p>
<p>UNIX程序设计的思想是提供给用户“机制”，而不限制用户制定“政策”。这是一个重要的尊重用户的作法。</p>
<p>我们再来看看 Xwindow。Xwindow是一个出色的设计，它把显示服务器和客户程序分开。一个显示上既可以显示本机上的程序，也可以显示别的机器上的X程序，而它们都遵守你的窗口管理器的统一指挥，它们之间可以方便的传送剪贴版数据，各种事件…… 比如有时我的 XFree86 上会出现四个不同机器上的XTerm，两个不同机器上的 GVIM，…… 它们统一受本机上的 FVWM指挥。</p>
<p>Xwindow 程序都具有很多很多命令行参数和 resource参数。你可以随意的在命令行或者 .Xdefaults文件设置所有的颜色，字体，尺寸…… 而且如果你用 xrdb 把 .Xdefaults导入到根窗口，那么其它机器上没有经过配置的同样的程序，显示到你的机器上的时候也会遵守同样的外观规定。</p>
<p>Xwindow 的窗口具有 Property,也就是一些可以自己定义的共享数据(原子)。正是因为这些 Property的存在，使得 Xwindow 具有无比强大的生命力。X的窗口管理器和其它客户程序之间并没有统一的协议，但是后来出现了ICCCM(客户程序间通信规范)，这个规范就是通过 property定义的。现在又有人定义了一套“扩展的窗口协议(EWM Hints)”，使得Xwindow 可以具有某些 Windows 的特征，比如一个工具条程序可以告<br />
诉窗口管理器：“这个屏幕下面被我占据了24个像素的空间，你最大化程序的时候不要越过这个界线。”</p>
<p>一个强大的窗口管理程序比如FVWM，它收到这样的提示时，可以答应工具条程序的这个要求，也可以不答应。一切选择的权力在于谁？当然是用户了！</p>
<p>你想想，是不是有些 Windows 程序常常弹出一个窗口要你选择 “Yes orNo”？你不点击它它就不下去。你觉不觉得你的程序在侵犯你的尊严？你是一个人，一个智慧的生物，怎能受到一个程序如此的待遇？</p>
<p>还有就是很多 Windows程序把人当成傻瓜，而它是“智能程序”。比如，有一个程序就是喜欢把你的每句话第一个字母都变成大写，我不说它是谁了，你遇到的时候就知道了。</p>
<p><em>如果连“一句话开头一个字母要大写”这么明显的问题都需要程序帮你纠正的话，人脑还用来干什么？况且如果你故意想要不大写的话，那就更麻烦了，我楞是没有从它那一大堆菜单里找到怎么关闭这个愚蠢的选项。</em></p>
<p><strong>只有符号才能完全操纵计算机</strong><br />
<em><br />
我们来说说很多初学 Linux 的用户。虽然他们在用 Linux，但是他们打心眼儿里是觉得 Windows 的工作方式好，他们希望 Linux 有一天能”像Windows那样”。你说：”我鼠标一点，我菜单一拉，&#8230;&#8230; 就可以完成我的操作。” 但是我要告诉你：”Linux 从来没有摹仿 Windows，将来也不会。Linux 从诞生之日起，它的工作方式就比 Windows 的先进。Linux 属于能勇敢面对符号的人。只有符号才能完全操纵计算机。”</em></p>
<p>看看优秀的 UNIX 程序，XFree86, FVWM, VIM, Emacs, proftpd, Mutt, wget,tin, &#8230; 没有一个不是用配置文件来设置选项的。为什么这些程序没有方便的菜单可以用来配置?难道它们的设计者就那么低能，连个图形配置界面也写不出来?</p>
<p>当然不是。因为图形界面配置方式的能力是极其有限的，而配置文件和程序语言的表达能力却是无限的。用图形界面配置这些程序的话，如果你想达到配 置文件的效果，你需要成百上千的菜单，checkbox, radio button, &#8230; 到时候你根本没办法找到你需要修改的地方了!而各个程序的配置文件的语法都有很多相似之处，一般就是一些命令，设置一些变量，参数，&#8230;&#8230; 一旦用会了一个，其它的也就容易理解了。如果你用惯了 awk, sed, <acronym title="Practical Extraction and Report Language">Perl</acronym>，你会觉得那才是真正的自动化啊。</p>
<p>鼠标虽然是很好的工具，但是它的表达能力是有限的。你不可能光用鼠标就让电脑完全明白你的意思，它毕竟只有3个按钮。看看我的MetaPost页你就能体会到鼠标的这一弱点。所以我们虽然很喜欢鼠标，但是却不能完全依赖它。</p>
<p><strong>各个小程序的完美配合</strong></p>
<p>这就是UNIX最重要的特点了，它就是UNIX设计的思想。让每个程序只具有一项专门的能力，然后让它们合作。Xwindow也继承了这种好传统。</p>
<p>这恐怕就是Windows和其它操作系统望尘莫及的地方了。UNIX 程序设计之统一，配合之完美，真使我难以置信!shell, grep, find, awk, sed, make, <acronym title="Practical Extraction and Report Language">Perl</acronym>,Emacs, vi, tin, Mutt, &#8230; 它们是那么的具有一致性!你一旦学会了 sed 的正则表达式，其它程序基本上都能用了。你一旦学会了 vi 和 VIM, 你会发现它的操作是那么的有规律性，似乎vi的设计者在几十年前就已经设计好了 VIM 在今天的完美而统一的操作方式!而且vi的操作还体现在 Mutt, tin 等很多程序中。你甚至可以把 bash 设置为 vi 的输入方式来输入命令行，我就是这么做的。一个程序可以调用另外一个程序来得到数据，可以把数据交给它处理后返回来，可以在自己的窗口里”嵌入”另外一个程序。</p>
<p>在 Windows 和其它非 UNIX 操作系统中，这种合作是非常困难的。我曾经在Windows 下使用 <acronym title="Practical Extraction and Report Language">Perl</acronym>来进行一些自动工作。但是 Windows 的文件操作，管道是如此的不稳定，程序之间基本不能合作。你别想在 Visual Studio 窗口里面嵌入UltraEdit 编辑器，你别想用一个 expect 脚本来控制 telnet 到水木清华BBS，这就是为什么 helloooo 诞生在 Linux 而不是 Windows。我曾经试图从Windows + Exceed + SecureCRT ssh 登录到 Sun 机器，然后通过 ssh 的隧道(X11 tunnel)把 X 程序传到 Exceed 上运行，但是搞了两天都没有成功!而在Linux 下这个事情根本就是不用怎么配置的，OpenSSH 和 XFree86 本来就是完美结合，只要打开 ssh 的 “forward X11&#8243; 选项就什么都搞定了。</p>
<p>Windows 的程序都是大而全，大而杂，所有的电子邮件程序都需要自己提供编辑器，自己发送和收取邮件，自己显示邮件的附件。每一个BBS程序都提供自己的 Virtual Terminal, 自己的通讯代码。每一个 IDE 都自己提供编辑器，编译器，汇编器，调试器。人们为了使用一种新的程序，需要适应所有这些它提供的界面，而不能使用自己喜欢的编辑器的键绑定，菜单组织&#8230;&#8230; 不能 DIY!</p>
<p>你要知道，最高级的电脑是定做的，自己想要什么什么CPU，什么主板，多少内存，什么硬盘，键盘，鼠标，显示器都是自己选择的。最高级的滑板，自己想要什么牌子的版面，什么牌子的沙，什么桥，什么轮子，什么轴承，也都是自己选的。最高级的乒乓球拍，木板，胶皮，海绵，胶水都是可以自己选择&#8230;&#8230; 而用Windows 程序，你得到的是大杂烩，就像你去买”品牌机”，只有那么几种配置，而且附带很多你不需要的软件和服务;就像你去买组装好的滑板，你想要大一点的轮子和窄一点的板子，但是你没有这种选择余地!Windo ws 程序就相当于最廉价，最次的滑板。但是它却会花你更多的钱，因为一旦一个部件坏了，或者你不喜欢了，你不能另外找一个好的换掉它，你必需重新买全套配件!</p>
<p>而 UNIX 和 Xwindow 就是高档的”组装货”。比如我用 Mutt 的时候，我可以用VIM 也可以用 pico 来编辑邮件，我可以用 ImageMagick 也可以用 xv 来显示附件里的图片，我可以用 lynx 把 <acronym title="HyperText Markup Language">HTML</acronym> 附件转成文本嵌入窗口中，我也可以把<acronym title="HyperText Markup Language">HTML</acronym> 附件交给 Mozilla 图形显示。我可以让 GnuPG 帮我把邮件进行数字签名和加密，我也可以用其它 PGP 程序。我想让 Postfix 而不是 sendmail 帮我发出邮件，我想让 fetchmail 帮我收邮件，转发给 postfix，然后被我自己写的<acronym title="Practical Extraction and Report Language">Perl</acronym>过滤器处理&#8230;&#8230; 这一切我都可以办到!我可以选择我最喜欢的专门的程序来完成专门的工作，然后把它们结合在一起，我也可以分别得到它们的好处。</p>
<p><strong>结论</strong></p>
<p>我写这么多的目的是什么?<em>我希望喜欢 Linux 的朋友，完全清除微软和Windows 灌输在你脑子里的谬论，别再相信它们所谓的”新技术”，别再追赶Windows，因为追赶 Windows =倒退。</em>马克思有一个思想很重要，”新生事物并不一定是在最近出现的。” UNIX，Xwindow, TeX 虽然都比 Windows 先出现，但是它们才是先进生产力的代表。我们要清楚的认识到什么才是真正的现代化，什么才是真正的自动化。</p>
<p>勇敢的拿起像 bash, FVWM, VIM, Emacs, Mutt, lftp &#8230;&#8230; 这样强大的程序，不要再埋怨”Linux 为什么不能像 Windows 那样”，不要再浪费时间试用这样那样的程序，不要再忙着升级。是你需要改变而不是 Linux 和 UNIX，Linux 现在就可以成为你的好朋友。你需要认识它，了解它，信任它，才能完全的靠它来高效的工作，省出时间来处理世界上更加值得处理的事情。</p><h2  class="related_post_title">类似的文章</h2><ul class="related_post"><li>2012年01月23日 -- <a href="http://www.penglixun.com/tech/database/case_about_innodb_faster_than_oracle.html" title="一个InnoDB性能超过Oracle的调优Case">一个InnoDB性能超过Oracle的调优Case</a> (1)</li><li>2010年08月27日 -- <a href="http://www.penglixun.com/tech/system/linux_cache_discovery.html" title="Linux Cache 机制探究">Linux Cache 机制探究</a> (1)</li><li>2010年08月10日 -- <a href="http://www.penglixun.com/tech/system/how_to_calc_load_cpu.html" title="Load和CPU利用率是如何算出来的">Load和CPU利用率是如何算出来的</a> (5)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.penglixun.com/life/feeling/all_works_in_linux.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

