Raspberry PiでFluentdを立ち上げてTDにデータを流してみた話
一ヶ月程前に同僚である @doryokujin 先生からRaspberry Pi(面倒なので以下Pi)を頂いたのだけど、Piに必要なSDカードが手元に無くてすっかり放置していたのですが、満を持してSDカードを買ってきたのでちょっとPiを立ち上げてみた。という話を備忘録的に。
必要なもの(というかこれで間に合った、的なもの)
- USBケーブル
- RCAケーブル
- USBキーボード
- LANケーブル
- SDカード(SDHD 8GB)
startxとか叩かなければUSBマウスは要らない。
Piの立ち上げ
- 準備に使った環境はMac OX 10.8.5
- SDカードは挿してある状態
- SDカードの/dev/disk番号を確認してunmount
$ diskutil list /dev/disk0 : /dev/disk4 #: TYPE NAME SIZE IDENTIFIER 0: FDisk_partition_scheme *7.8 GB disk4 1: DOS_FAT_32 NO NAME 7.8 GB disk4s1 $ diskutil unmountDisk /dev/disk4 Unmount of all volumes on disk4 was successful
- OSにはRaspbianを選択。2014-01-07-wheezy-raspbian.zip を落としてきて展開したimgファイルをddで書き込み。かなり時間がかかる
$ sudo dd bs=1m if=~/Downloads/2014-01-07-wheezy-raspbian.img of=/dev/disk4 Password: 2825+0 records in 2825+0 records out 2962227200 bytes transferred in 1071.833726 secs (2763700 bytes/sec)
- ddでイメージが書き込まれたSDカードをPiに挿してMBPとか適当なやつからUSBケーブルをつなげて電源を供給して上げれば起動
- 自宅にディスプレイが無いので、あまり使われていないアナログテレビを用いて動作確認。RCAケーブルの黄色いやつ(映像用)をつなげれば滲んだ雰囲気の画面で確認出来る
- Setting画面が表示されてユーザーのパスワードの変更とか色々できるので、やりたい場合はやる感じで。SSHの設定に関しては失敗してたけどひとまず先に進む
- Settingを終えるとlogin promptが表示されるのでlogin。sshdも起動していたのでログインしてみたら普通に入れた。
- Rubyは1.9.3, Javaは1.7が入っていて良い感じ
Fluentdとかを入れてTDにデータを流し込んでみる
- Fluentdの安定版であるtd-agent(http://docs.fluentd.org/articles/install-by-deb)入れようかと思ったけど、何となくgemから入れてみた。FluentdはC拡張のビルドが発生するので、ruby-dev的なものを入れておく
$ sudo aptitude install ruby-dev $ sudo gem install fluentd
- TreasureDataにデータを入れるのでfluent-flugin-tdも。というか事前にTDのアカウントが必要なので適当に作っておくのが前提
$ sudo fluent-gem install fluent-plugin-td
- fluentdのconfファイルを作成(/home/pi/fluentd/fluent.confとか)。入力はin_forwardだけの超シンプルな設定。出力はout_td。
<match td.*.*> type tdlog apikey <replace this with your TD API key!> auto_create_table buffer_type file buffer_path /home/pi/fluentd/td </match> <source> type forward </source>
- fluentd起動
$ fluentd -c /home/pi/fluentd/fluent.conf
fluentdデーモンとして起動したい場合は以下のようにしても良いかも。
$ export FLUENTD_ROOT=/home/pi/fluentd $ fluentd -c $FLUENTD_ROOT/fluent.conf --log $FLUENTD_ROOT/fluentd.log --daemon $FLUENTD_ROOT/fluentd.pid
- fluent-catとかfluent-postコマンドなどでレコードを放り込んでみる
$ echo '{"name":"pi", "age":49}' | fluent-cat td.pidb.test
- td tablesコマンドで件数を確認
$ td tables pidb +----------+-------+------+-------+--------+---------------------------+---------------------------+-----------------------+ | Database | Table | Type | Count | Size | Last import | Last log timestamp | Schema | +----------+-------+------+-------+--------+---------------------------+---------------------------+-----------------------+ | pidb | test | log | 1 | 0.0 GB | 2014-02-15 23:17:20 +0900 | 2014-02-15 23:14:15 +0900 | age:long, name:string | +----------+-------+------+-------+--------+---------------------------+---------------------------+-----------------------+ 1 row in set
- td query コマンドでクエリーを投げてみる
$ td query -w -d pidb 'select name, age from test' : Status : success Result : +------+-----+ | name | age | +------+-----+ | pi | 49 | +------+-----+ 1 row in set
見返してみると、記事にするほどの内容でも無い気がしてきたけど、勢いで書いたのでまぁ良いのではと。
PiにはGPIOとか付いているのでセンサー的なものをくっつけて、そこからの情報をTDに送り続けるというのは割と簡単に出来そう。データ量をあまり気にせずどんどん放り込んで後で集計の切り口を試行錯誤しやすいのは、1TDユーザーとしても使っていてかなり楽なので相性が良さげ。
fluent-logger について
こんにちは。Fluentd Advent Calendar 11日目担当の @komamitsu です。ワイワイ。
Fluentd Advent Calendarにノリで登録したもののfluentd本体やプラグインに余り関わっていないので途方に暮れていましたが、fluent/fluent-logger-java のメンテナンスをしていることもあり、fluent-logger周りのことを書いてやりすごしたいと思います。
fluent-logger-javaの一年
地味な見出しですね。自分でも書いてみて素でちょっと引きましたが、とりあえずfluent-logger-javaに関連した出来事などを...
いくつか細かいバグの修正や改善を入れていますが、その中でもTCP切断後の再接続処理やタイムアウトの問題が改善されているので、地味に使いやすくなっていると思います。
MLより。複数のfluentdに対して障害時のfailover、またはメモリバッファが一杯になったらファイル書き出し出来ないの?fluentdのメンテ中にメモリバッファがあふれちゃうよ的な話。確かに一理ある要望(まだ対応できてませんが...)
実のところ、TDでは全てのサーバーにfluentdがいて、アプリからは自サーバーのfluentdに投げているのであまり接続周りで困ったことがないんですよね... なので違う構成で利用されている方で困っているケースがあれば色々と知りたいなぁと思ってる次第です。
あとJavaのlog frameworkとの連携に関する要望とかもたまに目にしますねぇ。需要がどの程度あるのか気になります。
他のfluent-loggerとの比較
fluent-logger-javaは万一送信先のfluentdに送信出来なくてもメモリ上でバッファリングを行い、次回以降の送信成功時にまとめて送るようになっています。しかし、前述の "じゃあメモリバッファに書ききれなくなったらどうするの?ディスクに書き出すの?fluentdの接続先を変えてくれるの?" という要望には答えきれてないように思いました。そこで、他のfluent-loggerはどんな感じなのか気になったのでざっとコードを眺めてみました。
切断後の再接続の有無 | 再接続がexponential backoff? | 送信失敗時のデータ保持 | socket domain | ||
---|---|---|---|---|---|
Java | fluent/fluent-logger-java | yes | yes | yes | INET |
Ruby | fluent/fluent-logger-ruby | yes | yes | yes | INET |
Python | fluent/fluent-logger-python | yes | no | yes | INET,UNIX |
Perl | fluent/fluent-logger-perl | yes | yes | yes | INET,UNIX |
PHP | fluent/fluent-logger-php | yes | yes | no | INET,UNIX |
Node.js | fluent/fluent-logger-node | yes | no | yes | INET |
D | fluent/fluent-logger-d | yes | yes | yes | INET |
Scala | oza/fluent-logger-scala | yes | yes | yes | INET |
Haskell | notogawa/fluent-logger-haskell | yes | no | yes | INET |
OCaml | fluent/fluent-logger-ocaml | yes | yes | yes | INET,UNIX |
C | roadman/fluent-logger-c | no | - | no | INET |
C++ | todayman/fluent-logger-cpp | no | - | yes | INET |
C# | zoetrope/fluent-logger-csharp | yes | no | yes | INET |
Lua | ngigroup-developer/fluent-logger-lua | no | - | no | INET |
# Haskellもあったけど眠気の限界。気力があったら後で追加します...notogawaさんから教えて頂きHaskell版追記しました。thanks!
# 全体的にざっと眺めただけ&上記全ての言語についてちゃんと理解しているかというとそうではないので、間違っていたらご指摘頂けると幸いです。
全てのfluent-loggerでfluentdとの接続を保持しており、毎回接続しなおさないようになっていますが、それ以外は結構違いがあって面白いです。fluent-loggerのほうでどこまで頑張るか、呼び元のほうで頑張るかなど思想の違いもありそうです。(2013-12-11 思い出したので追記 ->) それ以外にも、Perl版ではfork()されたプロセスではsocketを共有せずに自分で開き直すような処理があったりして、そういう渋い工夫を見るのも楽しいですね。
ちなみに、複数のfluentdに接続してfailoverしたり、メモリバッファが溢れたらディスクに書き込む機能はどれもありませんでした。意外とそれで困るケースはすくないのかな。
一点気になったのが、いくつかのfluent-loggerではsocketへの書き込みのみを続けているっぽいので、fluentdが万一落ちたときにFINパケットが飛んで来ても気がつかないケースがありそうかなと。select()的なことをしてread()して0byteであったら切断を検知, またはnon-blockingでread()してEAGAINを期待する、ということが必要な気がしました。fluent-logger-rubyだと毎回別socketで接続しているようで、これであればFINを送る間もなく切断した場合でも検知出来るなー、でもちょっとコストが心配だなーと色々面白いです。
あと、自分では計測していないのですが、UNIX domainソケットのほうが性能が出るっぽい話も聞くので、優位な差がありそうであればJava版も対応してみても良いかな、などなど。