fluentdを勉強中

最近はlog collectionというと fluentd が話題らしいというので、少し触り始めている。 多少は分かってきたように思うので理解したことと、理解できていないところをまとめてみようと思う。

fluentdとは何か

オフィシャルサイトには"tool to collect events and log"と書いてある。 要するに、サーバー群から継続的に情報を吸い上げるための仕組みを提供するdaemonである。

この「情報をかき集める」という枠組みは今時のサーバーサイドでは頻出パターンだ。 データベースサーバ、アプリケーションサーバー、フロントエンドキャッシュサーバー, ...と役割分担をするのが普通だし、 アプリケーションサーバーだって負荷分散のために複数インスタンスを持つのが当たり前だ。 そしてこれらサーバー群をきちんと管理するためには様々な情報をかき集めてきて一カ所に保存したり集約したりする必要がある。 たとえば、

  • アプリケーションサーバーのログを全インスタンスから集めて一覧可能にする
  • キャッシュサーバーのヒット情報を集めて解析する
  • 各マシンのディスク空き容量を定期的に集めて不足しそうなら警告を出す

これらはいずれも一見するとそれほど難しい処理には思えない。scpとcronでもできそうだ。 しかしデータ転送の際の失敗をどうやって扱うのかを考えだすと、自明ではなくなる。 定時バッチ処理ではなくリアルタイムに処理し続けるようにしたいと考えると問題はさらに難しくなる。 失敗時は適切な時間を置いて再試行するように。通信エラーで情報が失われたりしないように。

fluentdはこの頻出パターンを司り、上記のような困難を処理してくれる。 そして、パターンの個々のバリエーションに対応できるようにデータ入力、加工、出力のそれぞれをプラグインなどで拡張可能になっている。

また、異なるデータソースからの情報をバラバラにあつめるのではなくfluentdという1つのシステムにつなぐことそのものにも意味がある。 データソースをまたいだリアルタイムの解析も容易になる。

よく分かってないこと1: システム監視

fluentdだけでモニタリングシステムを構築できるだろうか。すべきだろうか。

