<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>インフラエンジニアway</title>
    <link rel="alternate" type="text/html" href="http://heartbeats.jp/hbblog/" />
    <link rel="self" type="application/atom+xml" href="http://heartbeats.jp/hbblog/atom.xml" />
    <id>tag:heartbeats.jp,2009-08-24:/hbblog//2</id>
    <updated>2012-01-25T05:45:36Z</updated>
    <subtitle>株式会社ハートビーツのインフラエンジニアから、ちょっとした情報をお届けします</subtitle>
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type 4.26</generator>

<entry>
    <title>nginx連載1回目: nginxの紹介</title>
    <link rel="alternate" type="text/html" href="http://heartbeats.jp/hbblog/2012/01/nginx01.html" />
    <id>tag:heartbeats.jp,2012:/hbblog//2.59</id>

    <published>2012-01-25T05:00:00Z</published>
    <updated>2012-01-25T05:45:36Z</updated>

    <summary>皆様、初めまして。滝澤と申します。今月からここで記事を書いていきますのでよろしく...</summary>
    <author>
        <name>滝澤隆史</name>
        <uri>http://heartbeats.jp/</uri>
    </author>
    
        <category term="nginx" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://heartbeats.jp/hbblog/">
        <![CDATA[<p>皆様、初めまして。滝澤と申します。今月からここで記事を書いていきますのでよろしくお願いします。</p>

<p>ここ1,2年で注目を集めているWebサーバ<a href="http://nginx.org/en/">nginx</a>について今回から数回にわたってを紹介していきます。</p>
<p>nginxについて初めて知った、あるいは、名前は聞いたことがあるんだけど使ったことはない、といった方のために、1回目のこの記事ではnginxの概要を、2回目の記事ではインストールと設定について紹介します。</p>

]]>
        <![CDATA[<h1>nginxとは</h1>
<p>nginxはロシアのIgor Sysoev氏によって開発されているWebサーバ兼リバースプロキシのソフトウェアです。「エンジン エックス」（engine x）と呼びます。</p>
<p>2002年に開発が始まり、2004年に公開され、今では約10%のシェアを持つまでに成長しています。facebookやWordPress.ORGなどの大規模サイトでの導入実績もあり、導入するWebサーバの選択肢の一つとして考えられます。ちなみに、2011年7月には商用サポートやコンサルティングを行う法人<a href="http://nginx.com/">Nginx, Inc.</a>が設立されています。</p>

<h2>シェア</h2>
<p>英国のインターネット サービスの調査会社<a href="http://news.netcraft.com/">NETCRAFT</a>社による「<a href="http://news.netcraft.com/archives/2012/01/03/january-2012-web-server-survey.html">January 2012 Web Server Survey</a>」という調査によるとnginxのシェアはトップ サーバでは9.63%であり、Apache、Microsoftに続いて3位となっています。アクティブなサイト数としてはnginxのシェアは12.18%であり、Microsoftを超えて2位となっています。<a href="http://news.netcraft.com/archives/2009/01/16/january_2009_web_server_survey.html">2009年1月のレポート</a>ではそれぞれ1.87%、2.85%であることを踏まえると、nginxのシェアが急激に増加していることがわかります。</p>

<h2>nginxに関する情報</h2>
<p>日本でもこの1,2年で注目度も上がっており、nginxを利用しているサイトも増えています。しかし、ロシアで開発されているため、<a href="http://nginx.org/ru/docs/">オリジナルの文書</a>はロシア語であり、英語での文書もそれなりに揃ってはいますが、ロシア語のみの文書も多数あります。しかし、日本語での情報は乏しい状況です。幸いなことに、Clement Nedelcu氏の書籍『<a href="http://www.packtpub.com/nginx-http-server/book">nginx HTTP Server</a>』が日本語に翻訳され『<a href="http://ascii.asciimw.jp/books/books/detail/978-4-04-870227-0.shtml">ハイパフォーマンスHTTPサーバ nginx入門</a>』として出版されています。この書籍は入門書としての位置づけであり、取っかかりをつかむには良い本でしょう。しかし、実運用上はウェブアプリケーションと連携して利用することがほとんどなのですが、それについて十分な記載があるとはいえません。そのため、本ブログの次回以降ではそのあたりのノウハウやモジュールの機能について紹介していきます。</p>


<h1>nginxの特徴</h1>
<p>次のような特徴があります。</p>

<h2>C10K問題</h2>
<p>nginxは「<a href="http://www.kegel.com/c10k.html">C10K問題</a>」（クライアント1万台問題）に対応したWebサーバです。従来のWebサーバでは同時接続数が増えると、プロセス数やスレッド数が増えて、メモリを食いつぶしたり、コンテキストスイッチのオーバーヘッドが大きくなることにより本来の処理に時間が割けなくなったりします。nginxではマルチスレッドを使わずに、イベント駆動のアーキテクチャを採用することにより、このC10K問題に対応するような仕組みを設けております。このため、メモリの使用量も抑えることができ、メモリが少ないサーバでもそれなりに快適に動作します。</p>

<h2>静的なコンテンツを提供するWebサーバ</h2>
<p>nginxはWebサーバとして静的なコンテンツを提供します。ファイル記述子の情報をキャッシュするといった性能を上げるための様々な工夫が用意されています。</p>
<p>動的なコンテンツはnginx単体では提供できません。次に述べるようなWebアプリケーションサーバと連携することにより動的コンテンツを提供します。</p>

<h2>Webアプリケーションとの連携</h2>
<p>nginxではWebアプリケーションを（apacheのmod_phpやmod_wsgiのように）Webサーバ自体に組み込んで動作させることはできません。WebアプリケーションをFastCGIやSCGIやuWSGIに対応したアプリケーションサーバ上で動作させて、ネットワークあるいはUNIXドメインソケットを経由して利用します。PHPの場合はPHP-FPM (FastCGI Process Manager) 上でPHPのWebアプリケーションを動作させて、nginxからはPHP-FPMと通信を行って利用します。</p>
<p>Webアプリケーションとの連携についても性能向上のために次のような機能が用意されています。
<p>キャッシュ。Webアプリケーションサーバから取得したコンテンツをキャッシュできます。</p>
<p>memcached。Webアプリケーション側でコンテンツをmemcachedにキャッシュさせることができるときには、nginxはmemcachedからコンテンツを読み出すことができます。</p>
<p>ロードバランサ。ロードバランサとしての機能を持っており、複数のアプリケーションサーバを利用して負荷を分散することができます。また、利用できなくなったアプリケーションサーバを自動的に外すこともできます。</p>

<h2>リバースプロキシ</h2>
<p>nginxはリバースプロキシの機能を提供します。</p>
<p>性能向上のために次のような機能も用意されています。</p>
<p>キャッシュ。バックエンドのWebサーバから取得したコンテンツをキャッシュできます。</p>
<p>ロードバランサ。ロードバランサとしての機能を持っており、複数のバックエンドのWebサーバを利用して負荷を分散することができます。また、利用できなくなったWebサーバを自動的に外すこともできます。</p>

<h2>機能とモジュール</h2>
<p>nginxはモジュールにより機能を拡張できる仕組みになっており、50個近くのモジュールがあります。サードパーティのモジュールもたくさんあり、<a href="http://wiki.nginx.org/3rdPartyModules">Wikiサイト</a>で紹介されているものだけでも約80個あります。</p>

<p>たくさんのモジュールがありますが、それらを気軽に利用できるかというとそうではありません。この記事の執筆時点（2012年1月）でのnginxのバージョン（安定版1.0.11、開発版1.1.13）では、ビルドするときにしかモジュールを組み込むことができません。あるモジュールを利用する可能性が少しでもあれば、そのモジュールをビルド時に組み込んでおかないと再びビルドし直すことになります。このため、OSのパッケージ管理システムで提供されているnginxのパッケージではほとんどのモジュールが組み込まれています。
ちなみに、<a href="http://fsmsh.com/3657">Igor Sysoev氏へのインタビュー記事</a>によると、次のメジャーリリースで起動時にモジュールをロードできるようにする計画があるとのことです。</p>


<p>今回はここまでです。次回はnginxのインストールと設定について説明します。</p>
]]>
    </content>
