<?xml version="1.0" encoding="utf-8"?><rss version="2.0"  xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
  <title>leeon | 分享未来</title>
  <link>http://www.leeon.me</link>
  <description>Share Future,Share Internet Technology</description>
  <atom:link href="http://www.leeon.me/feed" rel="self" type="application/rss+xml" />
    <item>
    <title>【转载】浏览器缓存，HTTP缓存详解</title>
    <link>http://www.leeon.me/a/explorer-cache-http-cache</link>
	<pubDate>Fri, 03 Sep 2010 12:20:07 +0800</pubDate>
	<category>网络</category>
    <description><![CDATA[
	<p><strong>浏览器缓存现象</strong></p>
<p>浏览器通过URL地址访问一个网页，显示网页内容的同时会在用户的电脑上面缓存网页内容。如果网页没有更新的话，浏览器再次访问这个URL地址的时候，就不会再次下载网页，而是直接使用本地缓存的网页。只有当网站明确标识资源已经更新，浏览器才会再次下载网页。</p>
<p><strong>一、HTTP缓存涉及的http头</strong></p>
<p>1. Expires（过期时间）HTTP头信息</p>
<p>Expires属性是告诉缓存器缓存在多长时间内是有效的。过了该时间，缓存器就会向源服务器发送请求，检查文档是否被修 改。几乎所有的缓存服务器都支持Expires属性；</p>
<p>Web服务器设置Expires属性的方法有：</p>
<ul>
<li>绝对时间间隔：基于客户最后查看副本的时间（最后访问时间） </li>
</ul>
<ul>
<li>根据服务器上文档最后被修改的时间 </li>
</ul>
<p>适用范围：</p>
<ul>
<li>对于设置静态图片文件（例如导航栏和图片按钮）可缓存特别有用；因为这些图片修改很少，你可以给它们设置一个特别长的过期时间，这会使你的网站对 用户变得相应非常快； <li>对于控制有规律改变的网页也很有用。例如：你每天早上6点更新新闻页，你可以设置副本的过期时间也是这个时间，这样缓存 服务器就知道什么时候去取一个更新版本，而不必让用户去按浏览器的“刷新”按钮。 </li>
</ul>
<p>时间格式：</p>
<p>只能是HTTP格式的日期时间，其他的都会被解析成当前时间“之前”，副本会过期，记住：HTTP的日期时间必须是格林威治时 间（GMT），而不是本地时间。举例：Expires: Fri, 30 Oct 1998 14:19:41</p>
<p>注意：</p>
<ul>
<li>确认你的Web服务器时间设置正确。 <li>Web服务器的时间和缓存服务器的时间必须是同步的，如果不同步， 要么是应该缓存的内容提前过期了，要么是过期结果没及时更新。 <li>如果设置的过期时间是一个固定的时间，如果返回内容的时候又没有连带更新下次过期的时间，那么之后所有访问请求都会被发送给源Web服务器，反而增加了负载和响应时间； </li>
</ul>
<p>2. Cache-Control（缓存控制） HTTP头信息</p>
<p>有用的 Cache-Control响应头信息包括：</p>
<ul>
<li>max-age=n&nbsp; 单位是秒：从请求时间开始到过期时间之间的秒数，是相对时间间隔，而不是绝对过期时间； </li>
</ul>
<ul>
<li>s-maxage=n&nbsp; 类似于max-age属性，除了他应用于共享（如：代理服务器）缓存； </li>
</ul>
<ul>
<li>public&nbsp; 标记认证内容也可以被缓存，经过HTTP认证才能访问的内容，输出是自动不可以缓存的； </li>
</ul>
<ul>
<li>no-cache&nbsp; 强制每次请求直接发送给源服务器，而不经过本地缓存版本的校验； </li>
</ul>
<ul>
<li>no-store&nbsp; 强制缓存在任何情况下都不要保留任何副本 </li>
</ul>
<ul>
<li>must-revalidate&nbsp; 告诉缓存必须遵循所有你给予副本的新鲜度的，HTTP允许缓存在某些特定情况下返回过期数据； </li>
</ul>
<ul>
<li>proxy-revalidate和must-revalidate类似，除了他只对缓存代理服务器起作用 </li>
</ul>
<p>举例:<br />
Cache-Control: max-age=3600, must-revalidate</p>
<p>注意：</p>
<ul>
<li>给静态资源(HTML文件，图片文件等）的Repsone加上Expires/Cache-Control Header是很有效的一招。Expires的值只能是一个固定日期，比如“Thu 27 Nov 2008 07:00:00 GMT”，不能是一个类似“从现在开始之后10年”这样一个随机浮动的值，如果要这样的效果，可以用Cache-Control这样的Header，如果 HTTP Resposne中有这样的Header:“Cache-Control: max-age = 100”，表示这个资源在cache中的最大寿命是100秒。一般说来这种静态文件永远不应该过期，如果真的要给这个Cache加上一个期限，那我希望是 ——一万年，“Cache-Control: max-age = 315360000000” </li>
</ul>
<ul>
<li>其实就应该给Expires设一个永远不会过期的时间，比如你现在有一个文件叫logo.gif，需要用一个新的logo的时候，你不要去 覆盖原来的文件，而把新的logo存成logo_v2.gif，让相关网页引用新的logo_v2.gif，这样可以让新老网页同时工作，实在犯不上为了 节省存储空间覆盖原有文件。 </li>
</ul>
<p>配置：</p>
<p style="padding-left:30px;">对Apache服务器，使用mod_expires，在httpd.conf或者.htaccess中加上&lt;FilesMatch “<a>\\.(ico|gif|jpg|html)$”&gt;ExpiresDefault</a> “access plus 10 years”&lt;/FileMatch&gt;</p>
<p>3.Last-Modified/If-Modified-Since</p>
<p>所有现代的浏览器都支持最近修改 (last-modified) 的数据检查。如果你曾经访问过某页，一天后重新访问相同的页时发现它没有变化，并奇怪第二次访问时页面加载得如此之快——这就是原因所在。你的浏览器首次 访问时会在本地缓存页面内容，当你第二次访问，浏览器自动发送首次访问时从服务器获得的最近修改日期。服务器简单地返回 304: Not Modified (没有修改)，因此浏览器就会知道从本地缓存加载页面。</p>
<p>4. ETag/If-None-Match</p>
<p>ETag 是实现与最近修改数据检查同样的功能的另一种方法：没有变化时不重新下载数据。其工作方式是：服务器发送你所请求的数据的同时，发送某种数据的 hash (在 ETag 头信息中给出)。hash 的确定完全取决于服务器。当第二次请求相同的数据时，你需要在 If-None-Match: 头信息中包含 ETag hash，如果数据没有改变，服务器将返回 304 状态代码。与最近修改数据检查相同，服务器仅仅 发送 304 状态代码；第二次将不为你发送相同的数据。在第二次请求时，通过包含 ETag hash，你告诉服务器：如果 hash 仍旧匹配就没有必要重新发送相同的数据，因为你还有上一次访问过的数据。</p>
<p>这几个http头可以作为meta标签发送到客户端，但是需要注意的是Http头中的设置优先级更高一些，例如：<br />
&lt;meta http-equiv=”Expires” CONTENT=” Fri, 30 Oct 1998 14:19:41″&gt;<br />
&lt;meta http-equiv=”Cache-Control” CONTENT=”no-cache”&gt;</p>
<p>我们来访问http://www.baidu.com的首页，通过firebug，我们来查看logo图片http://www.baidu.com/img/baidu_logo.gif的headers：</p>
<p style="padding-left:30px;"><span>响应头信息</span></p>
<pre style="padding-left:30px;" class="html"><table class="tcliz_table" border="1" cellspacing="0" cellpadding="0"><tbody><tr><td><span>Date</span></td>
<td><code>Tue, 10 Aug 2010 09:31:36 GMT</code></td>
</tr>
<tr><td><span>Server</span></td>
<td><code>Apache</code></td>
</tr>
<tr><td><span>Last-Modified</span></td>
<td><code>Tue, 29 Jul 2008 16:00:00 GMT</code></td>
</tr>
<tr><td><span>Etag</span></td>
<td><code>"5d1-4532bbb6ca000"</code></td>
</tr>
<tr><td><span>Accept-Ranges</span></td>
<td><code>bytes</code></td>
</tr>
<tr><td><span>Content-Length</span></td>
<td><code>1489</code></td>
</tr>
<tr><td><span>Cache-Control</span></td>
<td><code>max-age=315360000</code></td>
</tr>
<tr><td><span>Expires</span></td>
<td><code>Fri, 07 Aug 2020 09:31:36 GMT</code></td>
</tr>
<tr><td><span>Connection</span></td>
<td><code>Keep-Alive</code></td>
</tr>
<tr><td><span>Content-Type</span></td>
<td><code>image/gif</code></td>
</tr>
</tbody>
</table>
<div><span>请求头信息</span></div>
<table class="tcliz_table" border="0" cellspacing="0" cellpadding="0"><tbody><tr><td><span>Host</span></td>
<td><code>www.baidu.com</code></td>
</tr>
<tr><td><span>User-Agent</span></td>
<td><code>Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3</code></td>
</tr>
<tr><td><span>Accept</span></td>
<td><code>image/png,image/*;q=0.8,*/*;q=0.5</code></td>
</tr>
<tr><td><span>Accept-Language</span></td>
<td><code>zh-cn,zh;q=0.5</code></td>
</tr>
<tr><td><span>Accept-Encoding</span></td>
<td><code>gzip,deflate</code></td>
</tr>
<tr><td><span>Accept-Charset</span></td>
<td><code>GB2312,utf-8;q=0.7,*;q=0.7</code></td>
</tr>
<tr><td><span>Keep-Alive</span></td>
<td><code>115</code></td>
</tr>
<tr><td><span>Connection</span></td>
<td><code>keep-alive</code></td>
</tr>
<tr><td><span>Referer</span></td>
<td><code>http://www.baidu.com/</code></td>
</tr>
<tr><td><span>Cookie</span></td>
<td><code>BAIDUID=60A41CF3CE102AC479459D7202BC7C0C:FG=1; USERID=de28364425ea7fdbeb32a85ecb7beb; BD_UTK_DVT=1</code></td>
</tr>
<tr><td><span>Pragma</span></td>
<td><code>no-cache</code></td>
</tr>
<tr><td><span>Cache-Control</span></td>
<td><code>no-cache</code></td>
</tr>
</tbody>
</table>
</pre> <p>F5刷新，第二次查看headers：</p>
<p style="padding-left:30px;"><span>响应头信息</span>查看源代码</p>
<pre style="padding-left:30px;" class="html"><table class="tcliz_table" border="0" cellspacing="0" cellpadding="0"><tbody><tr><td><span>Date</span></td>
<td><code>Tue, 10 Aug 2010 09:37:02 GMT</code></td>
</tr>
<tr><td><span>Server</span></td>
<td><code>Apache</code></td>
</tr>
<tr><td><span>Connection</span></td>
<td><code>Keep-Alive</code></td>
</tr>
<tr><td><span>Etag</span></td>
<td><code>"5d1-4532bbb6ca000"</code></td>
</tr>
<tr><td><span>Expires</span></td>
<td><code>Fri, 07 Aug 2020 09:37:02 GMT</code></td>
</tr>
<tr><td><span>Cache-Control</span></td>
<td><code>max-age=315360000</code></td>
</tr>
</tbody>
</table>
<span> 请求头信息</span><span>查看源代码</span> <table class="tcliz_table" border="0" cellspacing="0" cellpadding="0"><tbody><tr><td><span>Host</span></td>
<td><code>www.baidu.com</code></td>
</tr>
<tr><td><span>User-Agent</span></td>
<td><code>Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3</code></td>
</tr>
<tr><td><span>Accept</span></td>
<td><code>image/png,image/*;q=0.8,*/*;q=0.5</code></td>
</tr>
<tr><td><span>Accept-Language</span></td>
<td><code>zh-cn,zh;q=0.5</code></td>
</tr>
<tr><td><span>Accept-Encoding</span></td>
<td><code>gzip,deflate</code></td>
</tr>
<tr><td><span>Accept-Charset</span></td>
<td><code>GB2312,utf-8;q=0.7,*;q=0.7</code></td>
</tr>
<tr><td><span>Keep-Alive</span></td>
<td><code>115</code></td>
</tr>
<tr><td><span>Connection</span></td>
<td><code>keep-alive</code></td>
</tr>
<tr><td><span>Referer</span></td>
<td><code>http://www.baidu.com/</code></td>
</tr>
<tr><td><span>Cookie</span></td>
<td><code>BAIDUID=60A41CF3CE102AC479459D7202BC7C0C:FG=1; USERID=de28364425ea7fdbeb32a85ecb7beb; BD_UTK_DVT=1</code></td>
</tr>
<tr><td><span>If-Modified-Since</span></td>
<td><code>Tue, 29 Jul 2008 16:00:00 GMT</code></td>
</tr>
<tr><td><span>If-None-Match</span></td>
<td><code>"5d1-4532bbb6ca000"</code></td>
</tr>
<tr><td><span>Cache-Control</span></td>
<td><code>max-age=0</code></td>
</tr>
</tbody>
</table>
</pre> <p>我们可以看到这个图片的最后修改时间和Etag。于是浏览器把这两个状态信息连同网页内容在本地进行缓存，当浏览器再次访问该图片的时候，浏览器会发送如下两个状态标识告诉服务器，我本地缓存的网页最后修改时间和Etag，请问服务器的资源有没有在我上次访问之后有更新啊？于是服务器会核对一下， 如果该用户上次访问之后没有更新过新闻，直接告诉浏览器：“没什么新东西，你还是看自己缓存的网页吧”，于是服务器就发 送一个304 Not Modified的消息，其他什么都不用干了。</p>
<p><strong>二、HTTP缓存有什么用？</strong></p>
<p>1.像Google这种比较智能的网络爬虫可以有效识别资源的状态信息，如果使用这 种缓存机制，可以大大减少爬虫的爬取次数。</p>
<p>2.很多内容更新不频繁的网页，尽管用户不会频繁的刷新，但是从一个比较长的时间段来看使用HTTP Cache，仍然可以起到很大的缓存作用。</p>
<p>3.对于历史帖子使用HTTP缓存。</p>
<ul>
<li>例如，一些历史贴子，很少有人往后面翻页去看历史数据，也就无法被memcache缓存住，那有了http缓存，用户通过收藏夹保存或者其他方式过来，就不必去取数据了。另外爬虫也不会频繁爬去了。 </li>
</ul>
<p><strong><span style="font-size:medium;">三、如何在应用程序里面使用HTTP缓存<br />
</span></strong></p>
<p><span>前两种就不说了，直接设置过期时间。重点说说ETAG吧。<br />
</span></p>
<p><span>1. </span><span>适用于新闻列表页，文章列表页等。</span><span>拿最新一条数据做ETAG，该数据的最后更新时间做</span><span>Last-Modified时间。</span></p>
<p><span>2. 适用于单篇文章页。拿文章最后修改时间和评论数做hash值作为ETAGE，最后更新时间做Lsdt-Modified时间。如果该文章作修改或多一条评论数的话，就认为该页有更新。</span></p>
<p><span>等等，具体应用可根据需求来定，发挥大家的思想。</span><br />
<strong>总结</strong><br />
Expires/Cache-Control Header是控制浏览器是否直接从浏览器缓存取数据还是重新发请求到服务器取数据。只是Cache-Control比Expires可以控制的多一些， 而且Cache-Control会重写Expires的规则。</p>
<p>Last-Modified/If-Modified-Since和ETag/If-None-Match是浏览器发送请求到服务器后判断文件是否已经修改过，如果没有修改过就只发送一个304回给浏览器，告诉浏览器直接从自己本地的缓存取数据；如果修改过那就整个数据重新发给浏览器。</p>	]]></description>
	<guid isPermaLink="false">http://www.leeon.me/feed/112</guid>
  </item>
    <item>
    <title>CPU性能监控小记</title>
    <link>http://www.leeon.me/a/linux-performence-monitor</link>
	<pubDate>Thu, 02 Sep 2010 15:16:40 +0800</pubDate>
	<category>调优</category>
    <description><![CDATA[
	<p>监控 CPU 性能由以下几个部分组成：</p>
<div class="orderedlist">
<ol type="1">
<li>
<p>检查system的运行队列,以及确定不要超出每个处理器3个可运行状态线程的限制.</p>
<li>
<p>确定CPU 利用率中user/system比例维持在70/30</p>
<li>
<p>当CPU 开销更多的时间在system mode,那就说明已经超负荷并且应该尝试重新调度优先级</p>
<li>
<p>当I/O 处理得到增长,CPU 范畴的应用处理将受到影响</p>
</li>
</ol>
</div>	]]></description>
	<guid isPermaLink="false">http://www.leeon.me/feed/111</guid>
  </item>
    <item>
    <title>【转载】btree索引和hash索引的区别</title>
    <link>http://www.leeon.me/a/btree-between-hash</link>
	<pubDate>Thu, 02 Sep 2010 12:56:31 +0800</pubDate>
	<category>算法</category>
    <description><![CDATA[
	<p>在mysql中，大多数索引（如 PRIMARY KEY,UNIQUE,INDEX和FULLTEXT）都是在BTREE中存储，但使用memory引擎可以选择BTREE索引或者HASH索引，两种不同类型的索引各自有其不同的使用范围。</p>
<p>=========以下节选网摘==========<br />
Hash 索引结构的特殊性，其检索效率非常高，索引的检索可以一次定位，不像B-Tree 索引需要从根节点到枝节点，最后才能访问到页节点这样多次的IO访问，所以 Hash 索引的查询效率要远高于 B-Tree 索引。</p>
<p>&nbsp;</p>
<p>可能很多人又有疑问了，既然 Hash 索引的效率要比 B-Tree 高很多，为什么大家不都用 Hash 索引而还要使用 B-Tree 索引呢？任何事物都是有两面性的，Hash 索引也一样，虽然 Hash 索引效率高，但是 Hash 索引本身由于其特殊性也带来了很多限制和弊端，主要有以下这些。</p>
<p>（1）Hash 索引仅仅能满足"=","IN"和"&lt;=&gt;"查询，不能使用范围查询。</p>
<p>由于 Hash 索引比较的是进行 Hash 运算之后的 Hash 值，所以它只能用于等值的过滤，不能用于基于范围的过滤，因为经过相应的 Hash 算法处理之后的 Hash 值的大小关系，并不能保证和Hash运算前完全一样。</p>
<p>（2）Hash 索引无法被用来避免数据的排序操作。</p>
<p>由于 Hash 索引中存放的是经过 Hash 计算之后的 Hash 值，而且Hash值的大小关系并不一定和 Hash 运算前的键值完全一样，所以数据库无法利用索引的数据来避免任何排序运算；</p>
<p>（3）Hash 索引不能利用部分索引键查询。</p>
<p>对于组合索引，Hash 索引在计算 Hash 值的时候是组合索引键合并后再一起计算 Hash 值，而不是单独计算 Hash 值，所以通过组合索引的前面一个或几个索引键进行查询的时候，Hash 索引也无法被利用。</p>
<p>（4）Hash 索引在任何时候都不能避免表扫描。</p>
<p>前面已经知道，Hash 索引是将索引键通过 Hash 运算之后，将 Hash运算结果的 Hash 值和所对应的行指针信息存放于一个 Hash 表中，由于不同索引键存在相同 Hash 值，所以即使取满足某个 Hash 键值的数据的记录条数，也无法从 Hash 索引中直接完成查询，还是要通过访问表中的实际数据进行相应的比较，并得到相应的结果。</p>
<p>（5）Hash 索引遇到大量Hash值相等的情况后性能并不一定就会比B-Tree索引高。</p>
<p>对于选择性比较低的索引键，如果创建 Hash 索引，那么将会存在大量记录指针信息存于同一个 Hash 值相关联。这样要定位某一条记录时就会非常麻烦，会浪费多次表数据的访问，而造成整体性能低下。</p>	]]></description>
	<guid isPermaLink="false">http://www.leeon.me/feed/110</guid>
  </item>
    <item>
    <title>JavaScript之trim方法三则</title>
    <link>http://www.leeon.me/a/javascript-trim</link>
	<pubDate>Sat, 28 Aug 2010 21:29:34 +0800</pubDate>
	<category>javascript</category>
    <description><![CDATA[
	<p>ECMAscript 5规定了trim的原生方法，但老的浏览器是不支持的。现提供三种trim的方法来删除字符串头尾的空格。</p>
<p>方法一：</p>
<p>[code="js"]<br />
function trim(text){<br />
return text.replace(/^\s+|\s+$/g,"");<br />
}<br />
[/code]</p>
<p>此方法性能最差，但是编码简单。</p>
<p>方法二：</p>
<p>[code="js"]<br />
function trim(text){<br />
return text.replace(/^\s+/,""),replace(/\s+$/,"");<br />
}<br />
[/code]</p>
<p>较第一种方法性能稍好。</p>
<p>方法三：</p>
<p>[code="js"]<br />
function trim(){<br />
text = text.replace(/^\s+/,"");<br />
for(var i=text.length-1;i&gt;=0;i-){<br />
if(/\S/.test(text.charAt(i))){<br />
text = text.substring(0,i+1);<br />
break;<br />
}<br />
}<br />
}<br />
[/code]</p>
<p>此方法在大规模字符串中性能最好</p>	]]></description>
	<guid isPermaLink="false">http://www.leeon.me/feed/109</guid>
  </item>
    <item>
    <title>【转载】Linux服务器群集技术总结</title>
    <link>http://www.leeon.me/a/linux-cluster-summary</link>
	<pubDate>Fri, 20 Aug 2010 10:47:35 +0800</pubDate>
	<category>架构</category>
    <description><![CDATA[
	<p>1． 引言<br />
在制作电影《泰坦尼克号》所用的160台Alpha图形工作站中，有105台运行的是Linux操作系统，这160台Alpha工作站是做图形处理。图形处理中有一项重要的任务—计算。这些计算机是被利用群集技术（Cluster）组织到一起的。这就是cluster中的一种—“并行计算”。</p>
<p>2． Cluster概况<br />
Cluster只是一个笼统的概念，刚才提到的“并行计算”只是cluster的一个方面，这方面的主要应用就是用低成本的“低档”电脑去做super computer的工作。</p>
<p>Cluster分为下面几方面</p>
<p>l 高可用性，High-Availability (HA)</p>
<p>l 负载平衡，Load Balance</p>
<p>l 科学计算，即并行计算，Scientific Computing</p>
<p>1. HA：用在不允许中断服务的场合。实际上是两台（或更多台）计算机通过一定方式互相监听，实现热备份。当其中的主服务器（primary server）出现问题时，备份服务器(standby backup server or secondary server)能够自动立即接替工作，使用户感觉不出停机。在primary server恢复正常之后，backup server又会把工作还给primary server。</p>
<p>2. Load Balance：在web server上的应用比较多（尽管它支持很多别的协议如ftp, telnet, sendmail等，但用处最多的还是http服务）。用户访问一个地址，但实际上后台是有若干台服务器在提供服务。而当服务请求达到饱和时，还可以很容易地再添加新的节点而不用停掉整个cluster，实现所谓的“热插拔”，这也就是Cluster中的一个概念—Scalability (易扩展性)。而且，cluster还会查询真实节点的情况，当某台真实节点没有响应时，就不再把任务分配到那里，直到这台节点恢复正常。</p>
<p>3. Scientific，主要用于计算量大的场合。比如刚才提到的图象处理，或一些海量计算的科学实验，以及国防应用。</p>
<p>那么什么是cluster呢？</p>
<p>1.Clustering是用两个（或更多）的系统（节点）在一起工作，来提供相同服务或实现相同目的；</p>
<p>2.在外面看来，整个体系结构象一个完整的系统；</p>
<p>3.Clustering用来提高服务的稳定性和/或核心网络服务的性能。</p>
<p>2.1 HA (heartbeat)<br />
在HA方面，heartbeat（心跳）是代表技术。Heartbeat的工作方式属于Server Monitor（服务器监控）方式，即备份服务器和主服务器互相监听的一种技术。这种方式的特点是</p>
<p>l 提供了可用性（availability），但没有提供可扩展性（Scalability）。</p>
<p>l 只限两台节点</p>
<p>l 两台节点执行相同的服务，但只有主节点与外界通讯</p>
<p>l 当主节点出问题时，备份节点马上接替工作&nbsp;&nbsp;<br />
&nbsp; <br />
Server Mirror解决方案的例子有：</p>
<p>Novel SFT III</p>
<p>Vinca Standby Server</p>
<p>Compaq Standby Server</p>
<p>下图为Compaq Standby Server的应用示例：</p>
<p><img border="0" alt="" src="http://www.leeon.me/upload/2010-08/20100820100830_54341.gif" width="240" height="131" /></p>
<p>还有另外两种方式—Application Failover，Fault Tolerant</p>
<p>l 应用程序故障接管技术（Application Failover）</p>
<p><img border="0" alt="" src="http://www.leeon.me/upload/2010-08/20100820100813_36154.jpg" width="244" height="153" /></p>
<p>采用这种方式的例子有：</p>
<p>Microsoft Cluster Server</p>
<p>Digital Clusters</p>
<p>Sun Clusters</p>
<p>下图为Microsoft Cluster Server的一种配置示例：</p>
<p><img border="0" alt="" src="http://www.leeon.me/upload/2010-08/20100820100849_95425.gif" width="244" height="162" /></p>
<p>下图为Digital Clusters的一种配置示例</p>
<p><img border="0" alt="" src="http://www.leeon.me/upload/2010-08/20100820100815_32307.gif" width="244" height="106" /></p>
<p>l 容错技术（Fault Tolerant）</p>
<p>这种技术的优点也很多，特别是可以作到不间断客户端的连接就可以接替服务，但价格较贵，一般都在$1,000,000以上。</p>
<p>代表产品有：</p>
<p>Tandem (Compaq) NonStop Cluster</p>
<p>前几届的师兄们所做的广东省自然科学基金项目：基于Unix容错技术的研究，就属于这方面的范畴。</p>
<p>2.2 Load Balance（LVS, TurboCluster）<br />
负载均衡的群集技术主要应用于Web服务器群中，解决Web服务器在高访问量时的负载分流问题。</p>
<p>下面是一种成熟的商业Load Balance方案，主要采用了DNS的域名轮换指向技术，即在DNS服务器上使来在用户浏览器的请求平均分配给不同的Web服务器。&nbsp; <br />
<img border="0" alt="" src="http://www.leeon.me/upload/2010-08/20100820100801_36566.jpg" width="244" height="132" /></p>
<p><br />
这种属于单一的可扩展群集技术（Scalability-only Clustering），Web服务器群仅仅具有可扩展性，应付突发的高访问量。</p>
<p>例子有：</p>
<p>Round Robin DNS</p>
<p>F5 BigIP/LB</p>
<p>Other older HW solutions</p>
<p><img border="0" alt="" src="http://www.leeon.me/upload/2010-08/20100820100840_66872.jpg" width="456" height="239" /></p>
<p>新的解决方案是高可用性可扩展技术/高可用性负载均衡技术（HAScalability/HA Load Balancing Clusters），加入了故障处理机制。</p>
<p>它同时提供可扩展性和高可靠性，一般用来提供核心网络服务：Web, mail, news, 等等。大的ISP和企业会用到，起价$25,000到$50,000之间，随着价格下降，更多用户会对此产生兴趣。采用这种方案的有：</p>
<p>Resonate Central Dispatch</p>
<p>F5 BigIP</p>
<p>Cisco LocalDirector</p>
<p>TurboCluster Server</p>
<p>Linux Virtual Server(Piranha, UltraMonkey等)</p>
<p>而这些方案中，最具价格优势的是TurboCluster 和Linux Virtual Server(LVS)。TurboCluster软件目前约20,000人民币，而LVS则加入了GPL公约，是免费的。</p>
<p>2.3 Scientific (Beowulf, MOSIX, PVM, MPI)<br />
和刚才说的两种cluster的目的不同，这种cluster的主要目的是为了提高计算机处理任务的速度。应用程序需要被写成一种分布式应用程序，在运行时被分成分布式处理的进程，同时运行在多个节点上。例子：</p>
<p>Beowulf Cluster</p>
<p>Supercomputer Architectures</p>
<p>MPI(Message Passing Interface)</p>
<p>MOSIX </p>
<p>PVM(Parallel Virtual Mation)</p>
<p>2.4小节<br />
从上面可以看出，Cluster并不是什么新的思想，Cluster思想已经发展多年，比较成熟。但原来都需要专业的软/硬件设备才能实现。所以只有少数公司才有能力用的起。但随的linux的流行，出现了许多基于linux，基于PC的cluster解决方案，使更多的人有机会构建自己的cluster。而且这些基于linux的软件大多都是遵循GPL协议的，是Open Source的。从而更推动了cluster技术的发展。</p>
<p>3． Heartbeat<br />
3.1设计思想<br />
Heartbeat顾名思义，就是心跳。两台计算机通过某种途径向对方发送“heartbeat”，同时也在监听对方的“heartbeat”。从而知道对方的状态。这种途径可以是串口线，也可以是网卡。可以同时使用。但如果只用一块网卡，则会发生单故障点SPOF[Single Point of Failure: a part which renders an entire system unusable when if fails (SPOF)]</p>
<p>Heartbeat除了在互相发送消息外，另外一项重要的工作就是接替和释放资源。比如：</p>
<p>假设系统主服务器为192.168.2.49，副服务器为192.168.2.47。平时主服务器虚拟192.168.2.48这个IP，当主服务器出问题时（比如关机），192.168.2.47自动虚拟192.168.2.48这个IP。</p>
<p>3.2 安装<br />
Heartbeat属于应用程序级别的程序，所以不需要修改内核。只要取得其源代码。在任意目录下释放（/tmp），然后编译安装即可</p>
<p>tar xzvf heartbeat-0.4.6.tar.gz</p>
<p>cd heartbeat-0.4.6</p>
<p>make</p>
<p>make install</p>
<p>3.3 配置<br />
Heartbeat的安装很容易，关键步骤是配置，第一个需要配置的文件为/etc/ha.d/ha.cf，具体配置选项在里面都有注释，下面是一个例子：</p>
<p>logfacility local0</p>
<p>keepalive 1</p>
<p>deadtime 3</p>
<p>serial /dev/ttyS0</p>
<p>nice_failback off</p>
<p>node tst_sd5_svr9</p>
<p>node tst_sd5_svr7</p>
<p>这里表示主节点为tst_sd5_svr9(192.168.2.49)， 副节点为tst_sd5_svr7(192.168.2.47)</p>
<p>第二个需要配置的文件为/etc/ha.d/haresources，具体配置选项在里面都有注释，下面是一个例子：</p>
<p>tst_sd5_svr9 IPaddr::192.168.2.48/24 httpd</p>
<p>这个告诉系统主节点是tst_sd5_svr9，当heartbeat启动时，虚拟192.168.2.48这个IP。并且启动/etc/rc.d/init.d/httpd start这个命令。</p>
<p>第三个需要配置的文件是/etc/ha.d/authkeys，下面是一个例子：</p>
<p>auth 2</p>
<p>2 sha1 ultramonkey</p>
<p>注意，这个文件的属性一定要是600，所以要用chmod 600 authkeys设一下。然后就可以用/etc/rc.d/init.d/heartbeat start启动heartbeat服务了。还可以设为系统启动时自动启动：</p>
<p>cd /etc/rc.d/rc0.d ; ln -s ../init.d/heartbeat K01heartbeat </p>
<p>cd /etc/rc.d/rc3.d ; ln -s ../init.d/heartbeat S99heartbeat </p>
<p>cd /etc/rc.d/rc5.d ; ln -s ../init.d/heartbeat S99heartbeat </p>
<p>cd /etc/rc.d/rc6.d ; ln -s ../init.d/heartbeat K01heartbeat </p>
<p>至此，heartbeat就可以工作了，log文件在/var/log/ha-log中。</p>
<p>3.4 特点<br />
前面基本已经说过，heartbeat能提供HA，但不能提供扩展性。也就是说cluster的性能就是一台server的性能。所以heartbeat一般都是和load balance结合起来使用。下面的load balance就是结合heartbeat的例子，因为单纯的load balance如果没有HA，则当负责分配任务的router（switcher）出问题时，整个cluster都会不工作。</p>
<p>4． Load-Balance <br />
4.1设计思想<br />
Load balance是通过router（switcher）把任务分派到真实节点上来提高整个cluster的性能，整个cluster的性能是由真实节点的性能和真实节点的数量决定的。所以，同一个cluster中的各个真实节点的内容都是一样的。是完全相同的镜象。当整个cluster的能力不够是，可以增加真实节点来提高性能。而增加真实节点只是在网络里增加几台计算机，所以不用关掉其他机器，只需在router上的真实节点表里增加几条记录就可以了。</p>
<p>4.2和传统方式的比较<br />
有用其他方式实现类似功能的解决方案，比如前面提到的修改DNS，让一个域名对应多个IP，这样也可以把任务分派到多台机器上去。或者在路由器上把任务分给多台机器。第一做法是完全随机的，第二种做法是固定的，两者都不会根剧当时情况调整分配到真实节点上的任务量。而LVS提供了4中分配方法(Load-balancing Methods)和3种转发机制（Traffic Forward Mechanism）。具体情况在后面介绍</p>
<p>4.3 LVS<br />
l 设计思想及特点</p>
<p>LVS提供了4种负载平衡的分配方法(Load-balancing Methods)和3种转发机制（Traffic Forward Mechanism）。</p>
<p>负载平衡方法： 名称<br />
&nbsp;简介<br />
&nbsp;<br />
Round robin<br />
&nbsp;在实际服务器间平均分配负载<br />
&nbsp;<br />
Leastconnections<br />
&nbsp;最少活动连接数的服务器分配较多的负载 (The IPVS table stores active connections.)<br />
&nbsp;<br />
Weighted round robin<br />
&nbsp;根据动态负载权重和服务器的处理能力，在实际服务器中平均分配负载<br />
&nbsp;<br />
Weighted leastconnections<br />
&nbsp;根据服务器的权重，为最少连接数的服务器分配负载。<br />
&nbsp;</p>
<p><br />
LVS提供了3种转发机制（Traffic Forward Mechanism）</p>
<p>分别为VS-NAT,VS-TUN 和VS-DR&nbsp;&nbsp; VS-NAT<br />
&nbsp;VS-TUN<br />
&nbsp;VS-DR<br />
&nbsp;<br />
Server<br />
&nbsp;any<br />
&nbsp;tunneling<br />
&nbsp;non-arp device<br />
&nbsp;<br />
server network<br />
&nbsp;private<br />
&nbsp;LAN/WAN<br />
&nbsp;LAN<br />
&nbsp;<br />
server number<br />
&nbsp;low (10~20)<br />
&nbsp;high<br />
&nbsp;High<br />
&nbsp;<br />
server gateway<br />
&nbsp;load balancer<br />
&nbsp;own router<br />
&nbsp;own router<br />
&nbsp;</p>
<p><br />
3种转发机制中。常用的是VS-NAT。这种方式只需要几个公有IP，真实节点都在内部使用私有IP。而且真实节点可以是任何系统（包括NT），缺点是router（switcher）是整个系统的瓶颈，因为所有的数据都会通过router。一般真实节点数为20台左右。但这个问题可以解决，一种方法是混合途径，即设多个cluster组，然后通过DNS指向这几个router。另一种方法就是用VS-TUN或VS-DR</p>
<p>l 安装</p>
<p>所谓安装只需要在router上进行，真实节点不需要安装，特别是VS-NAT方式。这是节点唯一需要做的就是把设定一下缺省网关。安装LVS需要重新编译linux内核。在安装LVS时，需要下载相应版本的内核补丁。比如我们实验用的内核为2.2.14，相应补丁为ipvs-0.9.12-2.2.14.tar.gz</p>
<p>假设内核在/usr/src/linux中。ipvs-0.9.12-2.2.14.tar.gz被释放在/root/ipvs-0.9.12-2.2.14中。</p>
<p>1.先给内核做patch</p>
<p>cd /usr/src/linux</p>
<p>cat /root/ipvs-0.9.12-2.2.14/ipvs-0.9.12-2.2.14.patch | patch -p1</p>
<p>2.然后配置内核选项</p>
<p>make xconfig</p>
<p>Kernel Compile Options:</p>
<p>Code maturity level options ---</p>
<p>[*] Prompt for development and/or incomplete code/drivers</p>
<p>Networking options ---</p>
<p>[*] Network firewalls</p>
<p>....</p>
<p>[*] IP: firewalling</p>
<p>....</p>
<p>[*] IP: masquerading</p>
<p>....</p>
<p>[*] IP: masquerading virtual server support</p>
<p>(12) IP masquerading table size (the Nth power of 2)</p>
<p>IPVS: round-robin scheduling</p>
<p>IPVS: weighted round-robin scheduling</p>
<p>IPVS: least-connection scheduling</p>
<p>IPVS: weighted least-connection scheduling</p>
<p>....</p>
<p>[*] IP: aliasing support</p>
<p>其他选项根据需要选如网卡驱动程序</p>
<p>3.编译内核并用新内核启动</p>
<p>4.编译ipvsadm管理程序</p>
<p>cd /root/ipvs-0.9.12-2.2.14/ipvsadm</p>
<p>make install</p>
<p>重新启动系统就可以用ipvsadm来配置和管理cluster了</p>
<p>l 设置</p>
<p>具体设置方法在讲Piranha(水虎鱼)与Ultra Monkey文挡里有讲述。LVS的安装相对来说比较麻烦，但如果选用Piranha（这是RedHat公司基于LVS开发的产品，遵守GPL的），则只要正常安装RH6.1或RH6.2就免去了安装过程，而Ultra Monkey则提供了编译好的内核，而且是以rpm格式提供的，安装也非常简单。</p>
<p>5． MOSIX<br />
5.1 Beowulf<br />
一谈到并行计算，研究cluster的人第一个提到的就是Beowulf。Beowulf是目前最有名的基于廉价PC并行计算的cluster。但是Beowulf对硬件有特殊的要求。它需要千兆级速度的网卡，我们现在自己使用的网卡都是10M速度的。如果要研究Beowulf，需要在硬件上额外投资，这些时我们暂时所不能负担的，所以没有采用Beowulf方案</p>
<p>5.2 MOSIX是什么<br />
MOSIX （The Multicomputer OS for UNIX）在底层实现了进程在处理器之间的迁移，对于用户和程序来说这种迁移的过程是透明的，用户不需要加以干涉（当然也能够干涉）。所有迁移过程都是根据一定的算法自动进行的，可以充分利用CPU和内存资源。尽管MOSIX在文挡重称自己进行负载均衡（load balance）运算，但它不同与其它的load balance（LVS，TurboCluster等），它不能处理象web server或ftp server这样的I/O紧张的程序，MOSIX做的还是超级计算（super computering）方面的工作。它可以同时使很多人在服务器上运行程序，作为一个多用户的分时环境（Multi-user, time sharing environment）,也可以做科学计算（需要用并行通信机制PVM/MPI把程序预先编成可以并行计算的）</p>
<p>关于MOSIX更详细的介绍。在MOSIX网站上有一篇Slide Show “MOSIX Scalable Cluster Computing for Linux” 介绍得很详细。</p>
<p><img border="0" alt="" src="http://www.leeon.me/upload/2010-08/20100820100820_99762.jpg" width="244" height="147" /></p>
<p>MOSIX提供了内核级的接口，相对于内核级接口的是用户级接口。下面是用户级接口的图示：</p>
<p>下面是内核级接口的图示&nbsp;&nbsp;<br />
&nbsp;<img border="0" alt="" src="http://www.leeon.me/upload/2010-08/20100820100852_64816.jpg" width="244" height="150" /><br />
&nbsp;<img border="0" alt="" src="http://www.leeon.me/upload/2010-08/20100820100815_74268.jpg" width="244" height="132" /></p>
<p>比较起来，内核级的优点是对用户来将是透明的。用户不必和各个节点打交道。在用户看来，所有的节点就象一台机器。在MOSIX上运行的进程被分为两部分：</p>
<p>而上面的部分可以在cluster节点中移动，根据当时节点的负载情况。所以，MOSIX可以更有效的使用各节点的CPU资源和内存资源。</p>
<p>5.3 MOSIX与PVM的关系<br />
PVM是Parallel Virtual Machine的缩写。PVM实际上提供了一组API。用这种API，用户可以开发并行应用程序。并行应用程序在运行时会并发的产生多个进程同时执行。这些进程同时在多台机器上运行以缩短整个程序所需的运行时间。</p>
<p>PVM在不需要MOSIX的情况下可以正常执行。但在基于MOSIX的平台上运行PVM。会提高性能。PVM是用来写并行程序并运行，MOSIX是负责各个节点的资源调度。这就是PVM与MOSIX之间的关系</p>
<p>5.4安装MOSIX<br />
MOSIX需要重新编译内核，使内核支持上面提到的进程迁移机制。所以，需要linux内核源代码以及MOSIX补丁。MOSIX提供了安装脚本，根据此安装脚本，用户可以很容易的完成安装过程（当然，在配置内核选项时，用户需要有基本的配置内核的知识）。</p>
<p>一、安装</p>
<p>1. 首先在/tmp下解开MOSIX软件包。</p>
<p>2. 运行安装脚本</p>
<p>cd /tmp</p>
<p>./mosix.install</p>
<p>这个安装脚本将指导下面的安装过程。</p>
<p>3.在配置内核时，有4项要选</p>
<p>CONFIG_MOSIX (YES)</p>
<p>CONFIG_BINFMT_ELF (YES)</p>
<p>CONFIG_PROC_FS (YES)</p>
<p>CONFIG_KMOD (YES)</p>
<p>4.整个安装过程结束，重起系统，就可以配置系统了，MOSIX的自动安装过程中完成了配置过程，它在安装过程中修改了以下文件：</p>
<p>/etc/inittab</p>
<p>/etc/inetd.conf</p>
<p>/etc/lilo.conf</p>
<p>/etc/rc.d/init.d/atd</p>
<p>/etc/cron.daily/slocate.cron</p>
<p>二．节点配置</p>
<p>节点配置是通过修改/etc/mosix.map这个文件来实现的。示例配置文件如下（不跨网段）：</p>
<p># MOSIX CONFIGURATION</p>
<p># ===================</p>
<p>#</p>
<p># Each line should contain 3 fields, mapping IP addresses to MOSIX node-numbers:</p>
<p># 1) first MOSIX node-number in range.</p>
<p># 2) IP address of the above node (or node-name from /etc/hosts).</p>
<p># 3) number of nodes in this range.</p>
<p>#</p>
<p># MOSIX-# IP number-of-nodes</p>
<p># ============================</p>
<p>1 192.168.2.42 1</p>
<p>2 192.168.2.47 1</p>
<p>3 192.168.2.49 1</p>
<p>#或空格开头的是注释。每行配置有3个栏位</p>
<p>1． MOSIX节点号</p>
<p>2． IP地址（必须在/etc/hosts里指定IP-hostname的对应关系）</p>
<p>3． 节点数目</p>
<p>刚才是IP都不连续的的情况，所以节点数目都是1，假如我们有192.168.2.100-192.168.2.200这100台节点，则可以写成</p>
<p>1 192.168.2.100 100</p>
<p>更复杂的配置方法可以参照man mosix。与mosix.map相关的文件有/etc/hosts、/etc/mospe和/etc/mosgates (后两个文件都是在跨网段时会用到，我们目前的配置中不需要)</p>
<p>关于MOSIX的管理，MOSIX基本上不需要人为干涉，但如果用户希望干涉进程的运行状况，MOSIX提供了一套管理程序。MOSIX的管理主要是通过对/proc/mosix/下的文件进行操作来完成的。</p>
<p>5.5安装PVM<br />
PVM的安装不需要修改内核，它只需要普通用户的权限就可以安装。比如用户cluster在3台机器上都有用户，则可以利用这三台机器的资源进行并行计算。安装工作需要在用户的主目录$HOME下进行。经过解包，生成$HOME/pvm3目录；设置一些环境变量；编译，安装就完成了。在PVM设置好以后，就可以用pvm命令进入pvm虚拟机环境。在上面可以运行并行应用程序。也可以不进入虚拟机环境，直接在命令行上提交任务。这些只是PVM的运行环境，PVM的另一部分是其提供的开发环境。在pvm里有c和fortran语言的接口，用户使用这些接口（Interface）用c语言或fortran语言就可以写出并行应用程序然后在pvm运行环境上运行。在其主页上还看到其他的一些语言接口，比如</p>
<p>java，perl，c++</p>
<p>PVM有NT版和UNIX版，由于PVM有虚拟机的概念，所以协同工作的节点可以是NT，linux和其他系统的混合构架，之间只要通过tcp/ip协议连接就可以。（但MOSIX没有NT版的）</p>
<p>6． 结论<br />
以上对服务器群集技术（Server Cluster）做出了简单的介绍。现在正在进行的cluster的项目很多（有遵守GPL公约的，也有商业化的），这些只是cluster中的一小部分。不过这些Cluster方式基本上都是我们目前实际具有的软硬件情况所能够实现的技术。这些技术即具有各自的应用价值，分别适用于Cluster的三个方面，又有各自的不足之处。从这些技术的思路出发，借助自由软件的免费及技术公开的优势，开发出自己的Cluster系统是完全可行的。</p>
<p>&nbsp;</p>
<p>本文来自CSDN博客，转载请标明出处：<a href="http://blog.csdn.net/Mr_JBean/archive/2008/10/08/3033128.aspx">http://blog.csdn.net/Mr_JBean/archive/2008/10/08/3033128.aspx</a></p>	]]></description>
	<guid isPermaLink="false">http://www.leeon.me/feed/108</guid>
  </item>
    <item>
    <title>【转载】高并发web站点MySQL参数优化</title>
    <link>http://www.leeon.me/a/high-concurrency-web-site-for-mysql-optimization</link>
	<pubDate>Tue, 17 Aug 2010 11:56:45 +0800</pubDate>
	<category>数据库</category>
    <description><![CDATA[
	<div class="blog_content">在高访问量的网站下，MySQL自然成为瓶颈。因此MySQL 的优化成为我们需要考虑的问题，第一步自然想到的是 MySQL 系统参数的优化，作为一个访问量很大的网站（日20万人次以上）的数据库系统，不可能指望 MySQL 默认的系统参数能够让 MySQL运行得非常顺畅。 </div>
<div class="blog_content">(1)、back_log： 要求 MySQL 能有的连接数量。当主要MySQL线程在一个很短时间内得到非常多的连接请求，这就起作用，然后主线程花些时间(尽管很短)检查连接并且启动一个新线程。 back_log值指出在MySQL暂时停止回答新请求之前的短时间内多少个请求可以被存在堆栈中。只有如果期望在一个短时间内有很多连接，你需要增加它，换句话说，这值对到来的TCP/IP连接的侦听队列的大小。你的操作系统在这个队列大小上有它自己的限制。 试图设定back_log高于你的操作系统的限制将是无效。 当你观察你的主机进程列表，发现大量 264084 | unauthenticated user | xxx.xxx.xxx.xxx | NULL | Connect | NULL | login | NULL 的待连接进程时，就要加大 back_log的值了。默认数值是50，我把它改为500。</div>
<div class="blog_content">&nbsp;(2)、interactive_timeout： 服务器在关闭它前在一个交互连接上等待行动的秒数。一个交互的客户被定义为对mysql_real_connect()使用 CLIENT_INTERACTIVE 选项的客户。 默认数值是28800，我把它改为7200。 </div>
<div class="blog_content">(3)、key_buffer_size： 索引块是缓冲的并且被所有的线程共享。key_buffer_size是用于索引块的缓冲区大小，增加它可得到更好处理的索引(对所有读和多重写)，到你能负担得起那样多。如果你使它太大，系统将开始换页并且真的变慢了。默认数值是8388600(8M)，我的MySQL主机有2GB内存，所以我把它改为402649088(400MB)。</div>
<div class="blog_content">(4)、max_connections： 允许的同时客户的数量。增加该值增加mysqld 要求的文件描述符的数量。这个数字应该增加，否则，你将经常看到 Too many connections 错误。 默认数值是100，我把它改为1024 。</div>
<div class="blog_content">(5)、record_buffer： 每个进行一个顺序扫描的线程为其扫描的每张表分配这个大小的一个缓冲区。如果你做很多顺序扫描，你可能想要增加该值。默认数值是131072(128K)，我把它改为16773120 (16M) </div>
<div class="blog_content">(6)、sort_buffer： 每个需要进行排序的线程分配该大小的一个缓冲区。增加这值加速ORDER BY或GROUP BY操作。默认数值是2097144(2M)，我把它改为16777208 (16M)。 </div>
<div class="blog_content">(7)、table_cache： 为所有线程打开表的数量。增加该值能增加mysqld要求的文件描述符的数量。MySQL对每个唯一打开的表需要2个文件描述符。默认数值是64，我把它改为512。</div>
<div class="blog_content">(8)、thread_cache_size： 可以复用的保存在中的线程的数量。如果有，新的线程从缓存中取得，当断开连接的时候如果有空间，客户的线置在缓存中。如果有很多新的线程，为了提高性能可以这个变量值。通过比较 Connections 和 Threads_created 状态的变量，可以看到这个变量的作用。我把它设置为 80。</div>
<div class="blog_content">(9)、wait_timeout： 服务器在关闭它之前在一个连接上等待行动的秒数。 默认数值是28800，我把它改为7200。 注：参数的调整可以通过修改/etc/my.cnf 文件并重启 MySQL 实现。这是一个比较谨慎的工作，上面的结果也仅仅是我的一些看法，你可以根据你自己主机的硬件情况（特别是内存大小）进一步修改。 </div>	]]></description>
	<guid isPermaLink="false">http://www.leeon.me/feed/107</guid>
  </item>
    <item>
    <title>【原创】《构建高性能Web站点》读书笔记</title>
    <link>http://www.leeon.me/a/Building-High-Performance-Web-notes</link>
	<pubDate>Sun, 15 Aug 2010 10:39:30 +0800</pubDate>
	<category>其他</category>
    <description><![CDATA[
	<p>Etag Cache-Control Expires Last-Modified 这四者的区别？</p>
<p>答：Ctrl+F5 强制刷新，不使用本地cache，故对上述四者均无效。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; F5 对Etag（If-None-Match）和Last-Modified（If-Modified-Since）有效，会向服务器发起询问文件是否过期，如果没有过期会返回304，如果过期会返回200</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; Expires 只对通过链接跳转和通过地址栏“转到”按钮有效。这样不会像服务器发起询问，只会扫描本地cache并返回给浏览器。<strong>这样速度是最快的</strong>。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; Cache-Control用来记录max-age，这种标记是在HTTP1.1中出现的，用来弥补本地时间和服务器时间的不同导致缓存失效，max-age依据本地时间来进行cache，这样有效的保证了过期时间的确定性</p>
<p>&nbsp;</p>
<p><span style="color:#d6006d;"><strong>sendfile---&gt;直接将文件所在磁盘的特定部分传送给客户端的socket描述符</strong></span></p>
<p><span style="color:#d40a00;">APC --&gt;</span><strong><span style="color:#013add;">opcode缓存：（php.ini：apc.cache_by_default=on</span><span style="color:#013add;">）是php转换后的解释代码直接做cache，这样做</span><span style="color:#013add;">性能非常好。</span></strong></p>
<p><span style="color:#d40a00;">Xcache</span></p>
<p><span style="color:#f10b00;">Xdebug</span>--&gt;WinCacheGrind(一款可以读取xdebug输出的profiler信息的工具)</p>
<p><strong><span style="color:#d40a00;">Apache缓存</span></strong></p>
<p>--&gt;&nbsp;mod_disk_cache&nbsp; 和 mod__mem_cache(官方已放弃，原因为apache多进程模型下共享内存缓存的开销较大) </p>
<p>--&gt;apache缓存可以识别：Last-modified 和expires&nbsp;</p>
<p>&nbsp;--&gt; 可以通过设置：CacheIgnoreHeaders Set-cookie来避免有cookies的页面形成cache。</p>
<p>--&gt;缓存文件描述符，apache可以通过：CacheFile /data/www/index.html 的方式来指定在apache cache中记录文件描述符，提升查找文件的速度。（当文件更新后，必须重启apche才能刷新cache。）</p>
<p>&nbsp;</p>
<p><span style="color:#a44201;"><strong><span style="font-size:16px;"><img border="0" alt="" src="../editor/plugins/emoticons/51.gif" width="24" height="24" />提高web服务和mysql服务在同一台主机上的性能</span></strong></span>：</p>
<p>通常教科书是让我写</p>
<p>[code="php"]<br />
mysql_connect("127.0.0.1","xxxx","xxxx");<br />
[/code]</p>
<p>是的这样的连接方式是在同一台主机上形成tcp连接，但是这样的tcp握手是非常消耗资源的。我们为何不用mysql的另外一种连接方式socket来提升php与mysql的连接性能呢？</p>
<p>PHP手册中有提到socket的连接方式：</p>
<p>[code="php"]<br />
<?php<br />
// we connect to localhost and socket e.g. /tmp/mysql.sock<br />
<br />
//variant 1: ommit localhost<br />
$link = mysql_connect('/tmp/mysql', 'mysql_user', 'mysql_password');<br />
if (!$link) {<br />
die('Could not connect: ' . mysql_error());<br />
}<br />
echo 'Connected successfully';<br />
mysql_close($link);<br />
<br />
<br />
// variant 2: with localhost<br />
$link = mysql_connect('localhost:/tmp/mysql.sock', 'mysql_user', 'mysql_password');<br />
if (!$link) {<br />
die('Could not connect: ' . mysql_error());<br />
}<br />
echo 'Connected successfully';<br />
mysql_close($link);<br />
?&gt; <br />
[/code]</p>
<p><strong><span style="background-color:#6d201b;color:#ffffff;">&nbsp;Note</span><span style="background-color:#6d201b;color:#ffffff;">:</span><span style="background-color:#6d201b;color:#ffffff;">只要将 server 指定为 "localhost" 或 "localhost:port"，MySQL 客户端库会越过此值并尝试连接到本地套接字（Windows 中的名字管道）。如果想用 TCP/IP，应该用 "127.0.0.1" 代替 "localhost"。如果 MySQL 客户端库试图连接到一个错误的本地套接字，则应该在 PHP 配置中设定 </span><span style="background-color:#6d201b;color:#ffffff;">MySQL</span><span style="background-color:#6d201b;color:#ffffff;"> 的正确路径并把 server 留空。 </span></strong></p>
<p>从这里可以知道写成localhost php还是会自动连接套接字，如果写成127.0.0.1的话就用TCP/IP模式连接了</p>
<p>对于静态网页可以从以下几点进行优化：</p>
<p>1. 支持epoll</p>
<p>2. 非阻塞I/O</p>
<p>3. 异步I/O</p>
<p>4. 使用sendfile系统调用</p>
<p>5. 单进程</p>
<p>6. 使用高速磁盘</p>
<p>7. 使用RAID分区</p>
<p>8. 购买足够的带宽</p>
<p>&nbsp;</p>
<p><span style="font-size:18px;"><em>MySQL一些小记：</em></span></p>
<p>innodb_flush_log_at_trx_commit:</p>
<p>0: Innodb 中的Log Thread 每隔1 秒钟会将log buffer中的数据写入到文件，同时还会通知文件系统进行文件同步的flush 操作，保证数据确实已经写入到磁盘上面的物理文件。但是，每次事务的结束（commit 或者是rollback）并不会触发Log Thread 将log buffer 中的数据写入文件。所以，当设置为0 的时候，当MySQL Crash 和OS Crash 或者主机断电之后，最极端的情况是丢失1 秒时间的数据变更。事务提交后不立即将事务写入磁盘，而是每隔一秒写入磁盘一次，并刷新到磁盘，同时更新数据和索引。<span style="color:#d40a00;"><strong>mysql崩溃内存中的事务日志缓冲区最近一秒的数据将会丢失</strong></span>，无法恢复。</p>
<p>1: 这也是Innodb 的默认设置。我们每次事务的结束都会触发Log Thread 将log buffer 中的数据写入文件并通知文件系统同步文件。这个设置是最安全的设置，能够保证不论是MySQL Crash 还是OS Crash 或者是主机断电都不会丢失任何已经提交的数据。</p>
<p>2: 事务提交后立即将事务日志写入磁盘，但是不刷新磁盘，而是每隔一秒刷新到磁盘一次，同时更新数据和索引，<span style="color:#d40a00;"><strong>这种情况下mysql crash后数据是可以恢复的</strong></span>，但是系统挂了就恢复不了最后一秒的数据。</p>
<p><strong><span style="color:#0084a0;">写入磁盘</span></strong>：表示写入物理内存中的内核缓冲区。</p>
<p><strong><span style="color:#0084a0;">刷新磁盘</span></strong>：表示将内核缓冲区的数据真正写入磁盘。</p>
<p>增加mysql线程数量：my.cnf---&gt;thread_cache_size=100 增加到100个线程</p>	]]></description>
	<guid isPermaLink="false">http://www.leeon.me/feed/106</guid>
  </item>
    <item>
    <title>【原创】获取jQuery中Ajax函数的返回值的方法</title>
    <link>http://www.leeon.me/a/how-to-get-ajax-of-jquery-return-value</link>
	<pubDate>Thu, 12 Aug 2010 18:51:41 +0800</pubDate>
	<category>javascript</category>
    <description><![CDATA[
	<p>今天在写jquery的ajax方法的时候想获取回调函数中的返回值，但是怎么也获取不到，因为是jquery的方法中嵌套jquery的方法，导致作用域也不好使变量传递数据。</p>
<p>比如像如下的代码：</p>
<p>[code="js"]<br />
$("talbe&gt;td").each(function(){<br />
.........<br />
$.get('xxxx',function(data){<br />
return xxxxx;<br />
});<br />
.........<br />
});<br />
[/code]</p>
<p>在这种情况下想获取$.get方法中回调函数的return的话就很困难，其实我们可以换种方法来解决这个问题，为何不把data的数据提交到回调函数以外的地方进行处理，这样就会避免内层的数据无法向外层传递。</p>
<p>查看jquery手册发现有一种比较好的解决方案：</p>
<p>[code="js"]<br />
var str = $.ajax({url:xxxx,type:'GET',async:false,cache:false}).responseText;<br />
[/code]</p>
<p>这样就可以通过ajax来获取返回值，注意这里使用了<strong><span style="color:#d40a00;">async:false&nbsp; jQuery中的解释是：</span></strong></p>
<p><span style="color:#d40a00;"><font color="#000000"><u><span style="color:#00a0c2;">&nbsp;默认设置下，所有请求均为异步请求。如果需要发送同步请求，请将此选项设置为 false。注意，同步请求将锁住浏览器，用户其它操作必须等待请求完成才可以执行。</span></u></font></span></p>	]]></description>
	<guid isPermaLink="false">http://www.leeon.me/feed/105</guid>
  </item>
    <item>
    <title>mysql_install_db无法创建var目录</title>
    <link>http://www.leeon.me/a/mysql_install_db-fix-var-solution</link>
	<pubDate>Sun, 08 Aug 2010 21:29:36 +0800</pubDate>
	<category>数据库</category>
    <description><![CDATA[
	<p>今天遇到一个很诡异的事情，编译安装完mysql用mysql_install_db初始化数据库怎么也创建不了var目录，也没有任何报错信息。于是寻求google找到了答案，原来是系统中已经安装了mysql的rpm包，想想上午安装了perl，是不是因为关联的关系也附带安装了mysql的rpm包。导致后续安装mysql源码包后出现了问题。解决方案如下：</p>
<p>[code="plain"]<br />
rpm -qa | grep mysql<br />
[/code]</p>
<p>先查找是否有安装mysql，如果有提示那么卸载mysql</p>
<p>[code="plain"]<br />
rpm -e --nodeps mysql<br />
[/code]</p>
<p>继续进入mysql bin目录执行mysql_install_db ，注意用户权限的问题就行了<img border="0" alt="" src="../editor/plugins/emoticons/0.gif" width="24" height="24" /></p>	]]></description>
	<guid isPermaLink="false">http://www.leeon.me/feed/102</guid>
  </item>
    <item>
    <title>MySQL学习笔记《三》</title>
    <link>http://www.leeon.me/a/mysql-notes-3</link>
	<pubDate>Sun, 08 Aug 2010 12:18:33 +0800</pubDate>
	<category>数据库</category>
    <description><![CDATA[
	<p><span style="color:#d40a00;"><strong><span style="font-size:16px;">MySQL 处理GROUP BY 的方式</span></strong></span>，有两种如下优化思路：<br />
<strong>1.</strong> 尽可能让MySQL 可以利用索引来完成GROUP BY 操作，当然最好是<u><span style="color:#d6006d;"><strong>松散索引</strong></span></u>扫描的方式最佳。在系统允许的情况下，我们可以通过调整索引或者调整Query 这两种方式来达到目的；</p>
<p><br />
<strong>2. </strong>当无法使用索引完成GROUP BY 的时候，由于要使用到临时表且需要filesort，所以我们必须要有足够的<u><strong><span style="color:#ec0078;">sort_buffer_size</span> </strong></u>来供MySQL 排序的时候使用，而且尽量不要进行大结果集的GROUPBY 操作，因为如果超出系统设置的临时表大小的时候会出现将临时表数据copy 到磁盘上面再进行操作，这时候的排序分组操作性能将是成数量级的下降；</p>
<p>&nbsp;</p>
<p><span style="color:#013add;"><strong>DINSTINCT </strong></span>其实和 <strong><span style="color:#013add;">GROUP BY </span></strong>原理类似，同样可以使用松散索引。</p>
<p>&nbsp;</p>
<p><span style="color:#013add;"><strong><span style="font-size:16px;">MySQL Schema </span></strong></span>设计优化小记：</p>
<p>1. 适度冗余</p>
<p>2. 大字段垂直分拆</p>
<p>3. 大表水平分拆</p>
<p>&nbsp;</p>
<p><strong>时间字段</strong>类型：<span style="color:#9ca53b;">timestamp </span>占用4个字节，<span style="color:#9ca53b;">datetime,date</span>占用8个字节，但是timestamp只能用在1970年以后的记录，datetime,date可用在1001年开始。</p>
<p>&nbsp;</p>
<p><span style="color:#d15502;font-size:18px;">MySQL binlog</span>日志优化方案：</p>
<p>Binlog 相关参数及优化策略<br />
我们首先看看Binlog 的相关参数，通过执行如下命令可以获得关于Binlog 的相关参数。当然，其中也显示出了“ innodb_locks_unsafe_for_binlog”这个Innodb 存储引擎特有的与Binlog 相关的参数：<br />
mysql&gt; show variables like '%binlog%';<br />
+--------------------------------+------------+<br />
| Variable_name | Value |<br />
+--------------------------------+------------+<br />
| binlog_cache_size | 1048576 |<br />
| innodb_locks_unsafe_for_binlog | OFF |<br />
| max_binlog_cache_size | 4294967295 |<br />
| max_binlog_size | 1073741824 |<br />
| sync_binlog | 0 |<br />
+--------------------------------+------------+<br />
“binlog_cache_size"：在事务过程中容纳二进制日志SQL 语句的缓存大小。二进制日志缓存是服务器支持事务存储引擎并且服务器启用了二进制日志(—log-bin 选项)的前提下为每个客户端分配的内存，注意，是每个Client 都可以分配设置大小的binlog cache 空间。如果读者朋友的系统中经常会出现多语句事务的华，可以尝试增加该值的大小，以获得更好的性能。当然，我们可以通过MySQL 的以下两个状态变量来判断当前的binlog_cache_size 的状况：Binlog_cache_use 和Binlog_cache_disk_use。“max_binlog_cache_size”：和"binlog_cache_size"相对应，但是所代表的是binlog 能够使用的最大cache 内存大小。当我们执行多语句事务的时候，max_binlog_cache_size 如果不够大的话，系统可能会报出“ Multi-statement transaction required more than 'max_binlog_cache_size' bytes ofstorage”的错误。</p>
<p>“max_binlog_size”：Binlog 日志最大值，一般来说设置为512M 或者1G，但不能超过1G。该大小并不能非常严格控制Binlog 大小，尤其是当到达Binlog 比较靠近尾部而又遇到一个较大事务的时候，系统为了保证事务的完整性，不可能做切换日志的动作，只能将该事务的所有SQL 都记录进入当前日志，直到该事务结束。这一点和Oracle 的Redo 日志有点不一样，因为Oracle 的Redo 日志所记录的是数据文件的物理位置的变化，而且里面同时记录了Redo 和Undo 相关的信息，所以同一个事务是否在一个日志中对Oracle 来说并不关键。而MySQL 在Binlog 中所记录的是数据库逻辑变化信息，MySQL 称之为Event，实际上就是带来数据库变化的DML 之类的Query 语句。“sync_binlog”：这个参数是对于MySQL 系统来说是至关重要的，他不仅影响到Binlog 对MySQL 所带来的性能损耗，而且还影响到MySQL 中数据的完整性。对于“sync_binlog”参数的各种设置的说明如下：<br />
● sync_binlog=0，当事务提交之后，MySQL 不做fsync 之类的磁盘同步指令刷新binlog_cache 中的信息到磁盘，而让Filesystem 自行决定什么时候来做同步，或者cache 满了之后才同步到磁盘。<br />
● sync_binlog=n，当每进行n 次事务提交之后，MySQL 将进行一次fsync 之类的磁盘同步指令来将binlog_cache 中的数据强制写入磁盘。在MySQL 中系统默认的设置是sync_binlog=0，也就是不做任何强制性的磁盘刷新指令，这时候的性能是最好的，但是风险也是最大的。因为一旦系统Crash，在binlog_cache 中的所有binlog 信息都会被丢失。而当设置为“1”的时候，是最安全但是性能损耗最大的设置。因为当设置为1 的时候，即使系统Crash，也最多丢失binlog_cache 中未完成的一个事务，对实际数据没有任何实质性影响。从以往经验和相关测试来看，对于高并发事务的系统来说<span style="color:#ec0078;"><u><strong>，“sync_binlog”设置为0 和设置为1 的系统写入性能差距可能高达5 倍甚至更多</strong></u></span>。</p>
<p>&nbsp;</p>
<p><strong><span style="color:#c001cb;font-size:16px;">MyS</span><span style="color:#c001cb;font-size:16px;">QL </span><span style="color:#c001cb;font-size:16px;">QueryCache </span></strong>负面影响：<br />
a) Query 语句的hash 运算以及hash 查找资源消耗。当我们使用Query Cache 之后，每条SELECT类型的Query 在到达MySQL 之后，都需要进行一个hash 运算然后查找是否存在该Query 的Cache，虽然这个hash 运算的算法可能已经非常高效了，hash 查找的过程也已经足够的优化了，对于一条Query 来说消耗的资源确实是非常非常的少，但是当我们每秒都有上千甚至几千条Query 的时候，我们就不能对产生的CPU 的消耗完全忽视了。<br />
b) Query Cache 的失效问题。如果我们的表变更比较频繁，则会造成Query Cache 的失效率非常高。这里的表变更不仅仅指表中数据的变更，还包括结构或者索引等的任何变更。也就是说我们每次缓存到Query Cache 中的Cache 数据可能在刚存入后很快就会因为表中的数据被改变而被清除，然后新的相同Query 进来之后无法使用到之前的Cache。<br />
c) Query Cache 中缓存的是Result Set ，而不是数据页，也就是说，存在同一条记录被Cache 多次的可能性存在。从而造成内存资源的过渡消耗。当然，可能有人会说我们可以限定QueryCache 的大小啊。是的，我们确实可以限定Query Cache 的大小，但是这样，Query Cache 就很容易造成因为内存不足而被换出，造成命中率的下降。</p>
<p>&nbsp;</p>
<p>在<strong><span style="color:#0021b0;">短连接的应用系统</span></strong>中，<strong><span style="color:#a44201;">thread_cache_size</span></strong> 的值应该设置的相对大一些，不应该小于应用系统对数据库的实际并发请求数。</p>
<p>&nbsp;</p>
<p>通过系统设置和当前状态的分析，我们可以发现，thread_cache_size 的设置已经足够了，甚至还远大于系统的需要。所以我们可以适当减少thread_cache_size 的设置，比如设置为8 或者16。根据Connections 和Threads_created 这两个系统状态值，我们还可以计算出系统新建连接连接的ThreadCache 命中率，也就是通过Thread Cache 池中取得连接线程的次数与系统接收的总连接次数的比率，如下：<br />
<span style="color:#0021b0;">Threads_Cache_Hit = (Connections - Threads_created) / Connections * 100%</span></p>
<p>一般来说，当系统稳定运行一段时间之后，我们的Thread Cache 命中率应该保持在<strong><u><span style="color:#f10b00;">90%左右甚至更</span><span style="color:#f10b00;">高的比率才算正常</span></u></strong>。可以看出上面环境中的Thread Cache 命中比率基本还算是正常的。</p>
<p>&nbsp;</p>
<p>如何查看MySQL打开Table的数量：</p>
<p>mysql&gt; show status like 'open_tables';<br />
+---------------+-------+<br />
| Variable_name | Value |<br />
+---------------+-------+<br />
| Open_tables | 6 |<br />
+---------------+-------+</p>
<p>&nbsp;</p>
<p>MySQL buffer注意事项</p>
<p><strong>join_buffer_size</strong> 和 <strong>sort_buffer_size</strong> 是针对的每个线程的buffer大小而言的，而不是整个系统共享的Buffer。</p>
<p>&nbsp;</p>
<p>假设是一台单独给MySQL 使用的主机，物理内存总大小为8G，MySQL 最大连接数为500，同时还使用了MyISAM 存储引擎，这时候我们的整体内存该如何分配呢？<br />
内存分配为如下几大部分：<br />
a) 系统使用，假设预留800M；<br />
b) 线程独享，约2GB = 500 * (1MB + 1MB + 1MB + 512KB + 512KB)，组成大概如下:<br />
sort_buffer_size：1MB<br />
join_buffer_size：1MB<br />
read_buffer_size：1MB<br />
read_rnd_buffer_size：512KB<br />
thread_statck：512KB<br />
c) MyISAM Key Cache，假设大概为1.5GB；<br />
d) Innodb Buffer Pool 最大可用量：8GB - 800MB - 2GB - 1.5GB = 3.7GB；</p>	]]></description>
	<guid isPermaLink="false">http://www.leeon.me/feed/101</guid>
  </item>
  </channel>


</rss>