<?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>idv2 &#187; linux</title>
	<atom:link href="http://tech.idv2.com/tag/linux/feed/" rel="self" type="application/rss+xml" />
	<link>http://tech.idv2.com</link>
	<description>关注Web开发技术，关注Internet。</description>
	<lastBuildDate>Tue, 27 Jul 2010 12:54:54 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Xming：好用的Xserver</title>
		<link>http://tech.idv2.com/2009/09/28/xming-good-xserver/</link>
		<comments>http://tech.idv2.com/2009/09/28/xming-good-xserver/#comments</comments>
		<pubDate>Sun, 27 Sep 2009 16:29:16 +0000</pubDate>
		<dc:creator>charlee</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[xserver]]></category>

		<guid isPermaLink="false">http://tech.idv2.com/2009/09/28/xming-good-xserver/</guid>
		<description><![CDATA[<!-- begin Pukiwiki generated code--><p>以前一直用的是<a href="http://www.jcraft.com/weirdx/">weirdX</a>，一个纯Java写成的Xserver。功能还不错，
只是有些程序运行之后会报告无法连接Xserver的情况。不过前两天zz介绍了一款名为<a href="http://sourceforge.net/projects/xming/">Xming</a>的Xserver，
速度要比weirdX快一些，而且没遇到不兼容的程序，可以说是相当完美了。</p>
<p>下载后直接安装运行就可以了。xhost怎么设置？打开程序文件夹，里面有一个X0.hosts文件，其内容就是允许连接的主机，每行一个地址，
把程序所在的主机连接上即可。运行程序时只需先 export DISPLAY=IP地址:0.0 就行了。</p>
<p>有些gtk程序中的汉字会乱码（显示成方块），只需去<a href="http://sourceforge.net/projects/xming/">Xming的主页</a>下载字体包，装上即可。</p>
<!-- end Pukiwiki generated code-->]]></description>
			<content:encoded><![CDATA[<!-- begin Pukiwiki generated code--><p>以前一直用的是<a href="http://www.jcraft.com/weirdx/">weirdX</a>，一个纯Java写成的Xserver。功能还不错，
只是有些程序运行之后会报告无法连接Xserver的情况。不过前两天zz介绍了一款名为<a href="http://sourceforge.net/projects/xming/">Xming</a>的Xserver，
速度要比weirdX快一些，而且没遇到不兼容的程序，可以说是相当完美了。</p>
<p>下载后直接安装运行就可以了。xhost怎么设置？打开程序文件夹，里面有一个X0.hosts文件，其内容就是允许连接的主机，每行一个地址，
把程序所在的主机连接上即可。运行程序时只需先 export DISPLAY=IP地址:0.0 就行了。</p>
<p>有些gtk程序中的汉字会乱码（显示成方块），只需去<a href="http://sourceforge.net/projects/xming/">Xming的主页</a>下载字体包，装上即可。</p>
<!-- end Pukiwiki generated code-->]]></content:encoded>
			<wfw:commentRss>http://tech.idv2.com/2009/09/28/xming-good-xserver/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SuSE Linux安装死机</title>
		<link>http://tech.idv2.com/2009/09/23/suse-linux-install-freeze/</link>
		<comments>http://tech.idv2.com/2009/09/23/suse-linux-install-freeze/#comments</comments>
		<pubDate>Wed, 23 Sep 2009 07:09:53 +0000</pubDate>
		<dc:creator>charlee</dc:creator>
				<category><![CDATA[hardware]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[suse]]></category>

		<guid isPermaLink="false">http://tech.idv2.com/2009/09/23/suse-linux%e5%ae%89%e8%a3%85%e6%ad%bb%e6%9c%ba/</guid>
		<description><![CDATA[硬件环境：NEC Express 5800工作站 51Le
软件：SuSE Enterprise Linux Desktop 10 SP1
故障现象：从DVD启动之后选择安装Linux，片刻后出现SuSE的安装界面，第一步选择安装程序语言时，键盘、鼠标均无反应，键盘的Capslock灯也失效。
初步分析可能是由于SuSE 10不支持SATA硬盘的缘故，于是进入BIOS设置将SATA#1的模式由Enhanced改成了Compatible，结果启动时BIOS根本找不到硬盘。在网上查了查，有人说换成USB键盘鼠标就好了，抱着试试看的态度找了套USB的键盘鼠标换上，没想到真的好了。
太不可思议了，由于键盘鼠标而导致系统无法安装，这事儿还是第一次听说。
]]></description>
			<content:encoded><![CDATA[<p>硬件环境：NEC Express 5800工作站 51Le<br />
软件：SuSE Enterprise Linux Desktop 10 SP1<br />
故障现象：从DVD启动之后选择安装Linux，片刻后出现SuSE的安装界面，第一步选择安装程序语言时，键盘、鼠标均无反应，键盘的Capslock灯也失效。</p>
<p>初步分析可能是由于SuSE 10不支持SATA硬盘的缘故，于是进入BIOS设置将SATA#1的模式由Enhanced改成了Compatible，结果启动时BIOS根本找不到硬盘。在网上查了查，有人说换成USB键盘鼠标就好了，抱着试试看的态度找了套USB的键盘鼠标换上，没想到真的好了。</p>
<p>太不可思议了，由于键盘鼠标而导致系统无法安装，这事儿还是第一次听说。</p>
]]></content:encoded>
			<wfw:commentRss>http://tech.idv2.com/2009/09/23/suse-linux-install-freeze/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>利用gettext做软件翻译</title>
		<link>http://tech.idv2.com/2009/07/08/translate-with-gettext/</link>
		<comments>http://tech.idv2.com/2009/07/08/translate-with-gettext/#comments</comments>
		<pubDate>Wed, 08 Jul 2009 03:25:14 +0000</pubDate>
		<dc:creator>charlee</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[gettext]]></category>
		<category><![CDATA[i18n]]></category>

		<guid isPermaLink="false">http://tech.idv2.com/2009/07/08/translate-with-gettext/</guid>
		<description><![CDATA[<!-- begin Pukiwiki generated code--><p>很多软件都支持gettext，比如WordPress、ZenPhoto等。那么要想做个语言包，就得用到gettext这个工具。以ZenPhoto为例，使用方法如下：</p>
<p>首先要找出所有需要翻译的文件：</p>
<pre>$ cd zenphoto
$ find . -name &quot;*.php&quot; &gt; filelist.txt</pre>
<p>然后从所有需要翻译的文件中提取出英文字符串。</p>
<pre>$ xgettext --from-code utf-8 -f filelist.txt -d zenphoto</pre>
<p>这样，xgettext命令就会分析所有文件，找出其中需要翻译的字符串（即php中调用gettext所用的字符串）并输出到zenphoto.po中。--from-code参数指定源代码的编码格式。ZenPhoto的源代码中，gettext函数参数中含有一些UTF-8的字符（实际上应该没有），如果不指定这个参数，xgettext就无法正确识别这些UTF-8字符。-f 指定要分析的文件列表。-d指明输出文件的名称，扩展名为.po。</p>
<p>然后创建语言文件夹，把.po文件放进去。ZenPhoto的话，操作方法如下（当前目录为zenphoto根目录）：</p>
<pre>$ mkdir -p locale/zh-CN/LC_MESSAGES
$ mv zenphoto.po locale/zh-CN/LC_MESSAGES
$ cd locale/zh-CN/LC_MESSAGES</pre>
<p>接下来翻译zenphoto.po文件就行了。</p>
<p>翻译完成后，执行如下命令将.po文件编译成.mo文件：</p>
<pre>$ msgfmt -o zenphoto.mo zenphoto.po</pre>
<p>然后重启httpd就能看到翻译的效果。</p>
<p>忘了说了，如果系统上没有xgettext和msgfmt命令，只需安装gettext包即可。</p>
<!-- end Pukiwiki generated code-->]]></description>
			<content:encoded><![CDATA[<!-- begin Pukiwiki generated code--><p>很多软件都支持gettext，比如WordPress、ZenPhoto等。那么要想做个语言包，就得用到gettext这个工具。以ZenPhoto为例，使用方法如下：</p>
<p>首先要找出所有需要翻译的文件：</p>
<pre>$ cd zenphoto
$ find . -name &quot;*.php&quot; &gt; filelist.txt</pre>
<p>然后从所有需要翻译的文件中提取出英文字符串。</p>
<pre>$ xgettext --from-code utf-8 -f filelist.txt -d zenphoto</pre>
<p>这样，xgettext命令就会分析所有文件，找出其中需要翻译的字符串（即php中调用gettext所用的字符串）并输出到zenphoto.po中。--from-code参数指定源代码的编码格式。ZenPhoto的源代码中，gettext函数参数中含有一些UTF-8的字符（实际上应该没有），如果不指定这个参数，xgettext就无法正确识别这些UTF-8字符。-f 指定要分析的文件列表。-d指明输出文件的名称，扩展名为.po。</p>
<p>然后创建语言文件夹，把.po文件放进去。ZenPhoto的话，操作方法如下（当前目录为zenphoto根目录）：</p>
<pre>$ mkdir -p locale/zh-CN/LC_MESSAGES
$ mv zenphoto.po locale/zh-CN/LC_MESSAGES
$ cd locale/zh-CN/LC_MESSAGES</pre>
<p>接下来翻译zenphoto.po文件就行了。</p>
<p>翻译完成后，执行如下命令将.po文件编译成.mo文件：</p>
<pre>$ msgfmt -o zenphoto.mo zenphoto.po</pre>
<p>然后重启httpd就能看到翻译的效果。</p>
<p>忘了说了，如果系统上没有xgettext和msgfmt命令，只需安装gettext包即可。</p>
<!-- end Pukiwiki generated code-->]]></content:encoded>
			<wfw:commentRss>http://tech.idv2.com/2009/07/08/translate-with-gettext/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>diff命令的好用功能</title>
		<link>http://tech.idv2.com/2009/02/21/gnu-diff-tips/</link>
		<comments>http://tech.idv2.com/2009/02/21/gnu-diff-tips/#comments</comments>
		<pubDate>Sat, 21 Feb 2009 15:57:54 +0000</pubDate>
		<dc:creator>charlee</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[diff]]></category>

		<guid isPermaLink="false">http://tech.idv2.com/2009/02/21/gnu-diff-tips/</guid>
		<description><![CDATA[<!-- begin Pukiwiki generated code--><p>GNU diff有很多功能平时我们不常用到，但若知道，在急需时还真能派得上用场。</p>
<p>最常用的功能莫过于生成patch文件了：</p>
<pre>diff -urN old/ new/ &gt; mysoft.patch</pre>
<p>参数 -u 表示使用 unified 格式，-r 表示比较目录，-N 表示将不存在的文件当作空文件处理，
这样新添加的文件也会出现在patch文件中。</p>
<p>然后在需要应用patch的地方使用下述命令即可：</p>
<pre>patch -p0 &lt; mysoft.patch</pre>
<p>diff的 -y 命令（长格式为 --side-by-side）可以将屏幕分成左右两部分，来比较两个文件之间的差异。
许多图形化的比较工具都有这个功能，但如果只能使用命令行，这个参数就相当有用了。
如果要改变左右各部分的宽度，可以通过 -W （--width）参数来指定。
（这条技巧来自于<a href="http://0xcc.net/blog/archives/000208.html">bkブログ</a>，谢谢）</p>
<p>此外，--strip-trailing-cr 参数可以去除行尾的换行，这样DOS格式和Unix格式的文件互相比较时，
就不至于因为换行符不一致而出现大量的差异。</p>
<!-- end Pukiwiki generated code-->]]></description>
			<content:encoded><![CDATA[<!-- begin Pukiwiki generated code--><p>GNU diff有很多功能平时我们不常用到，但若知道，在急需时还真能派得上用场。</p>
<p>最常用的功能莫过于生成patch文件了：</p>
<pre>diff -urN old/ new/ &gt; mysoft.patch</pre>
<p>参数 -u 表示使用 unified 格式，-r 表示比较目录，-N 表示将不存在的文件当作空文件处理，
这样新添加的文件也会出现在patch文件中。</p>
<p>然后在需要应用patch的地方使用下述命令即可：</p>
<pre>patch -p0 &lt; mysoft.patch</pre>
<p>diff的 -y 命令（长格式为 --side-by-side）可以将屏幕分成左右两部分，来比较两个文件之间的差异。
许多图形化的比较工具都有这个功能，但如果只能使用命令行，这个参数就相当有用了。
如果要改变左右各部分的宽度，可以通过 -W （--width）参数来指定。
（这条技巧来自于<a href="http://0xcc.net/blog/archives/000208.html">bkブログ</a>，谢谢）</p>
<p>此外，--strip-trailing-cr 参数可以去除行尾的换行，这样DOS格式和Unix格式的文件互相比较时，
就不至于因为换行符不一致而出现大量的差异。</p>
<!-- end Pukiwiki generated code-->]]></content:encoded>
			<wfw:commentRss>http://tech.idv2.com/2009/02/21/gnu-diff-tips/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>OpenNMS配置笔记</title>
		<link>http://tech.idv2.com/2009/01/13/opennms-install-memo/</link>
		<comments>http://tech.idv2.com/2009/01/13/opennms-install-memo/#comments</comments>
		<pubDate>Mon, 12 Jan 2009 16:29:44 +0000</pubDate>
		<dc:creator>charlee</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[network]]></category>
		<category><![CDATA[opennms]]></category>
		<category><![CDATA[snmp]]></category>

		<guid isPermaLink="false">http://tech.idv2.com/2009/01/13/opennms-install-memo/</guid>
		<description><![CDATA[<!-- begin Pukiwiki generated code--><p><a href="http://www.opennms.org/">OpenNMS</a>是个很强大的网管软件，用它可以监视服务器的资源使用状况，
并在必要的时候向管理员发出警告。（当然它的强大功能不止这些，我就用到这个功能而已）。
安装其实也不麻烦，基本上按照<a href="http://www.opennms.org/index.php/Installation:Yum">官方文档的安装过程</a>都没问题。</p>
<p>网上流传的方法都是将OpenNMS装在Tomcat上，不过最新版的opennms-1.6.1内置了Web服务器，
所以Tomcat就不是必须的了，这样安装要方便许多。
下面这篇文章是在Redhat Liux Enterprise 4上安装的，其实RH系列的操作系统都差不多，
大家在安装时注意选择和操作系统匹配的软件包就行了。</p>
<!-- end Pukiwiki generated code--><span id="more-670"></span><!-- begin Pukiwiki generated code--><div class="contents">
<a id="contents_8"></a>
<ul class="list1" style="padding-left:16px;margin-left:16px"><li><a href="#content_8_0">  下载</a></li>
<li><a href="#content_8_1">  安装PostgreSQL</a></li>
<li><a href="#content_8_2">  安装JDK</a></li>
<li><a href="#content_8_3">  安装OpenNMS</a></li>
<li><a href="#content_8_4">  配置OpenNMS</a></li>
<li><a href="#content_8_5">  配置被监视的服务器</a></li>
<li><a href="#content_8_6">  在OpenNMS中添加节点</a></li></ul>
</div>

<hr class="full_hr" />
<h2 id="content_8_0">下载</h2>
<p>由于局域网中不能使用yum，所以必须手动下载需要的安装包。
安装OpenNMS需要以下软件：</p>
<ul class="list1" style="padding-left:16px;margin-left:16px"><li>PostgreSQL：Linux自带</li>
<li>OpenNMS：从<a href="http://www.opennms.org/index.php/New_and_Noteworthy">下载页面</a> 选择binaries下载。</li>
<li>jicmp和iplike，从<a href="http://yum.opennms.org/">OpenNMS的yum页面</a>可以下载。</li>
<li>JDK，从<a href="http://java.sun.com/javase/downloads/index.jsp">Sun的下载页面</a>上下载。</li></ul>

<h2 id="content_8_1">安装PostgreSQL</h2>
<p>首先安装PostgreSQL：</p>
<pre># rpm -i postgresql-7.4.8-1.RHEL4.1.i386.rpm
# rpm -i postgresql-server-7.4.8-1.RHEL4.1.i386.rpm
# chkconfig postgresql on
# /etc/init.d/postgresql start</pre>
<p>然后要编辑配置文件 /var/lib/pgsql/data/pg_hba.cof 中权限相关的部分：</p>
<p>把下面这一行：</p>
<pre>local  all    all             ident   sameuser</pre>
<p>改成这样：</p>
<pre>local  all    all             trust
host    all         all         127.0.0.1/32          trust
host    all         all         ::1/128               trust</pre>
<p>然后需要编辑 /var/lib/pgsql/data/postgresql.conf，让它监听TCP。我用的是RHEL4的postgresql-7.4.8，
修改方法如下：</p>
<pre>#tcpip_socket = false</pre>
<p>改成</p>
<pre>tcpip_socket = true</pre>
<p>如果是较新的服务器，那应该是默认监听TCP的，如果不行，就要在 postgresql.conf 中加入这样一行：</p>
<pre>listen_addresses = 'localhost'</pre>
<p>然后重启一下服务器：</p>
<pre>/etc/init.d/postgresql restart</pre>
<p>确认一下postgresql是否启动成功：</p>
<pre># netstat -lntp
...(中略)
tcp   0   0 0.0.0.0:5432     0.0.0.0:*   LISTEN   28603/postmaster  # 有这一行即可</pre>
<p>最后要创建OpenNMS的数据库：</p>
<pre># sudo -u postgres createdb -U postgres -E UNICODE opennms
CREATE DATABASE</pre>

<h2 id="content_8_2">安装JDK</h2>
<p>我从Sun的网站上下载了rpm版的JDK 6 Update 11。安装很简单：</p>
<pre># ./jdk-6u11-linux-i586-rpm.bin</pre>

<h2 id="content_8_3">安装OpenNMS</h2>
<p>安装OpenNMS需要以下几个包：</p>
<ul class="list1" style="padding-left:16px;margin-left:16px"><li>opennms-1.6.1-1.noarch.rpm：为yum准备的快捷包，不装也行</li>
<li>opennms-core-1.6.1-1.noarch.rpm：OpenNMS的核心</li>
<li>opennms-docs-1.6.1-1.noarch.rpm：OpenNMS的文档</li>
<li>opennms-webapp-jetty-1.6.1-1.noarch.rpm：OpenNMS自带的Web服务器</li></ul>
<p>还有依赖关系：</p>
<ul class="list1" style="padding-left:16px;margin-left:16px"><li>jicmp-1.0.7-1.i386.rpm：注意这个包，不同系统上的安装包是不一样的</li>
<li>iplike-1.0.7-1.i366.rpm：注意这个包，不同系统上的安装包是不一样的</li></ul>
<p>如果你要与Tomcat配合使用，可以选择安装opennms-webapp-standalone-1.6.1-1.noarch.rpm，这里就不介绍了。</p>
<p>按照顺序分别安装以上几个包：</p>
<pre># rpm -i jicmp-1.0.7-1.i386.rpm
# rpm -i opennms-core-1.6.1-1.noarch.rpm
# rpm -i opennms-webapp-jetty-1.6.1-1.noarch.rpm
# rpm -i opennms-docs-1.6.1-1.noarch.rpm
# rpm -i opennms-1.6.1-1.noarch.rpm</pre>
<p>安装iplike：</p>
<pre># rpm -i iplike-1.0.7-1.i386.rpm</pre>
<p>安装过程中会创建存储过程，如果失败的话，可以在排除原因之后执行 /usr/sbin/install_iplike.sh 。</p>

<h2 id="content_8_4">配置OpenNMS</h2>
<p>首先设置一个环境变量，指向OpenNMS的安装位置，便于以后的输入：</p>
<pre>export OPENNMS_HOME=/opt/opennms</pre>
<p>告诉OpenNMS使用新安装的JDK。注意这一步一定要指定你上面刚刚安装的JDK。
系统中有可能自带了JRE的java解释器，那个不行，要用JDK的。</p>
<pre># $OPENNMS_HOME/bin/runjava -S /usr/java/latest/bin/java</pre>
<p>然后安装OpenNMS的数据库：</p>
<pre># $OPENNMS_HOME/bin/install -dis</pre>
<p>最后启动OpenNMS：</p>
<pre># chkconfig --add opennms
# /etc/init.d/opennms start</pre>
<p>然后打开浏览器，访问 http://&lt;your_ip_address&gt;:8980/opennms/ ，用户名admin密码admin，登录就行了。</p>

<h2 id="content_8_5">配置被监视的服务器</h2>
<p>要监视服务器的运行状态，应该在要监视的服务器上安装SNMP。如果是Linux系统，那么可以使用自带的net-snmp包。</p>
<pre># rpm -i net-snmp-libs-5.1.2-11.EL4.6.i386.rpm
# rpm -i net-snmp-5.1.2-11.EL4.6.i386.rpm
# rpm -i net-snmp-utils-5.1.2-11.EL4.6.i386.rpm
# chkconfig snmpd on
# /etc/init.d/snmpd start</pre>
<p>然后修改 /etc/snmp/snmpd.conf 。该文件主要由四个指令构成：</p>
<div class="ie5"><table class="style_table" cellspacing="1" border="0"><tbody><tr><td class="style_td">com2sec</td><td class="style_td">定义一个安全策略。community的作用类似于密码。</td></tr><tr><td class="style_td">group</td><td class="style_td">将安全策略映射到组。securityModel指SNMP版本号，可以选择v1、v2c或v3。</td></tr><tr><td class="style_td">view</td><td class="style_td">定义一个视图，规定视图中包括的内容。</td></tr><tr><td class="style_td">access</td><td class="style_td">定义哪个组可以访问哪个视图，以及访问权限。</td></tr></tbody></table></div>
<p>view中的一长串数字 .1.3.6.1.2.1.1 是MIB结点名称(OID)，由RFC1065/1155定义。
用snmptranlsate工具可以看到数字的意义：</p>
<pre># snmptranslate .1.3.6.1.2.1.1
SNMPv2-MIB::system</pre>
<p>我们可以让SNMP返回更多的信息（由于是局域网，所以就不考虑安全性问题了）。
按照以下方式修改snmpd.conf，同时注释掉原有内容：</p>
<pre>com2sec opennms   192.168.1.100/32    opennms    # 最后一个字段为community名称
group   opennmsGroup    v1           opennms
view    view_all      included   .1
access  opennmsGroup   &quot;&quot;      any       noauth    exact  view_all none none</pre>
<p>另外syslocation和syscontact指令是用来记录服务器所在物理位置和管理员联系地址的，适当填写即可。</p>
<p>最后重启SNMP：</p>
<pre># /etc/init.d/snmpd restart</pre>
<p>用snmpwalk工具检查配置是否正确，正确的话应该会输出很多信息：</p>
<pre># snmpwalk -c opennms -v 1 192.168.1.100</pre>
<p>最后将每台要监视的服务器都按照上述方法配置即可。</p>

<h2 id="content_8_6">在OpenNMS中添加节点</h2>
<p>登录到OpenNMS中，点击Admincaidan，然后点击左侧Operations中的Configure Discovery。
在Specifics表格中将要监视的服务器的IP地址填进去。如果要监视大范围的服务器，
可以在下面的Include Ranges中指定IP地址的范围。
最后点击“Save and Restart Discovery”，重新开始搜索节点。</p>
<div class="img_margin" style="text-align:left"><img src="http://tech.idv2.com/wp-content/uploads/2009/01/opennms-add-discovery.png" alt="opennms-add-discovery.png" title="opennms-add-discovery.png" width="644" height="486" /></div>

<p>稍等几分钟，再点击Node List菜单，即可看到刚刚添加的服务器。</p>
<div class="img_margin" style="text-align:left"><img src="http://tech.idv2.com/wp-content/uploads/2009/01/opennms-node-without-snmp.png" alt="opennms-node-without-snmp.png" title="opennms-node-without-snmp.png" width="624" height="423" /></div>

<p>但是现在在服务器状态中还看不到SNMP信息，因为我们还没设置SNMP的community名称——
刚才说过，community名称相当于密码。</p>
<p>点击Admin菜单，然后选择左侧的Configure SNMP Community Names by IP命令。
然后输入IP地址，以及刚才在snmpd.conf中使用的community名称，
版本号也要与snmpd.conf的group指令中设置的一致，最后点击Submit。</p>
<p>接下来回到Node List，进入要监视的服务器的状态页面，点击上方菜单中的Rescan。
等待一分钟左右再刷新页面，就可以看到SNMP状态信息了。（由于有了SNMP的帮助，
你会发现状态页面的信息一下子多了许多。）</p>
<div class="img_margin" style="text-align:left"><img src="http://tech.idv2.com/wp-content/uploads/2009/01/opennms-node-with-snmp.png" alt="opennms-node-with-snmp.png" title="opennms-node-with-snmp.png" width="629" height="460" /></div>

<p>这样，我们可以通过点击上方的Resource Graphs即可看到服务器运行状态的图表。</p>
<div class="img_margin" style="text-align:left"><img src="http://tech.idv2.com/wp-content/uploads/2009/01/opennms-memory-stats.png" alt="opennms-memory-stats.png" title="opennms-memory-stats.png" width="656" height="351" /></div>

<!-- end Pukiwiki generated code-->
]]></description>
			<content:encoded><![CDATA[<!-- begin Pukiwiki generated code--><p><a href="http://www.opennms.org/">OpenNMS</a>是个很强大的网管软件，用它可以监视服务器的资源使用状况，
并在必要的时候向管理员发出警告。（当然它的强大功能不止这些，我就用到这个功能而已）。
安装其实也不麻烦，基本上按照<a href="http://www.opennms.org/index.php/Installation:Yum">官方文档的安装过程</a>都没问题。</p>
<p>网上流传的方法都是将OpenNMS装在Tomcat上，不过最新版的opennms-1.6.1内置了Web服务器，
所以Tomcat就不是必须的了，这样安装要方便许多。
下面这篇文章是在Redhat Liux Enterprise 4上安装的，其实RH系列的操作系统都差不多，
大家在安装时注意选择和操作系统匹配的软件包就行了。</p>
<!-- end Pukiwiki generated code--><span id="more-670"></span><!-- begin Pukiwiki generated code--><div class="contents">
<a id="contents_10"></a>
<ul class="list1" style="padding-left:16px;margin-left:16px"><li><a href="#content_10_0">  下载</a></li>
<li><a href="#content_10_1">  安装PostgreSQL</a></li>
<li><a href="#content_10_2">  安装JDK</a></li>
<li><a href="#content_10_3">  安装OpenNMS</a></li>
<li><a href="#content_10_4">  配置OpenNMS</a></li>
<li><a href="#content_10_5">  配置被监视的服务器</a></li>
<li><a href="#content_10_6">  在OpenNMS中添加节点</a></li></ul>
</div>

<hr class="full_hr" />
<h2 id="content_10_0">下载</h2>
<p>由于局域网中不能使用yum，所以必须手动下载需要的安装包。
安装OpenNMS需要以下软件：</p>
<ul class="list1" style="padding-left:16px;margin-left:16px"><li>PostgreSQL：Linux自带</li>
<li>OpenNMS：从<a href="http://www.opennms.org/index.php/New_and_Noteworthy">下载页面</a> 选择binaries下载。</li>
<li>jicmp和iplike，从<a href="http://yum.opennms.org/">OpenNMS的yum页面</a>可以下载。</li>
<li>JDK，从<a href="http://java.sun.com/javase/downloads/index.jsp">Sun的下载页面</a>上下载。</li></ul>

<h2 id="content_10_1">安装PostgreSQL</h2>
<p>首先安装PostgreSQL：</p>
<pre># rpm -i postgresql-7.4.8-1.RHEL4.1.i386.rpm
# rpm -i postgresql-server-7.4.8-1.RHEL4.1.i386.rpm
# chkconfig postgresql on
# /etc/init.d/postgresql start</pre>
<p>然后要编辑配置文件 /var/lib/pgsql/data/pg_hba.cof 中权限相关的部分：</p>
<p>把下面这一行：</p>
<pre>local  all    all             ident   sameuser</pre>
<p>改成这样：</p>
<pre>local  all    all             trust
host    all         all         127.0.0.1/32          trust
host    all         all         ::1/128               trust</pre>
<p>然后需要编辑 /var/lib/pgsql/data/postgresql.conf，让它监听TCP。我用的是RHEL4的postgresql-7.4.8，
修改方法如下：</p>
<pre>#tcpip_socket = false</pre>
<p>改成</p>
<pre>tcpip_socket = true</pre>
<p>如果是较新的服务器，那应该是默认监听TCP的，如果不行，就要在 postgresql.conf 中加入这样一行：</p>
<pre>listen_addresses = 'localhost'</pre>
<p>然后重启一下服务器：</p>
<pre>/etc/init.d/postgresql restart</pre>
<p>确认一下postgresql是否启动成功：</p>
<pre># netstat -lntp
...(中略)
tcp   0   0 0.0.0.0:5432     0.0.0.0:*   LISTEN   28603/postmaster  # 有这一行即可</pre>
<p>最后要创建OpenNMS的数据库：</p>
<pre># sudo -u postgres createdb -U postgres -E UNICODE opennms
CREATE DATABASE</pre>

<h2 id="content_10_2">安装JDK</h2>
<p>我从Sun的网站上下载了rpm版的JDK 6 Update 11。安装很简单：</p>
<pre># ./jdk-6u11-linux-i586-rpm.bin</pre>

<h2 id="content_10_3">安装OpenNMS</h2>
<p>安装OpenNMS需要以下几个包：</p>
<ul class="list1" style="padding-left:16px;margin-left:16px"><li>opennms-1.6.1-1.noarch.rpm：为yum准备的快捷包，不装也行</li>
<li>opennms-core-1.6.1-1.noarch.rpm：OpenNMS的核心</li>
<li>opennms-docs-1.6.1-1.noarch.rpm：OpenNMS的文档</li>
<li>opennms-webapp-jetty-1.6.1-1.noarch.rpm：OpenNMS自带的Web服务器</li></ul>
<p>还有依赖关系：</p>
<ul class="list1" style="padding-left:16px;margin-left:16px"><li>jicmp-1.0.7-1.i386.rpm：注意这个包，不同系统上的安装包是不一样的</li>
<li>iplike-1.0.7-1.i366.rpm：注意这个包，不同系统上的安装包是不一样的</li></ul>
<p>如果你要与Tomcat配合使用，可以选择安装opennms-webapp-standalone-1.6.1-1.noarch.rpm，这里就不介绍了。</p>
<p>按照顺序分别安装以上几个包：</p>
<pre># rpm -i jicmp-1.0.7-1.i386.rpm
# rpm -i opennms-core-1.6.1-1.noarch.rpm
# rpm -i opennms-webapp-jetty-1.6.1-1.noarch.rpm
# rpm -i opennms-docs-1.6.1-1.noarch.rpm
# rpm -i opennms-1.6.1-1.noarch.rpm</pre>
<p>安装iplike：</p>
<pre># rpm -i iplike-1.0.7-1.i386.rpm</pre>
<p>安装过程中会创建存储过程，如果失败的话，可以在排除原因之后执行 /usr/sbin/install_iplike.sh 。</p>

<h2 id="content_10_4">配置OpenNMS</h2>
<p>首先设置一个环境变量，指向OpenNMS的安装位置，便于以后的输入：</p>
<pre>export OPENNMS_HOME=/opt/opennms</pre>
<p>告诉OpenNMS使用新安装的JDK。注意这一步一定要指定你上面刚刚安装的JDK。
系统中有可能自带了JRE的java解释器，那个不行，要用JDK的。</p>
<pre># $OPENNMS_HOME/bin/runjava -S /usr/java/latest/bin/java</pre>
<p>然后安装OpenNMS的数据库：</p>
<pre># $OPENNMS_HOME/bin/install -dis</pre>
<p>最后启动OpenNMS：</p>
<pre># chkconfig --add opennms
# /etc/init.d/opennms start</pre>
<p>然后打开浏览器，访问 http://&lt;your_ip_address&gt;:8980/opennms/ ，用户名admin密码admin，登录就行了。</p>

<h2 id="content_10_5">配置被监视的服务器</h2>
<p>要监视服务器的运行状态，应该在要监视的服务器上安装SNMP。如果是Linux系统，那么可以使用自带的net-snmp包。</p>
<pre># rpm -i net-snmp-libs-5.1.2-11.EL4.6.i386.rpm
# rpm -i net-snmp-5.1.2-11.EL4.6.i386.rpm
# rpm -i net-snmp-utils-5.1.2-11.EL4.6.i386.rpm
# chkconfig snmpd on
# /etc/init.d/snmpd start</pre>
<p>然后修改 /etc/snmp/snmpd.conf 。该文件主要由四个指令构成：</p>
<div class="ie5"><table class="style_table" cellspacing="1" border="0"><tbody><tr><td class="style_td">com2sec</td><td class="style_td">定义一个安全策略。community的作用类似于密码。</td></tr><tr><td class="style_td">group</td><td class="style_td">将安全策略映射到组。securityModel指SNMP版本号，可以选择v1、v2c或v3。</td></tr><tr><td class="style_td">view</td><td class="style_td">定义一个视图，规定视图中包括的内容。</td></tr><tr><td class="style_td">access</td><td class="style_td">定义哪个组可以访问哪个视图，以及访问权限。</td></tr></tbody></table></div>
<p>view中的一长串数字 .1.3.6.1.2.1.1 是MIB结点名称(OID)，由RFC1065/1155定义。
用snmptranlsate工具可以看到数字的意义：</p>
<pre># snmptranslate .1.3.6.1.2.1.1
SNMPv2-MIB::system</pre>
<p>我们可以让SNMP返回更多的信息（由于是局域网，所以就不考虑安全性问题了）。
按照以下方式修改snmpd.conf，同时注释掉原有内容：</p>
<pre>com2sec opennms   192.168.1.100/32    opennms    # 最后一个字段为community名称
group   opennmsGroup    v1           opennms
view    view_all      included   .1
access  opennmsGroup   &quot;&quot;      any       noauth    exact  view_all none none</pre>
<p>另外syslocation和syscontact指令是用来记录服务器所在物理位置和管理员联系地址的，适当填写即可。</p>
<p>最后重启SNMP：</p>
<pre># /etc/init.d/snmpd restart</pre>
<p>用snmpwalk工具检查配置是否正确，正确的话应该会输出很多信息：</p>
<pre># snmpwalk -c opennms -v 1 192.168.1.100</pre>
<p>最后将每台要监视的服务器都按照上述方法配置即可。</p>

<h2 id="content_10_6">在OpenNMS中添加节点</h2>
<p>登录到OpenNMS中，点击Admincaidan，然后点击左侧Operations中的Configure Discovery。
在Specifics表格中将要监视的服务器的IP地址填进去。如果要监视大范围的服务器，
可以在下面的Include Ranges中指定IP地址的范围。
最后点击“Save and Restart Discovery”，重新开始搜索节点。</p>
<div class="img_margin" style="text-align:left"><img src="http://tech.idv2.com/wp-content/uploads/2009/01/opennms-add-discovery.png" alt="opennms-add-discovery.png" title="opennms-add-discovery.png" width="644" height="486" /></div>

<p>稍等几分钟，再点击Node List菜单，即可看到刚刚添加的服务器。</p>
<div class="img_margin" style="text-align:left"><img src="http://tech.idv2.com/wp-content/uploads/2009/01/opennms-node-without-snmp.png" alt="opennms-node-without-snmp.png" title="opennms-node-without-snmp.png" width="624" height="423" /></div>

<p>但是现在在服务器状态中还看不到SNMP信息，因为我们还没设置SNMP的community名称——
刚才说过，community名称相当于密码。</p>
<p>点击Admin菜单，然后选择左侧的Configure SNMP Community Names by IP命令。
然后输入IP地址，以及刚才在snmpd.conf中使用的community名称，
版本号也要与snmpd.conf的group指令中设置的一致，最后点击Submit。</p>
<p>接下来回到Node List，进入要监视的服务器的状态页面，点击上方菜单中的Rescan。
等待一分钟左右再刷新页面，就可以看到SNMP状态信息了。（由于有了SNMP的帮助，
你会发现状态页面的信息一下子多了许多。）</p>
<div class="img_margin" style="text-align:left"><img src="http://tech.idv2.com/wp-content/uploads/2009/01/opennms-node-with-snmp.png" alt="opennms-node-with-snmp.png" title="opennms-node-with-snmp.png" width="629" height="460" /></div>

<p>这样，我们可以通过点击上方的Resource Graphs即可看到服务器运行状态的图表。</p>
<div class="img_margin" style="text-align:left"><img src="http://tech.idv2.com/wp-content/uploads/2009/01/opennms-memory-stats.png" alt="opennms-memory-stats.png" title="opennms-memory-stats.png" width="656" height="351" /></div>

<!-- end Pukiwiki generated code-->
]]></content:encoded>
			<wfw:commentRss>http://tech.idv2.com/2009/01/13/opennms-install-memo/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Linux下Trac安装手记</title>
		<link>http://tech.idv2.com/2008/12/26/install-trac-on-linux/</link>
		<comments>http://tech.idv2.com/2008/12/26/install-trac-on-linux/#comments</comments>
		<pubDate>Fri, 26 Dec 2008 14:10:28 +0000</pubDate>
		<dc:creator>charlee</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[trac]]></category>

		<guid isPermaLink="false">http://tech.idv2.com/2008/12/26/install-trac-on-linux/</guid>
		<description><![CDATA[<!-- begin Pukiwiki generated code--><p>之前发过一篇在Windows下安装Trac的方法，不过Trac更多的是在Linux下使用，
所以这里介绍一下在Linux下的安装方法。时过境迁，Trac现在已正式发布了0.11版，
与之前的0.9、0.10相比，这个版本的代码浏览器增加了许多功能，
最好用的就是它支持subversion的Blame了，可以查看到源代码的每一行是在哪个版本由谁修改的。</p>
<p>这篇文章是在Fedora Core 8上进行的，其他的RedHat系的Linux应该大同小异。</p>
<!-- end Pukiwiki generated code--><span id="more-652"></span><!-- begin Pukiwiki generated code--><h2 id="content_12_0">下载和解包</h2>
<p>废话少说，先从<a href="http://trac.edgewall.org/wiki/TracDownload">Trac的下载页面</a>上下载
最新的Trac-0.11.2.1版，然后解压缩。</p>
<pre>$ wget http://ftp.edgewall.com/pub/trac/Trac-0.11.2.1.tar.gz
$ tar xzvf Trac-0.11.2.1.tar.gz</pre>
<p>解开之后查看一下其中的INSTALL文件，其中的Requirements一节详细列出了安装Trac所必须的软件：</p>
<ul class="list1" style="padding-left:16px;margin-left:16px"><li>Python &gt;= 2.3。<em>（Fedora Core 8自带版本为python-2.5.1，没问题）</em>
<ul class="list2" style="padding-left:16px;margin-left:16px"><li>注意：如果是用rpm安装的python，那么还需要安装python-devel和python-xml包。<em>（我们就是这种情况）</em></li></ul></li>
<li>Genshi &gt;= 0.5。'''（在与Trac同一个网站上有下载）</li>
<li>可选的subversion &gt;= 1.0（推荐&gt;=1.1.x）和subversion的SWIG Python绑定</li>
<li>PySQLite，需要用于SQLite 3.x版本的PySQLite 2.x版</li>
<li>可运行CGI的Web服务器'''（我们有httpd-2.2.6）</li></ul>
<p>接下来就先解决这些前提条件。</p>

<h2 id="content_12_1">安装前提软件</h2>
<p>首先装好python-devel包。python-xml包在Fedora Core 8中不存在，不装也没关系：</p>
<pre># rpm -i python-devel-2.5.1-15.fc8.i386.rpm</pre>
<p>接下来应该再安装一个名为setuptools的包，虽然Trac的INSTALL中没有说，但它是必要的：</p>
<pre># rpm -i python-setuptools-0.6c7-2.fc8.noarch.rpm</pre>
<p>然后到<a href="http://genshi.edgewall.org/wiki/Download">Trac的隔壁</a>下载Genshi，最新版本0.5.1：</p>
<pre>$ wget http://ftp.edgewall.com/pub/genshi/Genshi-0.5.1.tar.gz
$ tar xzvf Genshi-0.5.1.tar.gz
$ cd Genshi-0.5.1
$ su
# python setup.py install
# exit</pre>
<p>接下来是subversion。Fedora Core 8 自带subversion-1.4.4，所以这个就不用装了
（可以用rpm -q subversion确认，如果你没装就先装好）。
而SWIG绑定也已经自带了，可以用以下命令确认：</p>
<pre>$ python
&gt;&gt;&gt; import svn.repos</pre>
<p>不报错，就说明OK了。</p>
<p>然后确认一下已安装的sqlite版本，并安装sqlite-devel包（用来编译PySQLite）：</p>
<pre>$ rpm -q sqlite
sqlite-3.4.2-3.fc8
# rpm -i sqlite-devel-3.4.2-3.fc8.i386.rpm</pre>
<p>接下来<a href="http://oss.itsystementwicklung.de/trac/pysqlite/">下载PySQLite</a>并安装：</p>
<pre>$ wget http://oss.itsystementwicklung.de/download/pysqlite/2.5/2.5.1/pysqlite-2.5.1.tar.gz
$ tar xzvf pysqlite-2.5.1.tar.gz
$ cd pysqlite-2.5.1
$ su
# python setup.py install
# exit</pre>
<p>Web服务器就用自带的httpd，如果你没有装，就要先装好这几个包：</p>
<pre>httpd-2.2.6-3
mod_python-3.3.1-5</pre>

<h2 id="content_12_2">安装Trac</h2>
<p>安装Trac本身非常简单：</p>
<pre># cd Trac-0.11.2.1
# python setup.py install</pre>

<h2 id="content_12_3">配置Web服务器</h2>
<p>我们将把 /var/www/trac 作为项目的主目录，所有新建的trac项目都放在该目录下，
访问URL为 /trac/&lt;项目名&gt;。</p>
<p>首先确认安装了 httpd 和 mod_python，此时/etc/httpd/conf.d下应该有个python.conf文件。
之后，在/etc/httpd/conf.d下建立一个trac.conf作为Trac的配置文件：</p>
<pre>&lt;Location /trac&gt;
    SetHandler mod_python
    PythonInterpreter main_interpreter
    PythonHandler trac.web.modpython_frontend
    PythonOption TracEnvParentDir /var/www/trac
    PythonOption TracUriRoot /trac/
    PythonOption PYTHON_EGG_CACHE /tmp/egg-cache
&lt;/Location&gt;</pre>
<p>然后在 /var/www 下建立trac目录并修改权限：</p>
<pre># cd /var/www
# mkdir trac
# chown apache.apache trac</pre>
<p>然后重新启动 httpd：</p>
<pre># /etc/init.d/httpd restart</pre>
<p>接下来访问<a href="http://localhost/trac">http://localhost/trac</a>，如果看到“Available Projects”字样，就说明配置成功了。</p>

<h2 id="content_12_4">建立项目</h2>
<p>下面要建立一个Trac的演示项目。进入 /var/www/trac，用trac-admin命令建立：</p>
<pre># cd /var/www/trac
# trac-admin hello_project initenv        (hello_project为项目名称，可以任意选择)
（接下来的提问全部按回车即可。如果想与subversion联合使用，请继续看）
# chown -R apache.apache hello_project</pre>
<p>然后访问<a href="http://localhost/trac/hello_project">http://localhost/trac/hello_project</a>，即可看到Trac的主界面了！</p>
<p>如果想在Trac中查看subversion的代码库，可以在trac-admin工具中把trac项目关联到代码库上。
比如，首先建立用于放置代码库的目录，并建立代码库：</p>
<pre># cd /var/www
# mkdir svn
# chown apache.apache svn
# cd svn
# svnadmin create hello_project        (hello_project为代码库名称，可以任意选择)
# chown -R apache.apache hello_project</pre>
<p>然后在建立Trac项目时，回答代码库的完整路径：</p>
<pre># trac-admin hello_project initenv
......
Path to repository [/path/to/repos]&gt; /var/www/svn/hello_project        (输入代码库完整路径)</pre>
<p>这样Trac中就可以访问subversion的代码库了。</p>
<p>如果项目已经建好，而想添加subversion支持的话，可以进入项目中的conf目录，
修改trac.ini中的repository_dir变量为代码库完整路径即可。</p>
<p>这个方法要求/var/www/trac下的所有内容必须属于apache用户，否则Trac会出错。
所以如果看到trac出错了，首先查看一下是不是忘记了做chown。</p>

<h2 id="content_12_5">配置管理界面</h2>
<p>接下来需要配置好认证，这样才能方便地通过浏览器来修改项目设置。</p>
<p>首先在 /var/www 下建立 .htpasswd 文件，用来保存用户名和密码：</p>
<pre># cd /var/wwwj
# htpasswd -c .htpasswd root   (建立用户root。如果.htpasswd文件存在，则不用加-c)</pre>
<p>然后继续修改 /etc/httpd/conf.d/trac.conf，在末尾添加以下内容：</p>
<pre>&lt;LocationMatch &quot;/trac/[^/]+/login&quot;&gt;
    AuthType Basic
    AuthName &quot;Trac&quot;
    AuthUserFile /var/www/.htpasswd
    Require valid-user
&lt;/LocationMatch&gt;</pre>
<p>然后重新启动httpd：</p>
<pre># /etc/init.d/httpd restart</pre>
<p>最后，进入/var/www/trac，给刚才建好的hello_project项目设置权限：</p>
<pre># trac-admin hello_project permission add root TRAC_ADMIN</pre>
<p>这样，访问 <a href="http://localhost/trac/hello_project">http://localhost/trac/hello_project</a>，然后点击上方菜单中的“Login”，
输入用户名root登录之后，即可在右上角看到“Admin”菜单，点击之后即可进入管理界面。</p>

<h2 id="content_12_6">其他资源</h2>
<ul class="list1" style="padding-left:16px;margin-left:16px"><li>Trac官方主页：<a href="http://trac.edgewall.org/">http://trac.edgewall.org/</a></li>
<li>Trac插件：<a href="http://trac-hacks.org/">http://trac-hacks.org/</a></li></ul>
<p>有几个插件不错，推荐使用：TocMacro, AccountManagerPlugin。</p>
<!-- end Pukiwiki generated code-->
]]></description>
			<content:encoded><![CDATA[<!-- begin Pukiwiki generated code--><p>之前发过一篇在Windows下安装Trac的方法，不过Trac更多的是在Linux下使用，
所以这里介绍一下在Linux下的安装方法。时过境迁，Trac现在已正式发布了0.11版，
与之前的0.9、0.10相比，这个版本的代码浏览器增加了许多功能，
最好用的就是它支持subversion的Blame了，可以查看到源代码的每一行是在哪个版本由谁修改的。</p>
<p>这篇文章是在Fedora Core 8上进行的，其他的RedHat系的Linux应该大同小异。</p>
<!-- end Pukiwiki generated code--><span id="more-652"></span><!-- begin Pukiwiki generated code--><h2 id="content_14_0">下载和解包</h2>
<p>废话少说，先从<a href="http://trac.edgewall.org/wiki/TracDownload">Trac的下载页面</a>上下载
最新的Trac-0.11.2.1版，然后解压缩。</p>
<pre>$ wget http://ftp.edgewall.com/pub/trac/Trac-0.11.2.1.tar.gz
$ tar xzvf Trac-0.11.2.1.tar.gz</pre>
<p>解开之后查看一下其中的INSTALL文件，其中的Requirements一节详细列出了安装Trac所必须的软件：</p>
<ul class="list1" style="padding-left:16px;margin-left:16px"><li>Python &gt;= 2.3。<em>（Fedora Core 8自带版本为python-2.5.1，没问题）</em>
<ul class="list2" style="padding-left:16px;margin-left:16px"><li>注意：如果是用rpm安装的python，那么还需要安装python-devel和python-xml包。<em>（我们就是这种情况）</em></li></ul></li>
<li>Genshi &gt;= 0.5。'''（在与Trac同一个网站上有下载）</li>
<li>可选的subversion &gt;= 1.0（推荐&gt;=1.1.x）和subversion的SWIG Python绑定</li>
<li>PySQLite，需要用于SQLite 3.x版本的PySQLite 2.x版</li>
<li>可运行CGI的Web服务器'''（我们有httpd-2.2.6）</li></ul>
<p>接下来就先解决这些前提条件。</p>

<h2 id="content_14_1">安装前提软件</h2>
<p>首先装好python-devel包。python-xml包在Fedora Core 8中不存在，不装也没关系：</p>
<pre># rpm -i python-devel-2.5.1-15.fc8.i386.rpm</pre>
<p>接下来应该再安装一个名为setuptools的包，虽然Trac的INSTALL中没有说，但它是必要的：</p>
<pre># rpm -i python-setuptools-0.6c7-2.fc8.noarch.rpm</pre>
<p>然后到<a href="http://genshi.edgewall.org/wiki/Download">Trac的隔壁</a>下载Genshi，最新版本0.5.1：</p>
<pre>$ wget http://ftp.edgewall.com/pub/genshi/Genshi-0.5.1.tar.gz
$ tar xzvf Genshi-0.5.1.tar.gz
$ cd Genshi-0.5.1
$ su
# python setup.py install
# exit</pre>
<p>接下来是subversion。Fedora Core 8 自带subversion-1.4.4，所以这个就不用装了
（可以用rpm -q subversion确认，如果你没装就先装好）。
而SWIG绑定也已经自带了，可以用以下命令确认：</p>
<pre>$ python
&gt;&gt;&gt; import svn.repos</pre>
<p>不报错，就说明OK了。</p>
<p>然后确认一下已安装的sqlite版本，并安装sqlite-devel包（用来编译PySQLite）：</p>
<pre>$ rpm -q sqlite
sqlite-3.4.2-3.fc8
# rpm -i sqlite-devel-3.4.2-3.fc8.i386.rpm</pre>
<p>接下来<a href="http://oss.itsystementwicklung.de/trac/pysqlite/">下载PySQLite</a>并安装：</p>
<pre>$ wget http://oss.itsystementwicklung.de/download/pysqlite/2.5/2.5.1/pysqlite-2.5.1.tar.gz
$ tar xzvf pysqlite-2.5.1.tar.gz
$ cd pysqlite-2.5.1
$ su
# python setup.py install
# exit</pre>
<p>Web服务器就用自带的httpd，如果你没有装，就要先装好这几个包：</p>
<pre>httpd-2.2.6-3
mod_python-3.3.1-5</pre>

<h2 id="content_14_2">安装Trac</h2>
<p>安装Trac本身非常简单：</p>
<pre># cd Trac-0.11.2.1
# python setup.py install</pre>

<h2 id="content_14_3">配置Web服务器</h2>
<p>我们将把 /var/www/trac 作为项目的主目录，所有新建的trac项目都放在该目录下，
访问URL为 /trac/&lt;项目名&gt;。</p>
<p>首先确认安装了 httpd 和 mod_python，此时/etc/httpd/conf.d下应该有个python.conf文件。
之后，在/etc/httpd/conf.d下建立一个trac.conf作为Trac的配置文件：</p>
<pre>&lt;Location /trac&gt;
    SetHandler mod_python
    PythonInterpreter main_interpreter
    PythonHandler trac.web.modpython_frontend
    PythonOption TracEnvParentDir /var/www/trac
    PythonOption TracUriRoot /trac/
    PythonOption PYTHON_EGG_CACHE /tmp/egg-cache
&lt;/Location&gt;</pre>
<p>然后在 /var/www 下建立trac目录并修改权限：</p>
<pre># cd /var/www
# mkdir trac
# chown apache.apache trac</pre>
<p>然后重新启动 httpd：</p>
<pre># /etc/init.d/httpd restart</pre>
<p>接下来访问<a href="http://localhost/trac">http://localhost/trac</a>，如果看到“Available Projects”字样，就说明配置成功了。</p>

<h2 id="content_14_4">建立项目</h2>
<p>下面要建立一个Trac的演示项目。进入 /var/www/trac，用trac-admin命令建立：</p>
<pre># cd /var/www/trac
# trac-admin hello_project initenv        (hello_project为项目名称，可以任意选择)
（接下来的提问全部按回车即可。如果想与subversion联合使用，请继续看）
# chown -R apache.apache hello_project</pre>
<p>然后访问<a href="http://localhost/trac/hello_project">http://localhost/trac/hello_project</a>，即可看到Trac的主界面了！</p>
<p>如果想在Trac中查看subversion的代码库，可以在trac-admin工具中把trac项目关联到代码库上。
比如，首先建立用于放置代码库的目录，并建立代码库：</p>
<pre># cd /var/www
# mkdir svn
# chown apache.apache svn
# cd svn
# svnadmin create hello_project        (hello_project为代码库名称，可以任意选择)
# chown -R apache.apache hello_project</pre>
<p>然后在建立Trac项目时，回答代码库的完整路径：</p>
<pre># trac-admin hello_project initenv
......
Path to repository [/path/to/repos]&gt; /var/www/svn/hello_project        (输入代码库完整路径)</pre>
<p>这样Trac中就可以访问subversion的代码库了。</p>
<p>如果项目已经建好，而想添加subversion支持的话，可以进入项目中的conf目录，
修改trac.ini中的repository_dir变量为代码库完整路径即可。</p>
<p>这个方法要求/var/www/trac下的所有内容必须属于apache用户，否则Trac会出错。
所以如果看到trac出错了，首先查看一下是不是忘记了做chown。</p>

<h2 id="content_14_5">配置管理界面</h2>
<p>接下来需要配置好认证，这样才能方便地通过浏览器来修改项目设置。</p>
<p>首先在 /var/www 下建立 .htpasswd 文件，用来保存用户名和密码：</p>
<pre># cd /var/wwwj
# htpasswd -c .htpasswd root   (建立用户root。如果.htpasswd文件存在，则不用加-c)</pre>
<p>然后继续修改 /etc/httpd/conf.d/trac.conf，在末尾添加以下内容：</p>
<pre>&lt;LocationMatch &quot;/trac/[^/]+/login&quot;&gt;
    AuthType Basic
    AuthName &quot;Trac&quot;
    AuthUserFile /var/www/.htpasswd
    Require valid-user
&lt;/LocationMatch&gt;</pre>
<p>然后重新启动httpd：</p>
<pre># /etc/init.d/httpd restart</pre>
<p>最后，进入/var/www/trac，给刚才建好的hello_project项目设置权限：</p>
<pre># trac-admin hello_project permission add root TRAC_ADMIN</pre>
<p>这样，访问 <a href="http://localhost/trac/hello_project">http://localhost/trac/hello_project</a>，然后点击上方菜单中的“Login”，
输入用户名root登录之后，即可在右上角看到“Admin”菜单，点击之后即可进入管理界面。</p>

<h2 id="content_14_6">其他资源</h2>
<ul class="list1" style="padding-left:16px;margin-left:16px"><li>Trac官方主页：<a href="http://trac.edgewall.org/">http://trac.edgewall.org/</a></li>
<li>Trac插件：<a href="http://trac-hacks.org/">http://trac-hacks.org/</a></li></ul>
<p>有几个插件不错，推荐使用：TocMacro, AccountManagerPlugin。</p>
<!-- end Pukiwiki generated code-->
]]></content:encoded>
			<wfw:commentRss>http://tech.idv2.com/2008/12/26/install-trac-on-linux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>rpm -i &#8211;nodeps时出现警告的原因</title>
		<link>http://tech.idv2.com/2008/12/18/rpm-i-nodeps-warning/</link>
		<comments>http://tech.idv2.com/2008/12/18/rpm-i-nodeps-warning/#comments</comments>
		<pubDate>Thu, 18 Dec 2008 06:30:58 +0000</pubDate>
		<dc:creator>charlee</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[rpm]]></category>

		<guid isPermaLink="false">http://tech.idv2.com/2008/12/18/rpm-i-nodeps-warning/</guid>
		<description><![CDATA[<!-- begin Pukiwiki generated code--><p>今天发现，制作的某个rpm包在执行 rpm -i --nodeps &lt;packagename.rpm&gt;时会出现以下的警告信息：</p>
<pre>warning: cannot get shared lock on /var/lib/rpm/Packages</pre>
<p>但如果不加--nodeps参数，就不会出现这个信息。</p>
<p>网上查了半天没找到相关资料，最后用排除法发现，SPEC文件的%post中有一行 rpm -qa，就是这行命令导致了该警告的发生。
原因尚且不明，估计是在安装过程中，rpm正在执行，此时在%post中再次启动rpm，当然会发生共享锁的错误。</p>
<!-- end Pukiwiki generated code-->]]></description>
			<content:encoded><![CDATA[<!-- begin Pukiwiki generated code--><p>今天发现，制作的某个rpm包在执行 rpm -i --nodeps &lt;packagename.rpm&gt;时会出现以下的警告信息：</p>
<pre>warning: cannot get shared lock on /var/lib/rpm/Packages</pre>
<p>但如果不加--nodeps参数，就不会出现这个信息。</p>
<p>网上查了半天没找到相关资料，最后用排除法发现，SPEC文件的%post中有一行 rpm -qa，就是这行命令导致了该警告的发生。
原因尚且不明，估计是在安装过程中，rpm正在执行，此时在%post中再次启动rpm，当然会发生共享锁的错误。</p>
<!-- end Pukiwiki generated code-->]]></content:encoded>
			<wfw:commentRss>http://tech.idv2.com/2008/12/18/rpm-i-nodeps-warning/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>memcached全面剖析&#8211;PDF总结篇</title>
		<link>http://tech.idv2.com/2008/08/17/memcached-pdf/</link>
		<comments>http://tech.idv2.com/2008/08/17/memcached-pdf/#comments</comments>
		<pubDate>Sun, 17 Aug 2008 14:55:11 +0000</pubDate>
		<dc:creator>charlee</dc:creator>
				<category><![CDATA[web]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[memcached]]></category>

		<guid isPermaLink="false">http://tech.idv2.com/2008/08/17/memcached-pdf/</guid>
		<description><![CDATA[<!-- begin Pukiwiki generated code--><p>memcached全面剖析的连载已经结束，翻译工作也已经全部完成了。
为了方便阅读，现将原来的翻译结果打包成PDF文档。可在本文末尾处下载。</p>
<p>原来的各篇翻译的地址如下：</p>
<ul class="list1" style="padding-left:16px;margin-left:16px"><li>第1章：<a href="http://tech.idv2.com/2008/07/10/memcached-001/">http://tech.idv2.com/2008/07/10/memcached-001/</a></li>
<li>第2章：<a href="http://tech.idv2.com/2008/07/11/memcached-002/">http://tech.idv2.com/2008/07/11/memcached-002/</a></li>
<li>第3章：<a href="http://tech.idv2.com/2008/07/16/memcached-003/">http://tech.idv2.com/2008/07/16/memcached-003/</a></li>
<li>第4章：<a href="http://tech.idv2.com/2008/07/24/memcached-004/">http://tech.idv2.com/2008/07/24/memcached-004/</a></li>
<li>第5章：<a href="http://tech.idv2.com/2008/07/31/memcached-005/">http://tech.idv2.com/2008/07/31/memcached-005/</a></li></ul>
<div class="img_margin" style="text-align:left"><a href="http://tech.idv2.com/wp-content/uploads/2008/08/memcached.zip" title="memcached全面剖析的PDF版"><img src="http://tech.idv2.com/wp-content/plugins/wp-pukiwiki/img/attach.gif" width="16" height="16" alt="attach" style="border-width:0px" />memcached.zip</a></div>

<!-- end Pukiwiki generated code-->]]></description>
			<content:encoded><![CDATA[<!-- begin Pukiwiki generated code--><p>memcached全面剖析的连载已经结束，翻译工作也已经全部完成了。
为了方便阅读，现将原来的翻译结果打包成PDF文档。可在本文末尾处下载。</p>
<p>原来的各篇翻译的地址如下：</p>
<ul class="list1" style="padding-left:16px;margin-left:16px"><li>第1章：<a href="http://tech.idv2.com/2008/07/10/memcached-001/">http://tech.idv2.com/2008/07/10/memcached-001/</a></li>
<li>第2章：<a href="http://tech.idv2.com/2008/07/11/memcached-002/">http://tech.idv2.com/2008/07/11/memcached-002/</a></li>
<li>第3章：<a href="http://tech.idv2.com/2008/07/16/memcached-003/">http://tech.idv2.com/2008/07/16/memcached-003/</a></li>
<li>第4章：<a href="http://tech.idv2.com/2008/07/24/memcached-004/">http://tech.idv2.com/2008/07/24/memcached-004/</a></li>
<li>第5章：<a href="http://tech.idv2.com/2008/07/31/memcached-005/">http://tech.idv2.com/2008/07/31/memcached-005/</a></li></ul>
<div class="img_margin" style="text-align:left"><a href="http://tech.idv2.com/wp-content/uploads/2008/08/memcached.zip" title="memcached全面剖析的PDF版"><img src="http://tech.idv2.com/wp-content/plugins/wp-pukiwiki/img/attach.gif" width="16" height="16" alt="attach" style="border-width:0px" />memcached.zip</a></div>

<!-- end Pukiwiki generated code-->]]></content:encoded>
			<wfw:commentRss>http://tech.idv2.com/2008/08/17/memcached-pdf/feed/</wfw:commentRss>
		<slash:comments>60</slash:comments>
		</item>
		<item>
		<title>Apache报告No space left on device的解决办法</title>
		<link>http://tech.idv2.com/2008/08/15/apache-no-space-left-on-device/</link>
		<comments>http://tech.idv2.com/2008/08/15/apache-no-space-left-on-device/#comments</comments>
		<pubDate>Fri, 15 Aug 2008 05:16:03 +0000</pubDate>
		<dc:creator>charlee</dc:creator>
				<category><![CDATA[web]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[linux]]></category>

		<guid isPermaLink="false">http://tech.idv2.com/2008/08/15/apache-no-space-left-on-device/</guid>
		<description><![CDATA[<!-- begin Pukiwiki generated code--><p>今天在开发时突然apache无法启动了。表现为，输入 httpd -X 后片刻自动退出，
同时在error_log中有如下内容：</p>
<pre>[Fri Aug 15 10:54:31 2008] [emerg] (28)No space left on device: Couldn't create accept lock</pre>
<p>df一下发现不是磁盘空间的问题。Google了一下就找到了解决方案，原来是系统的信号量(?)不够用了。
用以下命令可以查看所有的信号量：</p>
<pre># ipcs -s
------ Semaphore Arrays --------
key        semid      owner      perms      nsems
0x00000000 19234816   nobody    600        1
0x00000000 19267585   nobody    600        1
0x00000000 19300354   nobody    600        1
0x00000000 19398659   nobody    600        1
0x00000000 19431428   nobody    600        1
0x00000000 19464197   nobody    600        1
0x00000000 19562502   nobody    600        1</pre>
<p>然后用这行命令删除所有的信号量即可：</p>
<pre>ipcs -s | grep nobody | perl -lane 'print `ipcrm sem $F[1]`'</pre>
<!-- end Pukiwiki generated code-->
]]></description>
			<content:encoded><![CDATA[<!-- begin Pukiwiki generated code--><p>今天在开发时突然apache无法启动了。表现为，输入 httpd -X 后片刻自动退出，
同时在error_log中有如下内容：</p>
<pre>[Fri Aug 15 10:54:31 2008] [emerg] (28)No space left on device: Couldn't create accept lock</pre>
<p>df一下发现不是磁盘空间的问题。Google了一下就找到了解决方案，原来是系统的信号量(?)不够用了。
用以下命令可以查看所有的信号量：</p>
<pre># ipcs -s
------ Semaphore Arrays --------
key        semid      owner      perms      nsems
0x00000000 19234816   nobody    600        1
0x00000000 19267585   nobody    600        1
0x00000000 19300354   nobody    600        1
0x00000000 19398659   nobody    600        1
0x00000000 19431428   nobody    600        1
0x00000000 19464197   nobody    600        1
0x00000000 19562502   nobody    600        1</pre>
<p>然后用这行命令删除所有的信号量即可：</p>
<pre>ipcs -s | grep nobody | perl -lane 'print `ipcrm sem $F[1]`'</pre>
<!-- end Pukiwiki generated code-->
]]></content:encoded>
			<wfw:commentRss>http://tech.idv2.com/2008/08/15/apache-no-space-left-on-device/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>memcached全面剖析&#8211;5. memcached的应用和兼容程序</title>
		<link>http://tech.idv2.com/2008/07/31/memcached-005/</link>
		<comments>http://tech.idv2.com/2008/07/31/memcached-005/#comments</comments>
		<pubDate>Wed, 30 Jul 2008 16:56:48 +0000</pubDate>
		<dc:creator>charlee</dc:creator>
				<category><![CDATA[web]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[memcached]]></category>

		<guid isPermaLink="false">http://tech.idv2.com/2008/07/31/memcached-005/</guid>
		<description><![CDATA[<!-- begin Pukiwiki generated code--><p>发表日：2008/7/30 <br />
作者：长野雅广(Masahiro Nagano) <br />
原文链接：<a href="http://gihyo.jp/dev/feature/01/memcached/0005">http://gihyo.jp/dev/feature/01/memcached/0005</a> <br /></p>
<p>前几次的文章在这里：</p>
<ul class="list1" style="padding-left:16px;margin-left:16px"><li>第1次：<a href="http://tech.idv2.com/2008/07/10/memcached-001/">http://tech.idv2.com/2008/07/10/memcached-001/</a></li>
<li>第2次：<a href="http://tech.idv2.com/2008/07/11/memcached-002/">http://tech.idv2.com/2008/07/11/memcached-002/</a></li>
<li>第3次：<a href="http://tech.idv2.com/2008/07/16/memcached-003/">http://tech.idv2.com/2008/07/16/memcached-003/</a></li>
<li>第4次：<a href="http://tech.idv2.com/2008/07/24/memcached-004/">http://tech.idv2.com/2008/07/24/memcached-004/</a></li></ul>
<p>我是Mixi的长野。memcached的连载终于要结束了。
到<a href="http://tech.idv2.com/2008/07/24/memcached-004/">上次</a>为止，
我们介绍了与memcached直接相关的话题，本次介绍一些mixi的案例和
实际应用上的话题，并介绍一些与memcached兼容的程序。</p>
<!-- end Pukiwiki generated code--><span id="more-614"></span><!-- begin Pukiwiki generated code--><div class="contents">
<a id="contents_22"></a>
<ul class="list1" style="padding-left:16px;margin-left:16px"><li><a href="#content_22_0">  mixi案例研究</a>
<ul class="list2" style="padding-left:16px;margin-left:16px"><li><a href="#content_22_1">  服务器配置和数量</a></li>
<li><a href="#content_22_2">  memcached进程</a></li>
<li><a href="#content_22_3">  memcached使用方法和客户端</a>
<ul class="list3" style="padding-left:16px;margin-left:16px"><li><a href="#content_22_4">  通过Cache::Memcached::Fast维持连接</a></li>
<li><a href="#content_22_5">  公共数据的处理和rehash</a></li></ul></li></ul></li>
<li><a href="#content_22_6">  memcached应用经验</a>
<ul class="list2" style="padding-left:16px;margin-left:16px"><li><a href="#content_22_7">  通过daemontools启动</a></li>
<li><a href="#content_22_8">  监视</a></li>
<li><a href="#content_22_9">  memcached的性能</a></li></ul></li>
<li><a href="#content_22_10">  兼容应用程序</a>
<ul class="list2" style="padding-left:16px;margin-left:16px"><li><a href="#content_22_11">  Tokyo Tyrant案例</a></li></ul></li>
<li><a href="#content_22_12">  总结</a></li></ul>
</div>

<h2 id="content_22_0">mixi案例研究</h2>
<p>mixi在提供服务的初期阶段就使用了memcached。
随着网站访问量的急剧增加，单纯为数据库添加slave已无法满足需要，因此引入了memcached。
此外，我们也从增加可扩展性的方面进行了验证，证明了memcached的速度和稳定性都能满足需要。
现在，memcached已成为mixi服务中非常重要的组成部分。</p>
<div class="img_margin" style="text-align:left"><img src="http://tech.idv2.com/wp-content/uploads/2008/07/memcached-0005-01.png" alt="memcached-0005-01.png" title="memcached-0005-01.png" width="616" height="406" /></div>

<p>图1 现在的系统组件</p>

<h3 id="content_22_1">服务器配置和数量</h3>
<p>mixi使用了许许多多服务器，如数据库服务器、应用服务器、图片服务器、
反向代理服务器等。单单memcached就有将近200台服务器在运行。
memcached服务器的典型配置如下：</p>
<ul class="list1" style="padding-left:16px;margin-left:16px"><li>CPU：Intel Pentium 4 2.8GHz</li>
<li>内存：4GB</li>
<li>硬盘：146GB SCSI</li>
<li>操作系统：Linux（x86_64）</li></ul>
<p>这些服务器以前曾用于数据库服务器等。随着CPU性能提升、内存价格下降，
我们积极地将数据库服务器、应用服务器等换成了性能更强大、内存更多的服务器。
这样，可以抑制mixi整体使用的服务器数量的急剧增加，降低管理成本。
由于memcached服务器几乎不占用CPU，就将换下来的服务器用作memcached服务器了。</p>

<h3 id="content_22_2">memcached进程</h3>
<p>每台memcached服务器仅启动一个memcached进程。分配给memcached的内存为3GB，
启动参数如下：</p>
<pre>/usr/bin/memcached -p 11211 -u nobody -m 3000 -c 30720</pre>
<p>由于使用了x86_64的操作系统，因此能分配2GB以上的内存。32位操作系统中，
每个进程最多只能使用2GB内存。也曾经考虑过启动多个分配2GB以下内存的进程，
但这样一台服务器上的TCP连接数就会成倍增加，管理上也变得复杂，
所以mixi就统一使用了64位操作系统。</p>
<p>另外，虽然服务器的内存为4GB，却仅分配了3GB，是因为内存分配量超过这个值，
就有可能导致内存交换(swap)。连载的<a href="http://tech.idv2.com/2008/07/11/memcached-002/">第2次</a>中
前坂讲解过了memcached的内存存储“slab allocator”，当时说过，memcached启动时
指定的内存分配量是memcached用于保存数据的量，没有包括“slab allocator”本身占用的内存、
以及为了保存数据而设置的管理空间。因此，memcached进程的实际内存分配量要比
指定的容量要大，这一点应当注意。</p>
<p>mixi保存在memcached中的数据大部分都比较小。这样，进程的大小要比
指定的容量大很多。因此，我们反复改变内存分配量进行验证，
确认了3GB的大小不会引发swap，这就是现在应用的数值。</p>

<h3 id="content_22_3">memcached使用方法和客户端</h3>
<p>现在，mixi的服务将200台左右的memcached服务器作为一个pool使用。
每台服务器的容量为3GB，那么全体就有了将近600GB的巨大的内存数据库。
客户端程序库使用了本连载中多次提到车的Cache::Memcached::Fast，
与服务器进行交互。当然，缓存的分布式算法使用的是
<a href="http://tech.idv2.com/2008/07/24/memcached-004/">第4次</a>介绍过的
Consistent Hashing算法。</p>
<ul class="list1" style="padding-left:16px;margin-left:16px"><li><a href="http://search.cpan.org/dist/Cache-Memcached-Fast/">Cache::Memcached::Fast - search.cpan.org</a></li></ul>
<p>应用层上memcached的使用方法由开发应用程序的工程师自行决定并实现。
但是，为了防止车轮再造、防止Cache::Memcached::Fast上的教训再次发生，
我们提供了Cache::Memcached::Fast的wrap模块并使用。</p>

<h4 id="content_22_4">通过Cache::Memcached::Fast维持连接</h4>
<p>Cache::Memcached的情况下，与memcached的连接（文件句柄）保存在Cache::Memcached包内的类变量中。
在mod_perl和FastCGI等环境下，包内的变量不会像CGI那样随时重新启动，
而是在进程中一直保持。其结果就是不会断开与memcached的连接，
减少了TCP连接建立时的开销，同时也能防止短时间内反复进行TCP连接、断开
而导致的TCP端口资源枯竭。</p>
<p>但是，Cache::Memcached::Fast没有这个功能，所以需要在模块之外
将Cache::Memcached::Fast对象保持在类变量中，以保证持久连接。</p>
<pre>package Gihyo::Memcached;

use strict;
use warnings;
use Cache::Memcached::Fast;

my @server_list = qw/192.168.1.1:11211 192.168.1.1:11211/;
my $fast;  ## 用于保持对象

sub new {
    my $self  = bless {}, shift;
    if ( !$fast ) {
        $fast = Cache::Memcached::Fast-&gt;new({ servers =&gt; \@server_list });
    }
    $self-&gt;{_fast} = $fast;
    return $self;
}

sub get {
   my $self = shift;
   $self-&gt;{_fast}-&gt;get(@_);
}</pre>
<p>上面的例子中，Cache::Memcached::Fast对象保存到类变量$fast中。</p>

<h4 id="content_22_5">公共数据的处理和rehash</h4>
<p>诸如mixi的主页上的新闻这样的所有用户共享的缓存数据、设置信息等数据，
会占用许多页，访问次数也非常多。在这种条件下，访问很容易集中到某台memcached服务器上。
访问集中本身并不是问题，但是一旦访问集中的那台服务器发生故障导致memcached无法连接，
就会产生巨大的问题。</p>
<p>连载的<a href="http://tech.idv2.com/2008/07/24/memcached-004/">第4次</a>
中提到，Cache::Memcached拥有rehash功能，即在无法连接保存数据的服务器的情况下，
会再次计算hash值，连接其他的服务器。</p>
<p>但是，Cache::Memcached::Fast没有这个功能。不过，它能够在连接服务器失败时，
短时间内不再连接该服务器的功能。</p>
<pre>my $fast = Cache::Memcached::Fast-&gt;new({
    max_failures     =&gt; 3,
    failure_timeout  =&gt; 1
});</pre>
<p>在failure_timeout秒内发生max_failures以上次连接失败，就不再连接该memcached服务器。
我们的设置是1秒钟3次以上。</p>
<p>此外，mixi还为所有用户共享的缓存数据的键名设置命名规则，
符合命名规则的数据会自动保存到多台memcached服务器中，
取得时从中仅选取一台服务器。创建该函数库后，就可以使memcached服务器故障
不再产生其他影响。</p>

<h2 id="content_22_6">memcached应用经验</h2>
<p>到此为止介绍了memcached内部构造和函数库，接下来介绍一些其他的应用经验。</p>

<h3 id="content_22_7">通过daemontools启动</h3>
<p>通常情况下memcached运行得相当稳定，但mixi现在使用的最新版1.2.5
曾经发生过几次memcached进程死掉的情况。架构上保证了即使有几台memcached故障
也不会影响服务，不过对于memcached进程死掉的服务器，只要重新启动memcached，
就可以正常运行，所以采用了监视memcached进程并自动启动的方法。
于是使用了daemontools。</p>
<p>daemontools是qmail的作者DJB开发的UNIX服务管理工具集，
其中名为supervise的程序可用于服务启动、停止的服务重启等。</p>
<ul class="list1" style="padding-left:16px;margin-left:16px"><li><a href="http://cr.yp.to/daemontools.html">daemontools</a></li></ul>
<p>这里不介绍daemontools的安装了。mixi使用了以下的run脚本来启动memcached。</p>
<pre>#!/bin/sh

if [ -f /etc/sysconfig/memcached ];then
        . /etc/sysconfig/memcached
fi

exec 2&gt;&amp;1
exec /usr/bin/memcached -p $PORT -u $USER  -m $CACHESIZE -c $MAXCONN $OPTIONS</pre>

<h3 id="content_22_8">监视</h3>
<p>mixi使用了名为“nagios”的开源监视软件来监视memcached。</p>
<ul class="list1" style="padding-left:16px;margin-left:16px"><li><a href="http://www.nagios.org/">Nagios: Home</a></li></ul>
<p>在nagios中可以简单地开发插件，可以详细地监视memcached的get、add等动作。
不过mixi仅通过stats命令来确认memcached的运行状态。</p>
<pre>define command {
command_name                   check_memcached
command_line                   $USER1$/check_tcp -H $HOSTADDRESS$ -p 11211 -t 5 -E -s 'stats\r\nquit\r\n' -e 'uptime' -M crit
}</pre>
<p>此外，mixi将stats目录的结果通过rrdtool转化成图形，进行性能监视，
并将每天的内存使用量做成报表，通过邮件与开发者共享。</p>

<h3 id="content_22_9">memcached的性能</h3>
<p>连载中已介绍过，memcached的性能十分优秀。我们来看看mixi的实际案例。
这里介绍的图表是服务所使用的访问最为集中的memcached服务器。</p>
<div class="img_margin" style="text-align:left"><img src="http://tech.idv2.com/wp-content/uploads/2008/07/memcached-0005-02.png" alt="memcached-0005-02.png" title="memcached-0005-02.png" width="497" height="193" /></div>

<p>图2 请求数</p>
<div class="img_margin" style="text-align:left"><img src="http://tech.idv2.com/wp-content/uploads/2008/07/memcached-0005-03.png" alt="memcached-0005-03.png" title="memcached-0005-03.png" width="497" height="193" /></div>

<p>图3 流量</p>
<div class="img_margin" style="text-align:left"><img src="http://tech.idv2.com/wp-content/uploads/2008/07/memcached-0005-04.png" alt="memcached-0005-04.png" title="memcached-0005-04.png" width="497" height="179" /></div>

<p>图4 TCP连接数</p>
<p>从上至下依次为请求数、流量和TCP连接数。请求数最大为15000qps，
流量达到400Mbps，这时的连接数已超过了10000个。
该服务器没有特别的硬件，就是开头介绍的普通的memcached服务器。
此时的CPU利用率为：</p>
<div class="img_margin" style="text-align:left"><img src="http://tech.idv2.com/wp-content/uploads/2008/07/memcached-0005-05.png" alt="memcached-0005-05.png" title="memcached-0005-05.png" width="400" height="212" /></div>

<p>图5 CPU利用率</p>
<p>可见，仍然有idle的部分。因此，memcached的性能非常高，
可以作为Web应用程序开发者放心地保存临时数据或缓存数据的地方。</p>

<h2 id="content_22_10">兼容应用程序</h2>
<p>memcached的实现和协议都十分简单，因此有很多与memcached兼容的实现。
一些功能强大的扩展可以将memcached的内存数据写到磁盘上，实现数据的持久性和冗余。
连载<a href="http://tech.idv2.com/2008/07/16/memcached-003/">第3次</a>
介绍过，以后的memcached的存储层将变成可扩展的（pluggable），逐渐支持这些功能。</p>
<p>这里介绍几个与memcached兼容的应用程序。</p>
<dl class="list1" style="padding-left:16px;margin-left:16px"><dt>repcached</dt>
<dd>为memcached提供复制(replication)功能的patch。</dd>
<dt>Flared</dt>
<dd>存储到QDBM。同时实现了异步复制和fail over等功能。</dd>
<dt>memcachedb</dt>
<dd>存储到BerkleyDB。还实现了message queue。</dd>
<dt>Tokyo Tyrant</dt>
<dd>将数据存储到Tokyo Cabinet。不仅与memcached协议兼容，还能通过HTTP进行访问。</dd></dl>

<h3 id="content_22_11">Tokyo Tyrant案例</h3>
<p>mixi使用了上述兼容应用程序中的Tokyo Tyrant。Tokyo Tyrant是平林开发的
Tokyo Cabinet DBM的网络接口。它有自己的协议，但也拥有memcached兼容协议，
也可以通过HTTP进行数据交换。Tokyo Cabinet虽然是一种将数据写到磁盘的实现，但速度相当快。</p>
<p>mixi并没有将Tokyo Tyrant作为缓存服务器，而是将它作为保存键值对组合的DBMS来使用。
主要作为存储用户上次访问时间的数据库来使用。它与几乎所有的mixi服务都有关，
每次用户访问页面时都要更新数据，因此负荷相当高。MySQL的处理十分笨重，
单独使用memcached保存数据又有可能会丢失数据，所以引入了Tokyo Tyrant。
但无需重新开发客户端，只需原封不动地使用Cache::Memcached::Fast即可，
这也是优点之一。关于Tokyo Tyrant的详细信息，请参考本公司的开发blog。</p>
<ul class="list1" style="padding-left:16px;margin-left:16px"><li><a href="http://alpha.mixi.co.jp/blog/?p=166">mixi Engineers' Blog - Tokyo Tyrantによる耐高負荷DBの構築</a></li>
<li><a href="http://alpha.mixi.co.jp/blog/?p=185">mixi Engineers' Blog - Tokyo (Cabinet|Tyrant)の新機能</a></li></ul>

<h2 id="content_22_12">总结</h2>
<p>到本次为止，“memcached全面剖析”系列就结束了。我们介绍了memcached的基础、内部结构、
分散算法和应用等内容。读完后如果您能对memcached产生兴趣，就是我们的荣幸。
关于mixi的系统、应用方面的信息，请参考本公司的<a href="http://alpha.mixi.co.jp/">开发blog</a>。
感谢您的阅读。</p>
<!-- end Pukiwiki generated code-->

]]></description>
			<content:encoded><![CDATA[<!-- begin Pukiwiki generated code--><p>发表日：2008/7/30 <br />
作者：长野雅广(Masahiro Nagano) <br />
原文链接：<a href="http://gihyo.jp/dev/feature/01/memcached/0005">http://gihyo.jp/dev/feature/01/memcached/0005</a> <br /></p>
<p>前几次的文章在这里：</p>
<ul class="list1" style="padding-left:16px;margin-left:16px"><li>第1次：<a href="http://tech.idv2.com/2008/07/10/memcached-001/">http://tech.idv2.com/2008/07/10/memcached-001/</a></li>
<li>第2次：<a href="http://tech.idv2.com/2008/07/11/memcached-002/">http://tech.idv2.com/2008/07/11/memcached-002/</a></li>
<li>第3次：<a href="http://tech.idv2.com/2008/07/16/memcached-003/">http://tech.idv2.com/2008/07/16/memcached-003/</a></li>
<li>第4次：<a href="http://tech.idv2.com/2008/07/24/memcached-004/">http://tech.idv2.com/2008/07/24/memcached-004/</a></li></ul>
<p>我是Mixi的长野。memcached的连载终于要结束了。
到<a href="http://tech.idv2.com/2008/07/24/memcached-004/">上次</a>为止，
我们介绍了与memcached直接相关的话题，本次介绍一些mixi的案例和
实际应用上的话题，并介绍一些与memcached兼容的程序。</p>
<!-- end Pukiwiki generated code--><span id="more-614"></span><!-- begin Pukiwiki generated code--><div class="contents">
<a id="contents_24"></a>
<ul class="list1" style="padding-left:16px;margin-left:16px"><li><a href="#content_24_0">  mixi案例研究</a>
<ul class="list2" style="padding-left:16px;margin-left:16px"><li><a href="#content_24_1">  服务器配置和数量</a></li>
<li><a href="#content_24_2">  memcached进程</a></li>
<li><a href="#content_24_3">  memcached使用方法和客户端</a>
<ul class="list3" style="padding-left:16px;margin-left:16px"><li><a href="#content_24_4">  通过Cache::Memcached::Fast维持连接</a></li>
<li><a href="#content_24_5">  公共数据的处理和rehash</a></li></ul></li></ul></li>
<li><a href="#content_24_6">  memcached应用经验</a>
<ul class="list2" style="padding-left:16px;margin-left:16px"><li><a href="#content_24_7">  通过daemontools启动</a></li>
<li><a href="#content_24_8">  监视</a></li>
<li><a href="#content_24_9">  memcached的性能</a></li></ul></li>
<li><a href="#content_24_10">  兼容应用程序</a>
<ul class="list2" style="padding-left:16px;margin-left:16px"><li><a href="#content_24_11">  Tokyo Tyrant案例</a></li></ul></li>
<li><a href="#content_24_12">  总结</a></li></ul>
</div>

<h2 id="content_24_0">mixi案例研究</h2>
<p>mixi在提供服务的初期阶段就使用了memcached。
随着网站访问量的急剧增加，单纯为数据库添加slave已无法满足需要，因此引入了memcached。
此外，我们也从增加可扩展性的方面进行了验证，证明了memcached的速度和稳定性都能满足需要。
现在，memcached已成为mixi服务中非常重要的组成部分。</p>
<div class="img_margin" style="text-align:left"><img src="http://tech.idv2.com/wp-content/uploads/2008/07/memcached-0005-01.png" alt="memcached-0005-01.png" title="memcached-0005-01.png" width="616" height="406" /></div>

<p>图1 现在的系统组件</p>

<h3 id="content_24_1">服务器配置和数量</h3>
<p>mixi使用了许许多多服务器，如数据库服务器、应用服务器、图片服务器、
反向代理服务器等。单单memcached就有将近200台服务器在运行。
memcached服务器的典型配置如下：</p>
<ul class="list1" style="padding-left:16px;margin-left:16px"><li>CPU：Intel Pentium 4 2.8GHz</li>
<li>内存：4GB</li>
<li>硬盘：146GB SCSI</li>
<li>操作系统：Linux（x86_64）</li></ul>
<p>这些服务器以前曾用于数据库服务器等。随着CPU性能提升、内存价格下降，
我们积极地将数据库服务器、应用服务器等换成了性能更强大、内存更多的服务器。
这样，可以抑制mixi整体使用的服务器数量的急剧增加，降低管理成本。
由于memcached服务器几乎不占用CPU，就将换下来的服务器用作memcached服务器了。</p>

<h3 id="content_24_2">memcached进程</h3>
<p>每台memcached服务器仅启动一个memcached进程。分配给memcached的内存为3GB，
启动参数如下：</p>
<pre>/usr/bin/memcached -p 11211 -u nobody -m 3000 -c 30720</pre>
<p>由于使用了x86_64的操作系统，因此能分配2GB以上的内存。32位操作系统中，
每个进程最多只能使用2GB内存。也曾经考虑过启动多个分配2GB以下内存的进程，
但这样一台服务器上的TCP连接数就会成倍增加，管理上也变得复杂，
所以mixi就统一使用了64位操作系统。</p>
<p>另外，虽然服务器的内存为4GB，却仅分配了3GB，是因为内存分配量超过这个值，
就有可能导致内存交换(swap)。连载的<a href="http://tech.idv2.com/2008/07/11/memcached-002/">第2次</a>中
前坂讲解过了memcached的内存存储“slab allocator”，当时说过，memcached启动时
指定的内存分配量是memcached用于保存数据的量，没有包括“slab allocator”本身占用的内存、
以及为了保存数据而设置的管理空间。因此，memcached进程的实际内存分配量要比
指定的容量要大，这一点应当注意。</p>
<p>mixi保存在memcached中的数据大部分都比较小。这样，进程的大小要比
指定的容量大很多。因此，我们反复改变内存分配量进行验证，
确认了3GB的大小不会引发swap，这就是现在应用的数值。</p>

<h3 id="content_24_3">memcached使用方法和客户端</h3>
<p>现在，mixi的服务将200台左右的memcached服务器作为一个pool使用。
每台服务器的容量为3GB，那么全体就有了将近600GB的巨大的内存数据库。
客户端程序库使用了本连载中多次提到车的Cache::Memcached::Fast，
与服务器进行交互。当然，缓存的分布式算法使用的是
<a href="http://tech.idv2.com/2008/07/24/memcached-004/">第4次</a>介绍过的
Consistent Hashing算法。</p>
<ul class="list1" style="padding-left:16px;margin-left:16px"><li><a href="http://search.cpan.org/dist/Cache-Memcached-Fast/">Cache::Memcached::Fast - search.cpan.org</a></li></ul>
<p>应用层上memcached的使用方法由开发应用程序的工程师自行决定并实现。
但是，为了防止车轮再造、防止Cache::Memcached::Fast上的教训再次发生，
我们提供了Cache::Memcached::Fast的wrap模块并使用。</p>

<h4 id="content_24_4">通过Cache::Memcached::Fast维持连接</h4>
<p>Cache::Memcached的情况下，与memcached的连接（文件句柄）保存在Cache::Memcached包内的类变量中。
在mod_perl和FastCGI等环境下，包内的变量不会像CGI那样随时重新启动，
而是在进程中一直保持。其结果就是不会断开与memcached的连接，
减少了TCP连接建立时的开销，同时也能防止短时间内反复进行TCP连接、断开
而导致的TCP端口资源枯竭。</p>
<p>但是，Cache::Memcached::Fast没有这个功能，所以需要在模块之外
将Cache::Memcached::Fast对象保持在类变量中，以保证持久连接。</p>
<pre>package Gihyo::Memcached;

use strict;
use warnings;
use Cache::Memcached::Fast;

my @server_list = qw/192.168.1.1:11211 192.168.1.1:11211/;
my $fast;  ## 用于保持对象

sub new {
    my $self  = bless {}, shift;
    if ( !$fast ) {
        $fast = Cache::Memcached::Fast-&gt;new({ servers =&gt; \@server_list });
    }
    $self-&gt;{_fast} = $fast;
    return $self;
}

sub get {
   my $self = shift;
   $self-&gt;{_fast}-&gt;get(@_);
}</pre>
<p>上面的例子中，Cache::Memcached::Fast对象保存到类变量$fast中。</p>

<h4 id="content_24_5">公共数据的处理和rehash</h4>
<p>诸如mixi的主页上的新闻这样的所有用户共享的缓存数据、设置信息等数据，
会占用许多页，访问次数也非常多。在这种条件下，访问很容易集中到某台memcached服务器上。
访问集中本身并不是问题，但是一旦访问集中的那台服务器发生故障导致memcached无法连接，
就会产生巨大的问题。</p>
<p>连载的<a href="http://tech.idv2.com/2008/07/24/memcached-004/">第4次</a>
中提到，Cache::Memcached拥有rehash功能，即在无法连接保存数据的服务器的情况下，
会再次计算hash值，连接其他的服务器。</p>
<p>但是，Cache::Memcached::Fast没有这个功能。不过，它能够在连接服务器失败时，
短时间内不再连接该服务器的功能。</p>
<pre>my $fast = Cache::Memcached::Fast-&gt;new({
    max_failures     =&gt; 3,
    failure_timeout  =&gt; 1
});</pre>
<p>在failure_timeout秒内发生max_failures以上次连接失败，就不再连接该memcached服务器。
我们的设置是1秒钟3次以上。</p>
<p>此外，mixi还为所有用户共享的缓存数据的键名设置命名规则，
符合命名规则的数据会自动保存到多台memcached服务器中，
取得时从中仅选取一台服务器。创建该函数库后，就可以使memcached服务器故障
不再产生其他影响。</p>

<h2 id="content_24_6">memcached应用经验</h2>
<p>到此为止介绍了memcached内部构造和函数库，接下来介绍一些其他的应用经验。</p>

<h3 id="content_24_7">通过daemontools启动</h3>
<p>通常情况下memcached运行得相当稳定，但mixi现在使用的最新版1.2.5
曾经发生过几次memcached进程死掉的情况。架构上保证了即使有几台memcached故障
也不会影响服务，不过对于memcached进程死掉的服务器，只要重新启动memcached，
就可以正常运行，所以采用了监视memcached进程并自动启动的方法。
于是使用了daemontools。</p>
<p>daemontools是qmail的作者DJB开发的UNIX服务管理工具集，
其中名为supervise的程序可用于服务启动、停止的服务重启等。</p>
<ul class="list1" style="padding-left:16px;margin-left:16px"><li><a href="http://cr.yp.to/daemontools.html">daemontools</a></li></ul>
<p>这里不介绍daemontools的安装了。mixi使用了以下的run脚本来启动memcached。</p>
<pre>#!/bin/sh

if [ -f /etc/sysconfig/memcached ];then
        . /etc/sysconfig/memcached
fi

exec 2&gt;&amp;1
exec /usr/bin/memcached -p $PORT -u $USER  -m $CACHESIZE -c $MAXCONN $OPTIONS</pre>

<h3 id="content_24_8">监视</h3>
<p>mixi使用了名为“nagios”的开源监视软件来监视memcached。</p>
<ul class="list1" style="padding-left:16px;margin-left:16px"><li><a href="http://www.nagios.org/">Nagios: Home</a></li></ul>
<p>在nagios中可以简单地开发插件，可以详细地监视memcached的get、add等动作。
不过mixi仅通过stats命令来确认memcached的运行状态。</p>
<pre>define command {
command_name                   check_memcached
command_line                   $USER1$/check_tcp -H $HOSTADDRESS$ -p 11211 -t 5 -E -s 'stats\r\nquit\r\n' -e 'uptime' -M crit
}</pre>
<p>此外，mixi将stats目录的结果通过rrdtool转化成图形，进行性能监视，
并将每天的内存使用量做成报表，通过邮件与开发者共享。</p>

<h3 id="content_24_9">memcached的性能</h3>
<p>连载中已介绍过，memcached的性能十分优秀。我们来看看mixi的实际案例。
这里介绍的图表是服务所使用的访问最为集中的memcached服务器。</p>
<div class="img_margin" style="text-align:left"><img src="http://tech.idv2.com/wp-content/uploads/2008/07/memcached-0005-02.png" alt="memcached-0005-02.png" title="memcached-0005-02.png" width="497" height="193" /></div>

<p>图2 请求数</p>
<div class="img_margin" style="text-align:left"><img src="http://tech.idv2.com/wp-content/uploads/2008/07/memcached-0005-03.png" alt="memcached-0005-03.png" title="memcached-0005-03.png" width="497" height="193" /></div>

<p>图3 流量</p>
<div class="img_margin" style="text-align:left"><img src="http://tech.idv2.com/wp-content/uploads/2008/07/memcached-0005-04.png" alt="memcached-0005-04.png" title="memcached-0005-04.png" width="497" height="179" /></div>

<p>图4 TCP连接数</p>
<p>从上至下依次为请求数、流量和TCP连接数。请求数最大为15000qps，
流量达到400Mbps，这时的连接数已超过了10000个。
该服务器没有特别的硬件，就是开头介绍的普通的memcached服务器。
此时的CPU利用率为：</p>
<div class="img_margin" style="text-align:left"><img src="http://tech.idv2.com/wp-content/uploads/2008/07/memcached-0005-05.png" alt="memcached-0005-05.png" title="memcached-0005-05.png" width="400" height="212" /></div>

<p>图5 CPU利用率</p>
<p>可见，仍然有idle的部分。因此，memcached的性能非常高，
可以作为Web应用程序开发者放心地保存临时数据或缓存数据的地方。</p>

<h2 id="content_24_10">兼容应用程序</h2>
<p>memcached的实现和协议都十分简单，因此有很多与memcached兼容的实现。
一些功能强大的扩展可以将memcached的内存数据写到磁盘上，实现数据的持久性和冗余。
连载<a href="http://tech.idv2.com/2008/07/16/memcached-003/">第3次</a>
介绍过，以后的memcached的存储层将变成可扩展的（pluggable），逐渐支持这些功能。</p>
<p>这里介绍几个与memcached兼容的应用程序。</p>
<dl class="list1" style="padding-left:16px;margin-left:16px"><dt>repcached</dt>
<dd>为memcached提供复制(replication)功能的patch。</dd>
<dt>Flared</dt>
<dd>存储到QDBM。同时实现了异步复制和fail over等功能。</dd>
<dt>memcachedb</dt>
<dd>存储到BerkleyDB。还实现了message queue。</dd>
<dt>Tokyo Tyrant</dt>
<dd>将数据存储到Tokyo Cabinet。不仅与memcached协议兼容，还能通过HTTP进行访问。</dd></dl>

<h3 id="content_24_11">Tokyo Tyrant案例</h3>
<p>mixi使用了上述兼容应用程序中的Tokyo Tyrant。Tokyo Tyrant是平林开发的
Tokyo Cabinet DBM的网络接口。它有自己的协议，但也拥有memcached兼容协议，
也可以通过HTTP进行数据交换。Tokyo Cabinet虽然是一种将数据写到磁盘的实现，但速度相当快。</p>
<p>mixi并没有将Tokyo Tyrant作为缓存服务器，而是将它作为保存键值对组合的DBMS来使用。
主要作为存储用户上次访问时间的数据库来使用。它与几乎所有的mixi服务都有关，
每次用户访问页面时都要更新数据，因此负荷相当高。MySQL的处理十分笨重，
单独使用memcached保存数据又有可能会丢失数据，所以引入了Tokyo Tyrant。
但无需重新开发客户端，只需原封不动地使用Cache::Memcached::Fast即可，
这也是优点之一。关于Tokyo Tyrant的详细信息，请参考本公司的开发blog。</p>
<ul class="list1" style="padding-left:16px;margin-left:16px"><li><a href="http://alpha.mixi.co.jp/blog/?p=166">mixi Engineers' Blog - Tokyo Tyrantによる耐高負荷DBの構築</a></li>
<li><a href="http://alpha.mixi.co.jp/blog/?p=185">mixi Engineers' Blog - Tokyo (Cabinet|Tyrant)の新機能</a></li></ul>

<h2 id="content_24_12">总结</h2>
<p>到本次为止，“memcached全面剖析”系列就结束了。我们介绍了memcached的基础、内部结构、
分散算法和应用等内容。读完后如果您能对memcached产生兴趣，就是我们的荣幸。
关于mixi的系统、应用方面的信息，请参考本公司的<a href="http://alpha.mixi.co.jp/">开发blog</a>。
感谢您的阅读。</p>
<!-- end Pukiwiki generated code-->

]]></content:encoded>
			<wfw:commentRss>http://tech.idv2.com/2008/07/31/memcached-005/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
	</channel>
</rss>