</entry>

<entry>
    <title>インフラエンジニアway 2011年間アクセスランキング！</title>
    <link rel="alternate" type="text/html" href="http://heartbeats.jp/hbblog/2011/12/way-2011.html" />
    <id>tag:heartbeats.jp,2011:/hbblog//2.55</id>

    <published>2011-12-27T15:34:16Z</published>
    <updated>2011-12-27T15:43:06Z</updated>

    <summary>こんにちは。CTOの馬場です。 2011年も残すところあと数日となりました。  ...</summary>
    <author>
        <name>馬場俊彰</name>
        <uri>http://heartbeats.jp/</uri>
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="http://heartbeats.jp/hbblog/">
        <![CDATA[<p>こんにちは。CTOの馬場です。</p>

<p>2011年も残すところあと数日となりました。 <br />
もういくつか寝ると2012年の幕開けです。  </p>

<p>来年のことを言うと鬼に笑われてしまいますので、
このインフラエンジニアwayの
<strong>2011年間アクセスランキング</strong> 
をもとに今年の振り返りをしてみましょう。</p>
]]>
        <![CDATA[<h1>10. <a href="http://heartbeats.jp/hbblog/2011/11/cacti-087h.html">cacti 0.8.7hでハマった件の顛末</a></h1>

<p>cacti最新版のbugで苦労した話。0.8.7hは地雷でした...</p>

<h1>9. <a href="http://heartbeats.jp/hbblog/2009/09/ubuntu-server-904-nagios30.html">Ubuntu Server 9.04 で Nagios3.0 を使う</a></h1>

<p>Nagiosインストラクションシリーズの中のエントリ。Ubuntu Serverの人気にあやかっています</p>

<h1>8. <a href="http://heartbeats.jp/hbblog/2010/04/post.html">プリンタで印刷できない大きなサイズを印刷する方法</a></h1>

<p>ライフハックなエントリ。誰かもっといい方法知らないですか...</p>

<h1>7. <a href="http://heartbeats.jp/hbblog/2010/05/mod-proxy-balancersorry.html">mod<em>proxy</em>balancerでsorryサーバを実現する</a></h1>

<p>ドキュメントの落とし穴。nginxが人気ですが、apacheだって現役です！</p>

<h1>6. <a href="http://heartbeats.jp/hbblog/2011/02/python-1.html">Pythonで日本語メールヘッダをデコードする</a></h1>

<p>メールの日本語処理って鬼門ですよねぇ。このくらい標準ライブラリで用意してほしいところです。</p>

<h1>5. <a href="http://heartbeats.jp/hbblog/2010/10/skype4pyskype.html">Skype4Pyを使ってコマンドラインからSkypeを使う</a></h1>

<p>モリヨシさんの<a href="http://d.hatena.ne.jp/moriyoshi/20100926/1285517353">Linux上で動くSkype用のbotを作る方法 - muddy brown thang</a>を噛み砕いた感じのエントリ。モリヨシさんのおこぼれで年間アクセス5位。さすがモリヨシさん。</p>

<h1>4. <a href="http://heartbeats.jp/hbblog/2009/09/nagios.html">Nagiosプラグインの紹介</a></h1>

<p>Nagiosプラグイン67個の解説です。力作すぎて書くのすごい疲れた思い出。</p>

<h1>3. <a href="http://heartbeats.jp/hbblog/2009/10/nagios-1.html">Nagiosプラグイン自作方法の紹介</a></h1>

<p>スタッフ発のエントリ。このあたりからアクセス数が跳ね上がります。3位は5位の倍近いアクセス数でした。</p>

<h1>2. <a href="http://heartbeats.jp/hbblog/2010/09/bash.html">覚えておきたいbashシェルスクリプトのオプション</a></h1>

<p>実践から生まれた小ネタ。シェルスクリプトをデバッグ実行する方法などを記載した、インフラエンジニアライフハック的なエントリ。</p>

<h1>1. <a href="http://heartbeats.jp/hbblog/2010/12/cgroups.html">超期待の新機能cgroups</a></h1>

<p>非常に地味(笑)で堅実なネタ、cgroupsの概要についてのエントリです。</p>

<h1>ちなみに</h1>

<p>じつはTOP5で全体の約60%、TOP10で全体の約77%のアクセス数でした。</p>

<p>TOP10のうち、2011年のエントリが2本、2010年のエントリが5本、2009年のエントリが3本でした。
古いエントリでも基礎的な内容は長くにわたりアクセスがありますね。</p>

<p>これからも、しっかりしたネタを織りまぜつつ色々と発信していきます！</p>

<p>来年も引き続き<a href="http://heartbeats.jp/">heartbeats</a>と<a href="http://heartbeats.jp/hbstudy/">hbstudy</a>と<a href="http://heartbeats.jp/hbblog/">インフラエンジニアway</a>をよろしくお願いします！</p>
]]>
    </content>
</entry>