情報をかき集めて変換するという点でシステム監視はfluentdのカバーする範囲に思える。 一方でシステム監視の世界では nagiosZABBIX)が長く使われている。 仮にこうした「fluentd以前」からのソリューションを置くとしても最近出た((<Sensu|URL:sensuapp.org) ももた話題になっているようだ。 こういうのとfluentdは棲み分けるべきなんだろうか。それともfluentdに集約してしまうべきなんだろうか。

可能ならシステムの中に似たようなモジュールは2つ置きたくない。fluentdを中心としたモニタリングは可能そうだし、 実際に構想している人もいる 。 でも、もし餅は餅屋としてシステム監視専門のモジュールならではのfluentdでカバーできない利点があるならそれは知りたい。

よく分かってないこと2: アーキテクチャ

Sensuやなんかだと、データ転送をreliableにするためにRabbitMQを使っている。 一方fluentdのforwardingは特にそういうミドルウェアは使ってない。fluentd自身ががんばってエラー対応している。

こういうのは別途ミドルウェアでqueueを使うものだと言う思い込みがあったのでfluentdのやり方は見慣れない感じがする。 この違いはどういう設計判断によるものなんだろう。

お返事

疑問を書いてみたら偉い人から お返事 来た。

MQ使わないのはやっぱりそういうことか。モニタリングは、うん、もうちょっと考えてみよう。

環境に優しい難読コード

ぼちぼち忘年会やクリスマス会のシーズンとなってきた。

そんなパーティーの1つに出欠の連絡をしなければならない場面があったのだけど、どうやらネタ回答を期待されているらしかったので次のように回答した。

puts [[->(&f){->(n){f[f[f[f[f[f[f[f[f[f[f[f[f[f[n]]]]]]]]]]]]]]}},->(&f){->(n){f[f[f[f[f[n]]]]]}},
->(&f){->(n){f[f[f[f[f[f[f[f[n]]]]]]]]}},->(&f){->(n){f[f[f[f[f[f[f[f[f[f[f[f[f[f[f[n]]]]]]]]]]]]]]]}},
->(&f){->(n){f[f[f[f[f[f[f[f[n]]]]]]]]}},->(&f){->(n){f[f[n]]}},->(&f){->(n){f[f[f[f[f[f[f[f[f[f[f[f[f[f[n]]]]]]]]]]]]]]}},
->(&f){->(n){f[f[f[f[f[n]]]]]}},->(&f){->(n){f[f[f[f[f[f[f[f[n]]]]]]]]}},->(&f){->(n){f[f[f[f[f[f[f[f[f[f[n]]]]]]]]]]}},
->(&f){->(n){f[f[f[f[f[f[f[f[f[f[n]]]]]]]]]]}},->(&f){->(n){n}}].map{|x|x[&:succ][0]}.map(&("%x".method("%"))).join].
pack("H*").unpack("U*").pack("U*").encode(Encoding.default_external)

難解コードとかゴルフとかは苦手なんだけど、相手のためを思って知恵を絞ればできるもんだね。

難読コーディングとしては割と定番の素材を使っていて読解難度はそう高くない。ただ、呼び出し可能オブジェクト技法の数々や、表示側のエンコーディングに依存しない環境(env(1)的な意味で)に優しい設計でありつつ"Encoding::UTF_8"と書くのはあくまでも避けたあたりについては我ながら満足している。

Ubuntu 12.04 preciseをaufs rootにした

表題のようにaufsをroot filesystemとしてマウントしてみたので、手順をメモする。

経緯

最近 DNA940 という面白い機器を手に入れた。なんでも本来は産業用機器のベースとして使用することを想定した機体で、中身はx86ベースの基板にGbE×4やらコンソールポートやらいろいろついている。 Debianが動いたという話も耳にする。

これにソフトウェアルーターを組み合わせて自宅ネットワークのルーターを好きなように組む、という野望を抱いたのがそもそもの動機である。

ところで、DNA940は2.5in HDDを組み込めるのでそれをメインディスクにしても良いのだけど、可動部品は可能な限りなくしたいのでCFのほうが嬉しい。しかしながら、普通にDebianUbuntuのシステムをCFで動かすとすぐに書き込み上限に引っかかるのは目に見えている。 そこでaufsでext4の上にtmpfsをオーバーレイしたものをroot fsにしたい、というのが今回の話だ。

いきなり実機は怖いので、まずはVMWare Fusion上の仮想マシンでやってみる。

手順

同じような需要は各所に有ると見えて、手順は Ubuntuのヘルプサイト にまとまっている。意外と簡単だった。

  1. 仮想マシンを作成する。メモリを1GB、ディスクを2GB割り振って、 ディスクは丸ごとext4のルートファイルシステムとした。Swap領域は作成しない。

  2. Ubuntu Precise (x86-64 Server Edition)をインストールする。 前述のヘルプページではLive CDからインストールするように書いてあるが、 これだとデスクトップ版がインストールされるような気がした。 そこで、普通にサーバー版のインストールディスクを用いた。

  3. 以下はヘルプページの手順に従った。

    • % sudo aptitude install aufs-tools
    • % sudo bash -c "echo aufs >> /etc/initramfs-tools/modules"

    ここでヘルプページに書いてあるrootaufs Scriptを /etc/initramfs-tools/scripts/init-bottom/__rootaufs に保存した上で、

    • % sudo chown root:root /etc/initramfs-tools/scripts/init-bottom/__rootaufs
    • % sudo chmod 0755 /etc/initramfs-tools/scripts/init-bottom/__rootaufs
    • % sudo update-grub
    • % sudo-initramfs -u

    とする。

    initrdまわりはあまり詳しくなかったのだけど、要はこの scripts ディレクトリ以下にあるスクリプト群はinitrd.imgの中にコピーされて、起動時にinitrdで動いている段階で実行されるということらしい。 スクリプトを見る感じ、実行時の ${rootmnt} 変数とかが見慣れないものの大体やってることは予想通りだ。tmpfsをマウントして、元のrootを他のマウントポイントにどかしてreadonlyでremountして、それからaufsで両者を重ねる。

  4. 再起動する。 さっきのスクリプトカーネルの引数にaufs=tmpfsを渡したときのみ発動するように書かれているので、起動時に引数を手入力した。

  5. 起動後 mount が期待通りであることを確認する。

    なお、ヘルプページにも書かれているように、rootaufsだとdhclient3がapparmorに引っかかって動かないようだ。おまけにDHCPを何度か再試行する間、起動を待たされる。私の用途ではDHCPは必要ないのでIPはstaticに割り振ることにした。 ログを見る限り、この問題って起動タイミングの関係上rootfsの移動によってdhclient3のリンクされるライブラリのパスがapparmorが思ってるやつとずれてしまうのが原因みたいね。dhclient3をprelinkとかすれば解決するんだろうか。まー今回は関係ない。

  6. 次は、常にaufs=tmpが渡るようにGrubを設定する。

    ヘルプページに書いてあるのはたぶんGrub1の設定だ。今回の環境の場合はGrub2なので少し手順が異なる。 といっても、やることは簡単で /boot/grub/menu.lst の代わりに /etc/default/grubGRUB_CMDLINE_LINUX_DEFAULT に"aufs-tmpfs"を設定するだけだ。 設定した後は sudo update-grub/boot/grub/grub.cfg を再生成する。

    以上により、起動時に自動的にaufs-tmpfsが引数に渡るように /boot/grub/grub.cfg が設定され、かつカーネルを入れ替えたりして grub.cfg が再生成されても設定が保たれるようになった。

さよならピアソン

ピアソン桐原のピアソングループ離脱にともない、 ピアソンの技術書和書は書店在庫限り だそうだ。

聞いたとき、これは日本のソフトウェア開発にとってとんでもないことだと思った。それ以前に私にとっても困ったことだ。だから、在庫限りであるならばそれを押さえなければならないということで急ぎ書店へと向かった。 しかし、見渡しても買うべき本をそれほど見つけられない。これは何故だろう。

なるほど、古典的名著は数多くある。『達人プログラマ』『アナリシスパターン』『リファクタリング』『計算機プログラムの構造と解釈』『Effective C++』『Effective Java』『人月の神話』『テスト駆動開発』『詳解UNIXプログラミング』『プログラミング言語の概念と構造』『モダン オペレーティング システム』『分散システム―原理とパラダイム』『Java仮想マシン仕様』。どれもその技術分野を触る人なら最低限読んでおく必要のある本ばかりだ。そして、『Modern C++ Design』。

Modern C++ Design―ジェネリック・プログラミングおよびデザイン・パターンを利用するための究極のテンプレート活用術 (C++ In‐Depth Series)

Modern C++ Design―ジェネリック・プログラミングおよびデザイン・パターンを利用するための究極のテンプレート活用術 (C++ In‐Depth Series)

これはC++の歴史をかえた本だ。それに個人的にも、この本をたまたまふらりと入った六本木の青山ブックセンターの新刊棚で手に取らなかったら私はソフトウェア開発を職業にしてない。 そうだとも、あの華々しいC++翻訳書の数々を覚えているだろうか。だからこそ私だって、この度のニュースを「とんでもないことだ」と戦慄したのだった。

だが、買うべき本がない。私に関して言えば上のような基本中の基本の本はもう買ってある、というのもあるけど、それだけではない。

  • C++とかCORBAがそこら中で使われてる時代でもないし
  • Effective Javaとか、開発文化じゃなくて純粋技術の話は読みやすいから原書でもいいし
  • SICPとか原書の方が読みやすいとすら言われるし
  • タネンバウム先生の本は分厚いから、まー売れなそうだし、それを仕事で触るのでなければ必須でもないし
  • そして、Javaオブジェクト指向デザインもコンピュータサイエンスも、ピアソンのラインナップの後続にあたる最近の「must have」な本はみんな翔泳社オライリージャパンが翻訳している

これは売れなかろう。技術書から撤退という判断はやむなしなのかもしれぬ。

英語が苦手な人でも読んでほしくて惜しまれるのは

ぐらいか。

『東京市制概要』

東京市制概要 表紙

ふらりと立ち寄った古書店で昭和十年版『東京市制概要』というのを見つけて買ってきた。結構役に立ちそうだ。

アメリカ系の会社で地図をやっていると「なんでTokyo Cityってないの?」みたいな知識がたまに必要になる。なんでかというと戦時体制がどうたらという話になるけど、この辺の知識は全部二次、三次の資料に基づく受け売りだ。実際のところ府市統合以前がどうで、その後どうなってという正確な知識には欠けている。その辺きちんと知りたいよなーと思っていたところにこの本との出会いである。これだから古書店巡りはやめられない。ぼちぼち読んでいこうと思う。

ぐんまRuby会議01で発表した

ぐんまRuby会議01 で発表してきた。

講演依頼では、「Rubyを通じて見てきた世界、ソフトウェア開発者としての世界観を語ってほしい」とのことであった。そうすると、私がRubyに関わっている理由は2つだ。

  • 個人的にRubyが好きで手に馴染んでいて、これからも継続してほしいから
  • 私が望む世界が実現されるための手段としてRubyは有効であり、Rubyに発展してほしいから

上についていえば好きなものを好きなのにそんなに理由はない。たぶん「プログラマのあるサブセットにとって自然で親しみやすく」というMatzの言語デザイン意図にうまくはめられたというだけだろう。 下についていうと、Rubyはあくまでも手段であり話題の主役ではない。が、Matzの意図についてはMatzがすでに多くを語っているし、私は下について話すことにした。内容は 過去の記事 +α。

ある人の世界観を共有する手段としては、背景にある読書歴というのが欠かせない。またそれらの書籍を通じてよりハイコンテキストな情報を限られた時間で伝達できる。だから今回はいろいろな書籍を挙 げながらMad web programmerと私の望む世界とそこに至るための私自身の取り組みについて話した。

スライドだけ見ても意味不明で、むしろ誤解を招きかねない部分もあるのでスライドの公開予定はない。ただ、その中では次のような書籍に言及した

正直なところ、あの内容を話すのも準備するのもかなりしんどい。それで若干準備し切れていない部分もあった。需要があればまたどこかで話したいと思う。

光目覚まし時計

光目覚まし時計というものを初めて買った。騒音でなく光によって目覚めを図るというものだ。2ヶ月ばかり使っている限りではなかなか好印象だ。OKIROという直球な名前も一周回ってセンスよくすら感じる。定価は39,000円だけど、Amazonではもっと安く売ってたし。

私はもともと睡眠時間が長いたちで、日常生活を送っているとなかなかその体質に足るだけの睡眠時間を毎日とることは難しい。 それで起きられなくて目覚まし時計に頼る訳だけれども、生半可なものでは起きられない。新しい目覚まし時計を買うとしばらくは起きられるが、一週間ぐらい経って新しい機体の操作に慣れると半ば眠ったまま無意識に止めてそのまま寝続けてしまう。そういうわけで、爆音目覚ましだとか音色が豊富な(=その音に慣れるのを防ぐ)目覚ましだとかをいろいろと試してそれなりに効果は得たものの完璧とはいかなかった。

それに比べると現在はOKIROによって次のように改善されている。

  • 指定した時刻よりも少し前から徐々に明るくなって日の出を再現する。明るくなったら起きるという自然な仕組みに基づいているので目覚めがすっきりする。どのぐらいの時間をかけて明るくしていくかは調整できる。
  • 従来は、目覚まし時計の音がまだ眠っている他の人に五月蝿くて迷惑だろうと考えて、早めに音を止めてしまっていた。しかし、それが為に二度寝を防げないことがあった。光であれば音波よりも遥かに指向性が強いので自分にしか影響しない。だから安心して、起き上がって着替えて顔を洗うまで目覚まし時計を放置しておける。目覚まし時計を止めた状態で二度寝という最悪のパターンを避けられる。
  • 個人的には音よりも光の方が目覚めやすい模様。これは体質によるだろうけれども、私は慣れればある程度大きな音が鳴っていても寝られる。けれども1時間明るい光を間近で照らされるとさすがに目が覚める。

ちなみにメーカーは読書灯としても使用可能とか時差ぼけの解消に有効とか謳っているけれども、こちらは試していないのでわからない。Amazonでの評を見ると読書灯としては光がどぎつくて目に厳しいとかいう意見もある。 光の照射面積が狭いという意見にはあまり賛同しない。私も寝相は良くないけれども、上下逆さになるとかベッドから落ちて寝ているような寝相でなければ有効範囲内には頭があるだろうと思われる。