世界線航跡蔵

Mad web programmerのYuguiが技術ネタや日々のあれこれをお送りします。

2014年02月02日

fluentdを勉強中

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

fluentdとは何か

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

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

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

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

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

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

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

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

情報をかき集めて変換するという点でシステム監視はfluentdのカバーする範囲に思える。 一方でシステム監視の世界ではnagiosZABBIXももた話題になっているようだ。 こういうのとfluentdは棲み分けるべきなんだろうか。それともfluentdに集約してしまうべきなんだろうか。

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

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

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

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

お返事

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

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

トラックバック

http://yugui.jp/articles/879/ping

現在のところトラックバックはありません

コメント閲覧/投稿

2013年11月30日

環境に優しい難読コード

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

そんなパーティーの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"と書くのはあくまでも避けたあたりについては我ながら満足している。

トラックバック

http://yugui.jp/articles/878/ping

現在のところトラックバックはありません

コメント閲覧/投稿

2013年11月09日

Ubuntu 12.04 preciseをaufs rootにした

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

経緯

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

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

ところで、DNA940は2.5in HDDを組み込めるのでそれをメインディスクにしても良いのだけど、可動部品は可能な限りなくしたいのでCFのほうが嬉しい。しかしながら、普通にDebianやUbuntuのシステムを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が再生成されても設定が保たれるようになった。

トラックバック

http://yugui.jp/articles/877/ping

現在のところトラックバックはありません

コメント閲覧/投稿

ご案内

最近の記事

タグ一覧

過去ログ

  1. 2014年02月
  2. 2013年11月
  3. 2013年08月
  4. 2013年04月
  5. 過去ログ一覧

フィード

フィードとは

その他

Powered by "rhianolethe" the blog system