<entry>
    <title>cacti 0.8.7hでハマった件の顛末</title>
    <link rel="alternate" type="text/html" href="http://heartbeats.jp/hbblog/2011/11/cacti-087h.html" />
    <id>tag:heartbeats.jp,2011:/hbblog//2.53</id>

    <published>2011-11-10T17:36:29Z</published>
    <updated>2011-11-10T18:22:29Z</updated>

    <summary>こんにちは。CTOの馬場です。 だいぶご無沙汰ですが、今回もインフラエンジニア向...</summary>
    <author>
        <name>馬場俊彰</name>
        <uri>http://heartbeats.jp/</uri>
    </author>
    
        <category term="cacti" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://heartbeats.jp/hbblog/">
        <![CDATA[<p>こんにちは。CTOの馬場です。</p>

<p>だいぶご無沙汰ですが、今回もインフラエンジニア向けにちょっとした情報を紹介します。  </p>

<p>今回はcacti 0.8.7hでハマったので、その顛末と回避方法を書いておきます。</p>

<p>ハマった事象は <strong>「データ取得は正常だけどrrdファイルが更新されない」</strong> でした。。。</p>

<h1>環境</h1>

<ul>
<li>CentOS 5.6</li>
<li>apache 2.2.21 (ソースインストール)</li>
<li>php 5.3.8 (ソースインストール)</li>
<li>MySQL 5.5.15 (本家謹製rpm)</li>
<li>cacti 0.8.7h + spine</li>
</ul>

<p>イケてるtemplateが使いたかったので、<a href="http://groups.google.com/group/better-cacti-templates">better-cacti-templates</a> を使えるように試行錯誤したのでした。</p>
]]>
        <![CDATA[<h1>ログを集めた</h1>

<p>何はなくともログです。ログ。</p>

<ul>
<li>cactiのweb管理画面で Settings > General > Poller Logging Level をDEVELにしてログ確認</li>
<li>pollerの出力をファイルに出してチェック</li>
</ul>

<p>すると、、、ログに下記の出力がありました。</p>

<ul>
<li><code>CACTI2RRD: rrdtool update &lt;filename&gt; --template  99999:99999</code></li>
<li><code>ERROR: Not enough arguments</code></li>
</ul>

<p>前者のほう、よくよく見るとrrdtoolのsyntaxが間違っている。よくよく見ると、本当は<code>--template</code>の後は引数2つなんです。</p>

<p>rrdtoolのsyntax errorの結果、後者が出力されてました。
このせいでrrdファイルが更新されません。</p>

<h1>回避策を探す</h1>

<p>とりあえずエラーメッセージでググる。</p>

<p><a href="http://forums.cacti.net/viewtopic.php?f=2&amp;t=41673">Poller is missing template parameter according to cacti.log</a></p>

<p>すると、データ取得スクリプトの余計な空行を削除せよ、とのこと。</p>

<p>さっそくやってみると...効果なし。色々試しても効果なし。効果なし。なし。。</p>

<h1>デバッグ</h1>

<p>公式のデバッグマニュアルを見ながらデバッグ <br />
<a href="http://docs.cacti.net/manual:087:4_help.2_debugging">manual:087:4<em>help.2</em>debugging - Cacti Docs</a></p>

<ol>
<li>Check Cacti Log File</li>
<li>Check Basic Data Gathering</li>
<li>Check Cacti's Poller</li>
<li>Check MySQL Update</li>
<li>Check RRD File Update</li>
</ol>

<p>今までの調査で 5. はダメなのがわかっていて、 
3. はokなのがわかっているので、
4. を実施。</p>

<h2>Check MySQL Update</h2>

<p>mysqlの設定を変更して全クエリを出力したのでした。 <br />
設定したら、 <code>show variables</code> して結果の確認を忘れずに！</p>

<ul>
<li><code>set global log_slow_queries=On</code></li>
<li><code>set global long_query_time=0;</code></li>
</ul>

<p>この状態でpollingが走ると、mysqlに対して実行された全クエリがスローログに出力されます。かなり大量なのでびっくりしてください。</p>

<p>実行されたクエリが取得できたら、データソースのIDを頼りに、 <code>poller_output</code> テーブルにデータを投入している箇所を探します。</p>

<pre>
INSERT INTO poller_output (local_data_id, rrd_name, time, output) 
VALUES ( データ ), ( データ ), ( データ ), ( データ ), ( データ ), ( データ ), ( データ ) 
ON DUPLICATE KEY UPDATE output=VALUES(output);
</pre>

<p>このクエリを手動でも実行してみて、データが正常に投入できているかどうか、取得できるかを確認します。</p>

<p>...今回はここは正常でした。明らかにオカシイ。まぁもともとオカシイから調べてるんですが。。。</p>

<h2>ソース読み</h2>

<p>公式マニュアルのお陰でMySQLが原因ではないことがわかったので、ハラを決めてソースを読みます。</p>

<p>今回はログに <code>CACTI2RRD: rrdtool update 〜</code> と記載があり、ここがおかしいことはわかっていたので、この <code>CACTI2RRD</code> ととっかかりに調査します。</p>

<pre>
# find /var/www/cacti/ -type f -name "*.php"|xargs grep -nHi "CACTI2RRD"
/var/www/cacti/lib/rrd.php:80:          cacti_log("CACTI2RRD: " . read_config_option("path_rrdtool") . " $command_line", $log_to_stdout, $logopt);
/var/www/cacti/lib/rrd.php:399:                         cacti_log("CACTI2RRD: " . read_config_option("path_rrdtool") . " tune $data_source_path $rrd_tune");
</pre>

<p>2箇所しかない！ということで、rrd.phpを見てみます。</p>

<ul>
<li><code>rrdtool_execute</code> 関数の中で呼ばれているのがクサい  </li>
<li>→ <code>rrdtool_execute</code> と <code>update</code> の組み合わせで呼ばれている行を探す  </li>
<li>→ <code>rrdtool_function_update</code> がクサい  </li>
<li>→ 呼んでいる箇所を探す。同じファイルにはないのでfindとxargsを組み合わせて探す  </li>
<li>→ <code>/var/www/cacti/lib/poller.php</code> でしか呼んでない  </li>
<li>→ <code>/var/www/cacti/lib/poller.php</code> を該当箇所からさかのぼって読む。読む。  </li>
<li>→ 実行されているはずのSQLが実行されていない！</li>
<li>→ 分岐がおかしい！</li>
<li>→ <code>is_hexadecimal</code>関数の結果がおかしい！</li>
<li>→ 定義されている箇所が見当たらないのでfindとxargsを組み合わせて探す</li>
<li>→ <code>lib/functions.php</code>にあった！</li>
</ul>

<p>と、いうわけで、 <code>lib/functions.php</code> の <code>is_hexadecimal</code> 関数を修正して対応完了。</p>

<p>コーディングミスで複数値対応ができなくなっていたようです。 <br />
(推測ですがipv6対応したかったもよう)</p>

<h1>SVNみてみる</h1>

<p>最新版(0.8.7のHEAD)では直ってる...</p>

<p>rev 6251→6252(2011/1/29)でエンバグして、rev 6850→6851(2011/10/9)に改修されてました。</p>

<h1>まとめ</h1>

<p>オープンソースでよかった。</p>
]]>
    </content>
</entry>

<entry>
    <title>botoを使ってEBSをバックアップ(世代管理つき)</title>
    <link rel="alternate" type="text/html" href="http://heartbeats.jp/hbblog/2011/04/botoebs.html" />
    <id>tag:heartbeats.jp,2011:/hbblog//2.47</id>

    <published>2011-04-27T23:15:28Z</published>
    <updated>2011-04-27T23:33:57Z</updated>

    <summary>こんにちは。CTOの馬場です。 今回もインフラエンジニア向けにちょっとした情報を...</summary>
    <author>
        <name>馬場俊彰</name>
        <uri>http://heartbeats.jp/</uri>
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="http://heartbeats.jp/hbblog/">
        <![CDATA[<p>こんにちは。CTOの馬場です。</p>

<p>今回もインフラエンジニア向けにちょっとした情報を紹介します。 <br />
少し間があいてしまいましたが今回は珍しくAWSネタです。</p>

<p>botoを使ってEBSをバックアップする方法を紹介します。</p>
]]>
        <![CDATA[<p>元ネタは <a href="http://twitter.com/d_sea">@d_sea</a> さんの <a href="http://d.hatena.ne.jp/d_sea/20091026/p1">Amazon EBS と boto を使って自動バックアップ環境を構築する</a> ですが少しだけupdateしています。</p>

<ul>
<li>Volume IDとDescriptionが同じsnapshotを、指定した世代数だけ保持するよう変更した <br />
(同じVolume IDのEBSを別のDescriptionで保存した場合に、世代にカウントされないようにした) <br />
→手動バックアップと自動バックアップを区別できるようになりました</li>
<li>リージョンを指定できるようにした</li>
</ul>

<p>boto-1.9bで動作を確認しています。
エラー処理がアレなのはご愛嬌で。</p>

<p><code>AWS_ACCESS_KEY_ID</code>、<code>AWS_SECRET_ACCESS_KEY</code>には、
webの アカウント＞セキュリティ証明書＞アクセスキー(タブ)　で表示されるものを指定してください。</p>

<pre>
#!/usr/bin/python 
import sys
import re
from boto import config
from boto import  ec2
from boto.ec2.connection import EC2Connection

AWS_ACCESS_KEY_ID = ''
AWS_SECRET_ACCESS_KEY = ''
DESCRIPTION = 'daily backup'
REGION_NAME = 'us-west-1'

if(len(sys.argv) != 3):
    print "Usage: ebs-snapshot.py &lt;num&gt; &lt;volume-id&gt;"
    sys.exit()
regions = ec2.regions(aws_access_key_id=AWS_ACCESS_KEY_ID,aws_secret_access_key=AWS_SECRET_ACCESS_KEY)
for r in regions:
    if r.name == REGION_NAME:
        _region=r
conn = EC2Connection(aws_access_key_id=AWS_ACCESS_KEY_ID,aws_secret_access_key=AWS_SECRET_ACCESS_KEY,region=_region)
conn.create_snapshot(volume_id=sys.argv[2], description=DESCRIPTION) 
snapshot = {}
for x in conn.get_all_snapshots(): 
    if((x.volume_id == sys.argv[2]) and (x.description == DESCRIPTION)): 
        tmp = {x.id:x.start_time} 
        snapshot.update(tmp) 
snapshot = sorted(snapshot.items(), key=lambda (k, v): (v, k), reverse=True) 
for i in range(int(sys.argv[1]), len(snapshot)): 
    conn.delete_snapshot(snapshot[i][0]) 
</pre>

<p>利用例(cronで実行)</p>

<pre>
30 5 * * * /opt/backup/bin/ebs_snapshot.py 3 vol-XXXXXXXX
</pre>

<p>簡単ですね！</p>
]]>
    </content>
</entry>

<entry>
    <title>Pythonで日本語メールヘッダをデコードする</title>
    <link rel="alternate" type="text/html" href="http://heartbeats.jp/hbblog/2011/02/python-1.html" />
    <id>tag:heartbeats.jp,2011:/hbblog//2.44</id>

    <published>2011-02-06T23:01:55Z</published>
    <updated>2011-02-06T23:13:18Z</updated>

    <summary>こんにちは。CTOの馬場です。 今回もインフラエンジニア向けにちょっとした情報を...</summary>
    <author>
        <name>馬場俊彰</name>
        <uri>http://heartbeats.jp/</uri>
    </author>
    
        <category term="Python" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://heartbeats.jp/hbblog/">
        <![CDATA[<p>こんにちは。CTOの馬場です。</p>

<p>今回もインフラエンジニア向けにちょっとした情報を紹介します。</p>

<p>インフラエンジニアをしていると、なんだかんだとメールを解析して処理をしたいシーンって多いですよね。 <br />
でも日本語のメールって色々大変ですよね。</p>

<p>特に大変なのがヘッダ部分。 <br />
ヘッダ部分はエンコードされていたり、長いと複数行にまたがったり、複数行の場合はデコードして結合してから処理したり・・・</p>

<p>今回はそんなあなた(=私)向けに、日本語メールのメールヘッダをうまく取り扱う方法を紹介します。</p>
]]>
        <![CDATA[<p>そんなわけでサンプルは下記のとおりです。 <br />
Pythonの標準ライブラリだけで実現できます。</p>

<p>第一引数にメールファイルのパスを指定すると、
From, To, Subjectを取得して表示します。</p>

<p>例: <code>python mail_header_decoder.py hoge.eml</code></p>

<pre><code>
#!/usr/bin/env python
#coding: utf-8

from email.Header import decode_header
from email.Parser import Parser
from sys          import argv,stdout
import re

NEWLINE=re.compile(r'(\r|\n|\r\n)$')
DEFAULT_ENCODING='iso-2022-jp'

def decode_header_multiline(message=None,name='',encoding=None):
    str_encoded=''
    for str_line in NEWLINE.split(message.get(name)):
        decoded_headers=decode_header(str_line)
        for parts in decoded_headers:
            str_encoded = str_encoded + parts[0]
            if encoding == None and  not parts[1] == None:
                encoding=parts[1]
    encoding=DEFAULT_ENCODING if encoding == None else encoding
    return str_encoded.decode(encoding)

def main():
    msg=Parser().parse(open(argv[1]))
    header_from   =decode_header_multiline(msg,'From')
    header_to     =decode_header_multiline(msg,'To')
    header_subject=decode_header_multiline(msg,'Subject')
    result="From: %s, To: %s, Subject: %s"%(
        header_from,
        header_to,
        header_subject,
        )
    stdout.write(result.encode('utf-8'))
    stdout.write('\n')

if __name__ == '__main__':
    main()
</code></pre>

<p>※Python 2.6.1で動作確認しています。 <br />
　デコード周りが若干怪しいような気がしないでもないですが、
　動作確認する限りはこれでうまく動いています。</p>
]]>
    </content>
</entry>

<entry>
    <title>超期待の新機能cgroups</title>
    <link rel="alternate" type="text/html" href="http://heartbeats.jp/hbblog/2010/12/cgroups.html" />
    <id>tag:heartbeats.jp,2010:/hbblog//2.41</id>

    <published>2010-12-06T13:53:21Z</published>
    <updated>2010-12-06T14:00:23Z</updated>

    <summary>こんにちは。CTOの馬場です。 今回もインフラエンジニア向けにちょっとした情報を...</summary>
    <author>
        <name>馬場俊彰</name>
        <uri>http://heartbeats.jp/</uri>
    </author>
    
        <category term="Linux" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://heartbeats.jp/hbblog/">
        <![CDATA[<p>こんにちは。CTOの馬場です。</p>

<p>今回もインフラエンジニア向けにちょっとした情報を紹介します。</p>

<p>今回は、先日参加した <a href="http://www.jp.redhat.com/event/2010/RedHatForum.html">レッドハットフォーラム 2010</a> で紹介されていた cgroups について紹介します。</p>

<p>※注：ざっくりとした理解で書いているので、誤りがあれば指摘してもらえると嬉しいです！</p>

<p>ここが理解が違う、こんな使い方もあるよ！などの情報は、twitterで
<a href="http://twitter.com/heartbeatsjp/">@heartbeatsjp</a>
<a href="http://twitter.com/hbstudy/">@hbstudy</a>
<a href="http://twitter.com/toshiak_netmark/">@toshiak_netmark</a>
あたりに教えてもらえると嬉しいです。</p>
]]>
        <![CDATA[<h1>cgroupsとは？</h1>

<p>cgroupsは Control Groupsの略で、
Linux kernelに組み込まれているリソース割り当て管理機能です。</p>

<p>「期待の新機能」とかタイトルつけましたが、
マージされたのは2.6.2xの頃のようなのでかなり時間は経っていますね。 <br />
RHEL的に新機能なので、ご愛嬌ということで。</p>

<p>プロセス(プロセスグループ)ごとに、下記のリソースの割り当てを変更できます。</p>

<ul>
<li>CPU</li>
<li>メモリ</li>
<li>ディスクI/O</li>
<li>ネットワークI/O</li>
</ul>

<h1>ざっくりとした使い方</h1>

<p>Linuxなので、ファイルベースで管理します。</p>

<ol>
<li>cgroupファイルシステムをマウントして</li>
<li>cgroupを作成して</li>
<li>CPU、メモリなどのリソース割り当てを定義して</li>
<li>PIDをcgroupに登録する</li>
</ol>

<p>といった感じです。</p>

<p>詳しくは
<a href="http://www.kernel.org/doc/Documentation/cgroups/cgroups.txt">公式ドキュメントの1.5 How do I use cgroups ?</a>
を見てください。</p>

<p>使い方は 2. Usage Examples and Syntax にとても丁寧に書いてあります。</p>

<h1>使いどころ</h1>

<p>レッドハットフォーラム 2010の会場でも宣伝していましたが、
KVMを利用した仮想化基盤でのリソース割り当て管理に最適です。</p>

<p>いままで難しかった「VMごとのディスク・ネットワークI/O制御」がついに実現します！</p>

<p>スゴいでしょう？スゴいですよね？スゴいんですよ。</p>

<h1>詳しい情報</h1>

<p>公式ドキュメントを読みましょう ;)</p>

<p><a href="http://www.kernel.org/doc/Documentation/cgroups/cgroups.txt">http://www.kernel.org/doc/Documentation/cgroups/cgroups.txt</a></p>

<p>最新のLinux kernelにはマージされていますが、
RHEL/CentOS 5.xでは利用できないようです。</p>

<p>RHEL6では利用できるそうなので、これからが楽しみですね。</p>
]]>
    </content>
</entry>

<entry>
    <title>unboundをrpmでインストール</title>
    <link rel="alternate" type="text/html" href="http://heartbeats.jp/hbblog/2010/10/unboundrpm.html" />
    <id>tag:heartbeats.jp,2010:/hbblog//2.38</id>

    <published>2010-10-27T05:07:13Z</published>
    <updated>2010-10-27T05:15:35Z</updated>

    <summary>こんにちは。CTOの馬場です。 今回もインフラエンジニア向けにちょっとした情報を...</summary>
    <author>
        <name>馬場俊彰</name>
        <uri>http://heartbeats.jp/</uri>
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="http://heartbeats.jp/hbblog/">
        <![CDATA[<p>こんにちは。CTOの馬場です。</p>

<p>今回もインフラエンジニア向けにちょっとした情報を紹介します。</p>

<p>今回は・・・本当にちょっとしたネタです。。。 <br />
unboundをrpmでインストールする方法をご紹介します。</p>

<p>unbound、いいですよね。楽で。 <br />
DNS RR非対応な点以外は、とてもイイ！</p>
]]>
        <![CDATA[<p>CentOS 5.5 64bitでやってみてます。</p>

<pre><code>
sudo yum -y install openssl-devel flex libevent-devel rpm-build gcc expect

wget http://www.unbound.net/downloads/unbound-1.4.6.tar.gz
sudo cp unbound-1.4.6.tar.gz /usr/src/redhat/SOURCES/.
tar zxf unbound-1.4.6.tar.gz
perl -pi -e 's/^Version:.*/Version: 1.4.6/' unbound-1.4.6/contrib/unbound.spec
perl -pi -e 's/^%configure (.*)/%configure $1 --with-libevent/' unbound-1.4.6/contrib/unbound.spec
sudo rpmbuild -ba unbound-1.4.6/contrib/unbound.spec
sudo rpm -ivh /usr/src/redhat/RPMS/x86_64/unbound-1.4.6-1.x86_64.rpm
</code></pre>

<p>sudoがNOPASSWDなら、切って貼るだけ。すばらしい！</p>

<p>(間違ってたら教えてください)</p>
]]>
    </content>
</entry>

<entry>
    <title>Proxy越しのDigest認証</title>
    <link rel="alternate" type="text/html" href="http://heartbeats.jp/hbblog/2010/10/proxydigest.html" />
    <id>tag:heartbeats.jp,2010:/hbblog//2.37</id>

    <published>2010-10-21T04:27:38Z</published>
    <updated>2010-10-21T04:40:18Z</updated>

    <summary>こんにちは。CTOの馬場です。 今回もインフラエンジニア向けにちょっとした情報を...</summary>
    <author>
        <name>馬場俊彰</name>
        <uri>http://heartbeats.jp/</uri>
    </author>
    
        <category term="Apache" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://heartbeats.jp/hbblog/">
        <![CDATA[<p>こんにちは。CTOの馬場です。</p>

<p>今回もインフラエンジニア向けにちょっとした情報を紹介します。</p>

<p>今回は一部で話題になっていた「Proxy越しのDigest認証」について、
ちょっとしたコツがあるのでノウハウを公開します。</p>
]]>
        <![CDATA[<p>前提として、</p>

<ul>
<li>Digest認証は、認証情報の中にURIを保持しています</li>
<li>Digest認証では、 <code>mod_auth</code> で <strong>「リクエストされたURI」</strong> と <strong>「認証情報の中のURI」</strong> の整合を確認しています</li>
</ul>

<p>と、いうことです。</p>

<p>なので、backendサーバで <code>mod_auth</code> が認証処理をする時に、
<strong>「リクエストされたURI」</strong> と <strong>「認証情報の中のURI」</strong> が一致している必要があります。</p>

<p>大抵の場合、次の図の構成になっていると思いますが、</p>

<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://heartbeats.jp/hbblog/assets_c/2010/10/proxy-digest01-26.html" onclick="window.open('http://heartbeats.jp/hbblog/assets_c/2010/10/proxy-digest01-26.html','popup','width=992,height=252,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://heartbeats.jp/hbblog/assets_c/2010/10/proxy-digest01-thumb-450x114-26.png" width="450" height="114" alt="proxy-digest01.png" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></a></span></p>

<p>これを、次の図のように変えることで両立させることができるようになります。</p>

<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://heartbeats.jp/hbblog/assets_c/2010/10/proxy-digest02-29.html" onclick="window.open('http://heartbeats.jp/hbblog/assets_c/2010/10/proxy-digest02-29.html','popup','width=1100,height=357,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://heartbeats.jp/hbblog/assets_c/2010/10/proxy-digest02-thumb-450x146-29.png" width="450" height="146" alt="proxy-digest02.png" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></a></span></p>

<p>ポイントは、RewriteするときにPT(PassThrough)を指定することです。 <br />
このフラグ指定により、 <code>mod_proxy</code> 通過後に <code>mod_auth</code> に渡されるリクエストURIが、
元(=backendが受け取ったそのもの)のままになります。</p>

<pre>　RewriteRule ^/proxied/(.*)$ /origin/$1 [PT]
</pre>

<p>別解として、proxyで認証情報をいじる方法(できればそのほうが設定が楽)もありそうですが、
まずは1つの方法として公開しておきます。</p>
]]>
    </content>
</entry>

<entry>
    <title>Skype4Pyを使ってコマンドラインからSkypeを使う</title>
    <link rel="alternate" type="text/html" href="http://heartbeats.jp/hbblog/2010/10/skype4pyskype.html" />
    <id>tag:heartbeats.jp,2010:/hbblog//2.35</id>

    <published>2010-10-04T15:47:42Z</published>
    <updated>2010-10-04T16:16:29Z</updated>

    <summary>こんにちは。CTOの馬場です。 今回もインフラエンジニア向けにちょっとした情報を...</summary>
    <author>
        <name>馬場俊彰</name>
        <uri>http://heartbeats.jp/</uri>
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="http://heartbeats.jp/hbblog/">
        <![CDATA[<p>こんにちは。CTOの馬場です。</p>

<p>今回もインフラエンジニア向けにちょっとした情報を紹介します。</p>

<p>今回は「Skype4Pyを使ってコマンドラインからSkypeを使う」です。 <br />
具体的には、ブックマークしたグループチャットに発言するプログラムを紹介します。</p>

<p>実際のところ、ちゃちゃっとセットアップしてしまえば、あとはコマンドラインからSkypeを利用できますので、ぜひ試してみてください。</p>
]]>
        <![CDATA[<p>参考: <a href="http://d.hatena.ne.jp/moriyoshi/20100926/1285517353">Linux上で動くSkype用のbotを作る方法 - muddy brown thang</a></p>

<p>困ったら上のURLを見てください。だいたい解決します。</p>

<p>と、投げっぱなしもなんなので、ざっくり手順を説明します。</p>

<ol>
<li>Skype4Pyをインストール</li>
<li>スクリプトを作成</li>
<li>実行</li>
</ol>

<p>という3ステップです。</p>

<p>※MacOSX 10.6でテストしています</p>

<h1>SKype4Pyをインストール</h1>

<p>コマンドラインから実行するだけ！簡単です。</p>

<pre>sudo easy_install Skype4Py
</pre>

<h1>スクリプトを作成</h1>

<p>今回は<code>PushMessage2BookmarkedChat.py</code>という名前でファイルを作成しました。</p>

<pre>
# coding: utf-8

import sys
import Skype4Py

def selectChatFromBookmark(skype,topic):
    for bookmarkedChat in skype.BookmarkedChats:
        if bookmarkedChat.Topic == topic:
            return bookmarkedChat

def main():
    skype = Skype4Py.Skype()
    skype.Attach()
    topic = unicode(sys.argv[1],'utf-8')
    message = unicode(sys.argv[2],'utf-8')
    chat = selectChatFromBookmark(skype,topic)
    chat.SendMessage(message)

if __name__ == '__main__':
    main()

</pre>

<h1>実行</h1>

<p>実行する前の注意事項</p>

<ul>
<li>Skypeを起動しておくこと</li>
<li>発言したいチャットをブックマークに登録しておくこと</li>
<li>スクリプトの初回起動時のみ認証画面がでるので、「次回以降も〜」を選ぶこと</li>
</ul>

<p>実行方法は以下の通り。</p>

<pre>
$ python PushMessage2BookmarkedChat.py "テス子の部屋" "こんにちはこんにちは！！"
</pre>

<p>ちなみに、MacOSXで実行する場合には、以下のように32bitモードで実行するための環境変数を設定する必要があります。</p>

<pre>
$ VERSIONER_PYTHON_PREFER_32_BIT=yes ¥  
 python PushMessage2BookmarkedChat.py "テス子の部屋" "こんにちはこんにちは！！"
</pre>

<p>コレを指定しないとSegmentation faultでプログラムが落ちますのでご注意。 <br />
どうもSkype4Pyの問題のようです。 </p>

<p>私の環境では環境変数指定で対応できていますが、回避できない場合は下記URLを参考にがんばってみてください ;)</p>

<p>参考： <a href="http://d.hatena.ne.jp/namaco35/20100403/1270263908"> Macports で入れた Python で Skype4Py を使う - SPEAKER BREAKA</a></p>
]]>
    </content>
</entry>

<entry>
    <title>覚えておきたいbashシェルスクリプトのオプション</title>
    <link rel="alternate" type="text/html" href="http://heartbeats.jp/hbblog/2010/09/bash.html" />
    <id>tag:heartbeats.jp,2010:/hbblog//2.34</id>

    <published>2010-09-26T23:15:55Z</published>
    <updated>2010-09-26T23:25:17Z</updated>

    <summary>こんにちは。CTOの馬場です。 今回もインフラエンジニア向けにちょっとした情報を...</summary>
    <author>
        <name>馬場俊彰</name>
        <uri>http://heartbeats.jp/</uri>
    </author>
    
        <category term="Linux" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://heartbeats.jp/hbblog/">
        <![CDATA[<p>こんにちは。CTOの馬場です。</p>

<p>今回もインフラエンジニア向けにちょっとした情報を紹介します。</p>

<p>今回は「覚えておきたいbashシェルスクリプトのオプション」です。</p>

<p>便利なものを3つ紹介します。</p>

<p>これを覚えておけば、シェルスクリプトとの付き合いが楽になること間違いなし！</p>
]]>
        <![CDATA[<h1>その1: eオプション</h1>

<p>まず1つめはeオプションです。</p>

<p>使い方としては <br />
<code>bash -e shellscript.sh</code> <br />
のように使います。</p>

<p>このオプションの効果ですが、man bashによると</p>

<blockquote>
  <p>-e オプションが与えられた場合、返り値は最後に実行されたコマンドの返り値となるか、あるいはコマンドの一時ファイルでエラーが起きた場合には偽となります。2番目の形式を用いた場合、終了ステータスは再実行されたコマンドの終了ステータスとなります。</p>
</blockquote>

<p>とのこと。。。よくわかりませんね。</p>

<p>平たく言うと、シェルスクリプトの一連の動作の中でエラー(exit codeが0以外)が発生した場合に、
そこで <strong>終了してエラーを報告</strong> してくれます。 <br />
これはシェルスクリプト群でのエラー処理に活用できます。</p>

<p>子シェル・孫シェルを使えば、
エラーが起きたら処理を中断してエラー処理(メールするなど)なども簡単に書けます。</p>

<p>例(バッククォートがうまく出なくて全角にしてます):</p>

<p><code><pre>
<code>#!/bin/bash</code></p>

<p>MAILTO="hoge@example.com"</p>

<p>RESULT=｀bash -e main.sh｀
if [ $? -ne 0 ]
then
    echo "${RESULT}"| mail -s "error at ｀hostname｀" ${MAILTO}
fi
</pre></code></p>

<h1>その2: xオプション</h1>

<p>2つめはxオプションです。</p>

<p>これは <br />
<code>bash -x shellscript.sh</code> <br />
のように使います。</p>

<p>このオプションの効果ですが、man bashによると</p>

<blockquote>
  <p>-x 単純なコマンドをそれぞれ展開した後、PS4を展開した値を表示し、その後にそのコマンドと展開した引き数を表示します。</p>
</blockquote>

<p>とのこと。。。やっぱりよくわかりませんね。</p>

<p>これは一言でいうと <strong>デバッグモード</strong> です。 <br />
シェルスクリプトで実行した結果を逐一表示してくれます。 <br />
実行してみれば、ぱっとみで何が起きているかすぐわかるので、ぜひやってみて体験してください。</p>

<h1>その3: norcオプション</h1>

<p>3つめはnorcオプションです。</p>

<p>このオプションの効果ですが、man bashによると</p>

<blockquote>
  <p>--norc シェルが対話的動作を行う場合に、個人用初期化ファイル ~/.bashrc の読み込み・実行を行いません。シェルがshとして起動された場合には、このオプションはデフォルトで有効になります。</p>
</blockquote>

<p>とのこと。</p>

<p>動作環境を安定させる意味でも、設定が環境に影響されるのは避けたいところです。 <br />
このnorcオプションとrcfileオプションを適切に指定することで、 
<strong>安定した環境でシェルスクリプトを動作させる</strong> ことができます。</p>

<p>ここでは3つ紹介しましたが、他にも便利なオプションがいっぱい！ <br />
続きは <code>man bash</code> してくださいね！</p>
]]>
    </content>
</entry>

<entry>
    <title>インフラエンジニア的Pythonのススメ</title>
    <link rel="alternate" type="text/html" href="http://heartbeats.jp/hbblog/2010/08/python.html" />
    <id>tag:heartbeats.jp,2010:/hbblog//2.33</id>

    <published>2010-08-31T00:36:22Z</published>
    <updated>2010-08-31T00:38:55Z</updated>

    <summary>こんにちは。CTOの馬場です。 なぜか月末更新と化していますが、今回もインフラエ...</summary>
    <author>
        <name>馬場俊彰</name>
        <uri>http://heartbeats.jp/</uri>
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="http://heartbeats.jp/hbblog/">
        <![CDATA[<p>こんにちは。CTOの馬場です。</p>

<p>なぜか月末更新と化していますが、今回もインフラエンジニア向けにちょっとした情報を紹介します。</p>

<p>今回は「インフラエンジニア的Pythonのススメ」です。</p>

<p>みなさん、業務自体・効率化のためになにがしかの言語を使っていると思います。</p>

<p>シェルスクリプト、perlあたりがメジャーだと思いますが、私はPythonをお勧めします。</p>
]]>
        <![CDATA[<h1>お勧めポイント1: batteries included</h1>

<p>Pythonには <code>batteries included</code> 哲学があり、
パッケージがとても充実しています。</p>

<p>監視系のプラグインなどを書くとき、
とても重宝するのです。</p>

<p>たとえば、smtp接続するプログラムはこれだけです
(エラー処理は別途書いてくださいね)。</p>

<pre><code>
import smtplib
s = smtplib.SMTP(host='mail.example.com',port=25,timeout=15)
s.helo('localhost')
s.quit()

</code></pre>

<p>メールを送るのも簡単です。
mailコマンドもいいけど、
Pythonでさくっと書けるのもいいですよ！</p>

<pre><code>
import smtplib
from email.MIMEText import MIMEText
from email.Utils import formatdate

body='this is mail body'
msg = MIMEText(body)
msg['Subject'] = 'this is subject'
msg['From'] = 'from@example.com'
msg['To'] = 'to@example.com'
msg['Date'] = formatdate()

s = smtplib.SMTP('mai.example.com',25)
s.sendmail('from@example.com', 'to@example.com', msg.as_string())
s.close()

</code></pre>

<p>※動かなかったらゴメンナサイね</p>

<h1>お勧めポイント2: Windowsバイナリが作れる</h1>

<p><a href="http://www.python.jp/Zope/articles/tips/py2exe">py2exe</a>
を使うと、PythonスクリプトからWindowsのバイナリを作成できます。</p>

<p>なんということでしょう！
Python実行環境をインストールしなくても、
Pythonが使えてバッチ運用したり監視プラグインを作ったりできるのです！</p>

<p>今まで悩みのタネだったWindowsサーバの管理自動化実現に大きく貢献しますね！</p>

<p>みなさんもPythonで楽しましょう！</p>

<p>(続く、かもしれない)</p>
]]>
    </content>
</entry>

<entry>
    <title>MySQLでBlackholeストレージエンジンを活用するのオマケ</title>
    <link rel="alternate" type="text/html" href="http://heartbeats.jp/hbblog/2010/07/mysqlblackhole.html" />
    <id>tag:heartbeats.jp,2010:/hbblog//2.30</id>

    <published>2010-07-29T23:26:21Z</published>
    <updated>2010-07-29T23:56:18Z</updated>

    <summary>こんにちは。CTOの馬場です。 ちょっと、いや、かなり間が空いてしまいましたが、...</summary>
    <author>
        <name>馬場俊彰</name>
        <uri>http://heartbeats.jp/</uri>
    </author>
    
        <category term="MySQL" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://heartbeats.jp/hbblog/">
        <![CDATA[<p>こんにちは。CTOの馬場です。</p>

<p>ちょっと、いや、かなり間が空いてしまいましたが、今回もインフラエンジニア向けにちょっとした情報を紹介します。</p>

<p>先日<a href="http://heartbeats.jp/hbstudy/2010/07/hbstudy13.html">hbstudy#13</a>が開催されました。</p>

<p>奥野さんからお話しいただいた「Art Of MySQL Replication」の中で紹介されていた、Blackholeストレージエンジンの活用のところで目からウロコだったので、補足してみます。</p>

<p>Blackholeストレージエンジンの活用方法としては、以下のものが有名でしょうか。</p>

<ol>
<li>クエリをキューイングする</li>
<li>暖気運転する</li>
<li>UDF(ユーザ定義関数)を利用して、Slave側でのみ処理を実行する</li>
</ol>

<p>1.については、書籍「4Gbpsを超えるWebサービス構築術」に解説されてますし、
2.についてはhbstudy直後に割と話題になっているので、
3.について紹介してみます。</p>

<p>といっても、やっていることは簡単で、
紹介されている通りmemcachedのデータ更新を
セミリアルタイムで実施するためのしくみとして活用しているようです。</p>

<p>うまく利用すれば、ランキングデータの更新/参照など
リアルタイム性の高いデータの更新/参照をうまく制御できるようになりそうです。</p>

<p>※実は常識だったらスミマセン</p>
]]>
        <![CDATA[<p>前提として、プログラムが下記の流れでデータを取得するように
組まれている必要があります。</p>

<ul>
<li>データが欲しい時、まずmemcachedをチェックする</li>
<li>memcachedにデータがない場合のみ、DBに問合せする</li>
</ul>

<p>プログラムからのデータ更新の流れは下記の通りになります。</p>

<ol>
<li>プログラムがDBにデータを登録(insert/update)</li>
<li>UDFを実行(トリガーにすることで自動化できる)</li>
<li>memcachedに最新データが登録される</li>
</ol>

<p>全slaveでUDFを実行しても無駄な可能性が高いので、
特定のslaveでのみ実行するUDFを作成するなど、
UDF側で工夫が必要そうです。</p>

<p>また、上記前提のプログラムだと、
memcachedでミスヒットしたタイミングで
DBに大量のクエリが発行される可能性があるので、
それを抑える仕組みを別途用意したほうがよさそうです。</p>

<p>例えば、データ取得は個々のプログラムインスタンスが行うのではなく、
API化してキューイングして特定商数のインスタンスが担当するなどなど。</p>

<p>と、いうわけで、目からウロコのUDF+Blackhole。
みなさまぜひ使ってみてください。</p>

<h1>参考</h1>

<ul>
<li><a href="http://journal.mycom.co.jp/articles/2008/04/28/mysql/004.html">Facebookのデータセンターに見るMySQL活用事例 - MySQLカンファレンス</a></li>
<li><a href="http://nippondanji.blogspot.com/2008/05/memcached_28.html">勝手に図解するmemcached</a></li>
</ul>
]]>
    </content>
</entry>

<entry>
    <title>mod_proxy_balancerでsorryサーバを実現する</title>
    <link rel="alternate" type="text/html" href="http://heartbeats.jp/hbblog/2010/05/mod-proxy-balancersorry.html" />
    <id>tag:heartbeats.jp,2010:/hbblog//2.27</id>

    <published>2010-05-10T12:46:06Z</published>
    <updated>2010-05-10T12:46:26Z</updated>

    <summary>こんにちは。CTOの馬場です。 今回もインフラエンジニア向けにちょっとした情報を...</summary>
    <author>
        <name>馬場俊彰</name>
        <uri>http://heartbeats.jp/</uri>
    </author>
    
        <category term="Apache" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://heartbeats.jp/hbblog/">
        <![CDATA[<p>こんにちは。CTOの馬場です。
今回もインフラエンジニア向けにちょっとした情報を紹介します。</p>

<p>apache2.2から導入された<code>mod_proxy_balancer</code> 、便利ですよね。 <br />
今回はその<code>mod_proxy_balancer</code>でsorryサーバを実現する方法を紹介します。</p>
]]>
        <![CDATA[<p>と、いっても方法は簡単。</p>

<p>BalancerMemberの指定時に、statusを指定することで実現します。</p>

<p>1.2.3.4、1.2.3.5がサービスのサーバで、1.2.3.6がsorryサーバの場合は下記のように設定します。</p>

<pre>
 ProxyPass / balancer://hotcluster/
 &lt;Proxy balancer://hotcluster&gt;
     BalancerMember http://1.2.3.4:8009 loadfactor=1
     BalancerMember http://1.2.3.5:8009 loadfactor=2
     # The below is the hot standby
     BalancerMember http://1.2.3.6:8009 status=+H
     ProxySet lbmethod=bytraffic 
 &lt;/Proxy&gt;
</pre>

<p>・・・と、公式ドキュメントに書いてあります。公式ドキュメントは偉いですね。 <br />
<span style="color:red;"><b>※日本語版には書いてありませんので、英語版を読みましょう！※</b></span></p>

<p>from <a href="http://httpd.apache.org/docs/2.2/en/mod/mod_proxy.html#proxypass">Apache 2.2 Document / ProxyPass Directive</a></p>

<p>パラメータで色々と細かく設定できますのでご参考まで。</p>
]]>
    </content>
</entry>

<entry>
    <title>プリンタで印刷できない大きなサイズを印刷する方法</title>
    <link rel="alternate" type="text/html" href="http://heartbeats.jp/hbblog/2010/04/post.html" />
    <id>tag:heartbeats.jp,2010:/hbblog//2.25</id>

    <published>2010-04-15T03:00:28Z</published>
    <updated>2010-04-15T03:13:26Z</updated>

    <summary>こんにちは。CTOの馬場です。 今回もインフラエンジニア向けにちょっとした情報を...</summary>
    <author>
        <name>馬場俊彰</name>
        <uri>http://heartbeats.jp/</uri>
    </author>
    
        <category term="仕事術" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://heartbeats.jp/hbblog/">
        <![CDATA[<p>こんにちは。CTOの馬場です。
今回もインフラエンジニア向けにちょっとした情報を紹介します。</p>

<p>今回はA1、A2など、普通のプリンターでは対応していない大きなサイズの図や画像を印刷する方法をご紹介します。</p>

<p>ポスター展示の作成や、A3/A4では細かくて見えない大きな図を印刷するのに有効です。</p>

<p>プリンタの機能で「ポスター印刷」や「タイル印刷」と呼ばれるものがあればそれを使います。
また、Acrobat(Readerではないほう)の機能でもタイル印刷が可能なようです。 <br />
しかし、ウチにはそんな贅沢!?なものはありません。</p>

<p>と、いうわけで、工夫でなんとかしてみましょう。</p>
]]>
        <![CDATA[<p>A2縦のものを、A3横x2で印刷する前提で説明します。</p>

<h1>1. 画像に変換する</h1>

<p>まず、なんとかして図を画像に変換します。</p>

<p>元ネタがOpenOffice DrawやMicrosoft Visioなどの場合、名前をつけて保存やエクスポートで画像を出力できます。</p>

<p>このとき、サイズは大きいままでokです。</p>

<h1>2.(Windows) ペイントで開く</h1>

<p>出力した画像をおもむろにペイントで開きます。</p>

<h1>3.ページ指定する</h1>

<p>メニューから <em>ファイル</em> ＞ <em>ページ設定</em> を開きます。</p>

<ul>
<li>用紙＞サイズ: A3</li>
<li>印刷の向き: 横</li>
<li>余白: 適宜調整</li>
<li>拡大縮小＞適合 1 x 2 ページ</li>
</ul>

<p>上記を設定してOK。</p>

<h1>4.印刷</h1>

<p>印刷してみましょう。</p>

<p>はい、簡単ですね。 <br />
あとはカッターや裁断機でキリハリしてください。</p>

<p><strong><em>※もっと楽な/スマートな方法をご存知の方は教えてください！</em></strong></p>
]]>
    </content>
</entry>

<entry>
    <title>仕事を10倍速くするコマンドライン操作Tips</title>
    <link rel="alternate" type="text/html" href="http://heartbeats.jp/hbblog/2010/03/10tips.html" />
    <id>tag:heartbeats.jp,2010:/hbblog//2.23</id>

    <published>2010-03-22T01:10:15Z</published>
    <updated>2010-03-23T01:31:51Z</updated>

    <summary>こんにちは。CTOの馬場です。 今回もインフラエンジニア向けにちょっとした情報を...</summary>
    <author>
        <name>馬場俊彰</name>
        <uri>http://heartbeats.jp/</uri>
    </author>
    
        <category term="Linux" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://heartbeats.jp/hbblog/">
        <![CDATA[<p>こんにちは。CTOの馬場です。
今回もインフラエンジニア向けにちょっとした情報を紹介します。</p>

<p>今回はコマンドラインの操作を10倍速くして、コマンドラインを楽しくTipsをご紹介します。 <br />
もちろん独断と偏見で選んでいます。 <br />
これから挙げる5つのコマンドを覚えるだけで、コマンドライン操作は10倍（当社比）速くなります！ <br />
この5つを使っていない人が周りにいたら、ぜひ教えてあげましょう！</p>

<p><em>諸注意</em></p>

<ul>
<li>ショートカットキー表記の<code>+</code>は同時押しの意味です。</li>
<li>bashで動作確認しています</li>
</ul>
]]>
        <![CDATA[<h1>前のコマンド：<code>↑</code>または<code>Ctrl+p</code></h1>

<p>コマンドラインで<code>↑</code>または<code>Ctrl+p</code>を押すと、直前に実行したコマンドを呼び出すことができます。</p>

<pre>
baba@dynass:/$
</pre>

<p>この状態でコマンドラインで<code>↑</code>または<code>Ctrl+p</code>をタイプすると・・・</p>

<pre>
baba@dynass:/$ tail /var/log/messages
</pre>

<p>直前に実行したコマンドが表示されます。 <br />
この状態で更に<code>↑</code>または<code>Ctrl+p</code>をタイプすると・・・</p>

<pre>
baba@dynass:/$ cat /etc/resolv.conf
</pre>

<p>さらにその前のコマンドが表示されます。</p>

<ul>
<li>何度も同じコマンドを入力するとき、前のコマンドを少し修正して使いたいときにとても便利です</li>
<li>後述の行頭移動や行末移動と合わせて利用するとすばらしい！</li>
</ul>

<h1>補完：<code>TAB</code></h1>

<p>コマンド名、パスは、ちょっと打って<code>TAB</code>キーをタイプすると補完できます。</p>

<ol>
<li>入力ミスがなくなる</li>
<li>タイプ数が少なくなる</li>
</ol>

<p>という2つの利点があるのでぜひ常用してください。</p>

<pre>
baba@dynass:/$ ls /u
</pre>

<p>この状態で<code>TAB</code>をタイプすると・・・</p>

<pre>
baba@dynass:/$ ls /usr/
</pre>

<p>こうなります。</p>

<p>ちなみに、候補が複数ある場合、<code>TAB</code>キーを2回タイプすると候補が表示されます。</p>

<pre>
baba@dynass:/$ ls /m
</pre>

<p>この状態で<code>TAB</code>を2回タイプすると・・・</p>

<pre>
baba@dynass:/$ ls /m
media/ mnt/   
</pre>

<p>こうなります。</p>

<h1>履歴探索：<code>Ctrl+r</code></h1>

<p>コマンドラインで実行した履歴を一瞬で探索できます。 <br />
コレを覚えると操作が<strong>冗談ではなく10倍速くなります！</strong></p>

<pre>
baba@dynass:/$ 
</pre>

<p>この状態で<code>Ctrl+r</code>と打つと・・・</p>

<pre>
baba@dynass:/$ 
(reverse-i-search)`': 
</pre>

<p>履歴探索モードに入ります。 <br />
このまま、実行したコマンドラインの一部をタイプすると・・・ <br />
（今回は<code>ta</code>とタイプしました）</p>

<pre>
(reverse-i-search)`ta': tail -f /var/log/cron
</pre>

<p>一番近い履歴が表示されます。
この状態で更に<code>Ctrl+r</code>をタイプすると・・・</p>

<pre>
(reverse-i-search)`ta': tail -f /var/log/messages
</pre>

<p>遡って探索してくれます。 <br />
この状態で<code>TAB</code>をタイプすると、コマンドラインに過去のコマンドが入力された状態になります。</p>

<pre>
baba@dynass:/$ tail -f /var/log/messages
</pre>

<p>そうしたら<code>Enter</code>をタイプして実行しましょう。</p>

<p>設定ファイル編集→デーモンの再起動→ログ確認 などを繰り返す場合、この履歴探索を使うと操作が圧倒的に速くなります。</p>

<ul>
<li>この<code>Ctrl+r</code>と、次の<code>Ctrl+a</code>、<code>Ctrl+e</code>を組み合わせると更にコマンドライン操作が楽になりますよ！</li>
<li>うまく探索できなかった、遡りすぎてしまった場合には、<code>Ctrl+c</code>でいったんリセットしましょう</li>
</ul>

<h1>カーソル移動：<code>Ctrl+a</code>, <code>Ctrl+e</code></h1>

<ul>
<li><code>Ctrl+a</code>：カーソルを行頭に移動する（Homeキーと同じ）</li>
<li><code>Ctrl+e</code>：カーソルを行末に移動する（Endキーと同じ）</li>
</ul>

<p>履歴探索結果からスタートしてみましょう。</p>

<pre>
(reverse-i-search)`ta': tail -f /var/log/messages
</pre>

<p>この状態で、<code>Ctrl+e</code>をタイプすると・・・</p>

<pre>
baba@dynass:/$ tail -f /var/log/messages
</pre>

<p>カーソルが行末に移動します。 <br />
そのままパイプして<code>grep</code>につなげたりできます。便利！</p>

<pre>
baba@dynass:/$ tail -f /var/log/messages | grep kernel
</pre>

<p>行頭移動を使うと、同じファイルに対して利用するコマンドを簡単に変更できます。 <br />
ぜひ利用してください！</p>
]]>
    </content>
</entry>

</feed>

