Documentation Home

Flume クックブック

flume-dev@cloudera.org [FAMILY Given]

改訂履歴
改訂 0.9.5-SNAPSHOT October 11 2011 F

目次

1. はじめに
2. Flume ソースとシンクを使ってみる
2.1. ソースのテスト
2.2. シンクとデコレータのテスト
2.3. ノードの監視
3. Apache 2.x Web サーバーロギングでの Flume エージェントの使用
3.1. CentOS / Red Hat の Apache サーバーを使用している場合
3.2. Ubuntu の Apache サーバーを使用している場合
3.3. パイプ経由のログファイルからのログエントリの取得
3.4. パイプ経由のログの使用
4. syslog データの Flume エージェントへのロギング
4.1. ファイルの末尾の追跡
4.2. ソケットを介した syslog イベントの配信
4.2.1. syslogd の構成
4.2.2. rsyslog の構成
4.2.3. syslog-ng の構成
5. Scribe イベントの Flume エージェントへのロギング

1. はじめに

Flume は、大量のログデータを効率的に収集、集約、移動することを目的に開発された、高い信頼性と可用性を持つ分散型のサービスです。構成の自由度が高く、拡張性に富んでいるということは、多くのオプションが存在し、したがってオペレータが決めなければならないことも数多く存在することを意味します。このドキュメントは、細部にあまりこだわることなく Flume を手っ取り早く動作させるための「レシピ」を紹介した「クックブック」です。

ここでは、最初に Flume ノードの使い方を簡単に説明したあと、3 つのシナリオにしたがって、それぞれ異なる種類のソースを対象にエージェントをセットアップする方法を説明します。最後に、簡単なコレクタをセットアップし、分散デプロイでのトラブルシューティングの方法について説明します[訳注:該当する箇所はありません]。

  • ワンショット Flume ノードのデバッグの基本
  • Apache Web サーバーロギング用 Flume エージェント
  • syslog / syslog-ng ロギング用 Flume エージェント
  • scribe ロギング用 Flume エージェント

2. Flume ソースとシンクを使ってみる

ここでは、ソース、シンク、および論理ノードをテストするときの基本的なヒントを示します。

2.1. ソースのテスト

ソースのテストはむずかしくありません。flume スクリプトの dump コマンドを使うと、コンソールにデータを表示させながらデータソースをテストすることができます。

flume dump source
[注記] 注記

source は 1 つのコマンドライン引数である必要があります。したがって、引用符やかっこが含まれている場合は、 'quotes'"quotes" のように引用符を追加する必要があります。単一引用符を使うと、エスケープしていない二重引用符を引数の中で使用できます。(例: 'text("/tmp/foo")' または "text(\"/tmp/foo\")" 。)

次に示すのは、いくつかの簡単な実行例です。

$ flume dump console
$ flume dump 'text("/path/to/file")'
$ flume dump 'file("/path/to/file")'
$ flume dump syslogTcp
$ flume dump 'syslogUdp(5140)'
$ flume dump 'tail("/path/to/file")'
$ flume dump 'tailDir("path/to/dir", "fileregex")'
$ flume dump 'rpcSource(12346)'

この dump コマンドは、実際にはいくつか追加のコマンドラインパラメータを指定して flume node_nowatch コマンドを実行しています。

flume node_nowatch -1 -s -n dump -c "dump: $1 | console;"

指定されているオプションの意味は次のとおりです。

-1

ワンショット実行。ノードのインスタンスは、ハートビートを使って構成を取得することをしません。

-s

ノードの HTTP ステータス Web サーバーを起動せずに Flume ノードを起動します。ステータス Web サーバーが起動されている場合、Flume ノードのステータスサーバーは、ワンショットモードでも、プロセスをアクティブな状態に保ちます。ワンショットモード (-1) とともに -s フラグが指定された場合、Flume ノードは、すべての論理ノードが完了した後に終了します。

-c "node:srcsnk;"

指定された構成定義でノードを起動します。注意: -1 を指定しない場合、ここで指定する設定はマスターへの最初のハートビートで無効にされます。

-n node

ノードの物理ノード名を指定します。

次のコマンドを実行すると、Flume node コマンドについての詳しい情報が表示されます。

$ flume node -h

2.2. シンクとデコレータのテスト

すでにソースはテストできるようになりました。コマンドラインから任意のシンクとデコレータをテストするには、あと 1 つだけ手順が必要です。シンクには消費するデータが必要です。よくテストデータの生成に使われるソースとして、合成データセット (asciisynth)、コンソール (console)、およびファイル (text) があります。

たとえば、合成ソースを使うと、それそれがランダムな 100 バイトのデータからなる 1000 個のイベントを生成してコンソールに出力することができます。テキストソースを使えば /etc/services などのファイルを読み取ることができ、コンソールをソースとして使えば、テキスト行をイベントとして対話的に入力することもできます。

$ flume node_nowatch -1 -s -n dump -c 'dump: asciisynth(1000,100) | console;'
$ flume node_nowatch -1 -s -n dump -c 'dump: text("/etc/services") | console;'
$ flume node_nowatch -1 -s -n dump -c 'dump: console | console;'

指定するシンクでデコレータを使うこともできます。たとえば、delay デコレータを挿入して、ソースからシンクにプッシュされるデータ量のレートを制限することができます。次の例では、 delay デコレータは 100ms だけ待機してから各合成イベントをコンソールに送信します。

$ flume node_nowatch -1 -s -n dump -c 'dump: asciisynth(1000,100) | { delay(100) => console};'

コマンドラインから直接ベストエフォート (BE) エージェントまたはディスクフェイルオーバー (DFO) エージェントを介してイベントを送信することもできます。次に示すのは、 console ソースを使って対話的にデータを生成し、これを BE モードおよび DFO モードでコレクタに送信する例です。

[注記] 注記

Flume ノードの console ソースにパイプでデータを渡す場合は、flume node_nowatch を使用しなければなりません。watchdog プログラムは標準入力を転送しません。

$ flume node_nowatch -1 -s -n dump -c 'dump: console | agentBESink("collectorHost");'
$ flume node_nowatch -1 -s -n dump -c 'dump: console | agentDFOSink("collectorHost");'
[警告] 警告

これらのノードはコマンドラインで入力された構成を使って実行され、マスターへのコンタクトは行わないので、これらのノードで自動チェインや論理ノード変換を使用することはできません。また、E2E モードで使われる受信確認は、ノードからマスターへのハートビートにピギーバックされる形でマスターを経由します。このモードではハートビートを行わないので、E2E モードは使用しないでください。

コンソールソースは、データをパイプで直接 Flume に渡せるので便利です。次に示すのは、プログラムから出力されたデータをパイプで Flume に渡し、これを Flume が配信する例です。

$ <external process> | flume node_nowatch -1 -s -n foo -c 'foo:console|agentBESink("collector");'

理想を言えば、データを名前付きパイプに書き込み、 text または tail を使って Flume に名前付きパイプからデータを読み取らせることができれば便利です。残念ながら、現行バージョンの Flume の texttail は、今のところ Linux 環境の名前付きパイプと互換性がありません。ただし、次に示す例のように、標準出力コンソールをリスンする Flume ノードにパイプでデータを渡すことはできます。

$ tail -f namedpipe | flume node_nowatch -1 -s -n foo -c 'foo:console|agentBESink;'

次のように exec ソースを使って出力データを取得することもできます。

$ flume node_nowatch -1 -s -n bar -c 'bar:exec("cat pipe")|agentBESink;'

2.3. ノードの監視

コンソールやログファイルにデータを出力するやり方は、データの伝送を検証する効果的な方法ですが、Flume ノードではソースとシンクの状態を監視する手段が用意されています。この監視は、ノードの報告ページで行うことができます。デフォルトでは、ブラウザでノードの TCP ポート 35862 にアクセスすると、報告ページが表示されます。(http://node:35862/)

このページには、物理ノード上のすべての論理ノードに関するカウンタ情報、およびマシンの基本的なメトリクス情報の一部が表示されます。

[ティップ] ティップ

1 台のマシン上に複数の物理ノードがある場合は、ポートが衝突する可能性があります。ポートの自動検索オプション (flume.node.http.autofindport) を有効にすると、物理ノードはバインド可能な空きポートが見つかるまで、ポート番号をインクリメントしながら利用可能なポートを探します。

3. Apache 2.x Web サーバーロギングでの Flume エージェントの使用

Apache 2.x サーバーに Flume を接続するには、次の操作が必要です。

  • Web サーバーのログファイルのパーミッションを設定する。
  • Web サーバーのログを tail するか、またはパイプ経由のログを使って、Flume が Web サーバーからデータを取得できるようにする。

ここでは、これらの操作をデフォルトインストールの Ubuntu Lucid と CentOS 5.5 で実行する手順について説明します。その後、Flume を統合するさまざまな方法について説明します。

3.1. CentOS / Red Hat の Apache サーバーを使用している場合

デフォルトでは、CentOS の Apache は、オーナーが root でグループが adm 、モードが 0644 (rw-r—r--) のファイルに Web サーバーのログを書き込みます。Flume は flume ユーザーで実行されるので、Flume ノードはログを読み取ることができます。

CentOS/Red Hat の Apache サーバーは、デフォルトでは次の 2 つのファイルにログを書き込みます。

/var/log/httpd/access_log
/var/log/httpd/error_log

これらのファイルからデータを取得するには、 tail ソースを使うよう Flume ノードを構成して、これらのファイルの末尾を追跡するのが最も簡単な方法です。

tail("/var/log/httpd/access_log")
tail("/var/log/httpd/error_log")

3.2. Ubuntu の Apache サーバーを使用している場合

デフォルトでは、Ubuntu の Apache は、オーナーが root でグループが adm 、モードが 0640 (rw-r-----) のファイルに Web サーバーのログを書き込みます。Flume は flume ユーザーで実行されるので、デフォルトでは Flume ノードはログを読み取ることが できませんflume ユーザーがファイルを読み取ることができるようにする 1 つの方法として、 flume ユーザーを adm グループに追加するやり方があります。

Ubuntu の Apache サーバーは、デフォルトでは次の 3 つのファイルにログを書き込みます。

/var/log/apache2/access.log
/var/log/apache2/error.log
/var/log/apache2/other_vhosts_access.log

これらのファイルからデータを取得するには、 tail ソースを使うよう Flume ノードを構成するのが最も簡単です。

tail("/var/log/apache2/access.log")
tail("/var/log/apache2/error.log")
tail("/var/log/apache2/other_vhosts_access.log")

3.3. パイプ経由のログファイルからのログエントリの取得

Apache 2.x のドキュメント (http://httpd.apache.org/docs/2.2/logs.html) には、CustomLog ディレクティブでパイプ経由のログを使う方法の説明があります。例では rotatelogs を使い、一定時間ごとに、指定されたプリフィックスの付いた新しいファイルにデータを書き込んでいます。次に示すのは、 httpd.conf/apache2.conf ファイルに記述できるディレクティブの例です。

LogFormat "%h %l %u %t \"%r\" %>s %b" common
CustomLog "|/usr/sbin/rotatelogs /var/log/apache2/foo_access_log 3600" common
[ティップ] ティップ

Ubuntu Lucid では、これらのディレクティブは /etc/apache2/sites-available/default に記述します。CentOS 5.5 では、これらのディレクティブは /etc/httpd/conf/httpd.conf に記述します。

これらのディレクティブを指定した Apache では、毎時間 (3600 秒) ごとに "common" ログ形式で /var/log/apache2/foo_access_log.xxxxx にログファイルが書き込まれます。

次のようにして Flume の tailDir ソースを使うと、Apache の設定を変えることなく、すべてのファイルを読み取ることができます。

tailDir("/var/log/apache2/", "foo_access_log.*")

最初の引数はディレクトリで、2 番目の引数は対象となるファイル名を示す正規表現です。tailDir はディレクトリを監視し、指定された正規表現に一致するすべてのファイルの末尾を追跡します。

3.4. パイプ経由のログの使用

データをディスクに書き込んでこれを Flume に読み取らせる代わりに、Apache から直接データを取得するようにすることもできます。それには、Web サーバーのパラメータを変更し、Apache の設定にいくつかディレクティブを追加してパイプ経由のログ機能を利用します。

CustomLog "|flume node_nowatch -1 -s -n apache -c \'apache:console|agentBESink(\"collector\");\'" common
CustomLog "|flume node_nowatch -1 -s -n apache -c \'apache:console|agentDFOSink(\"collector\");\'" common
[警告] 警告

CentOS の場合、Flume ノードで必要になる Java は、デフォルトではユーザー root のパスには含まれていません。alternatives を使うと、java 実行可能ファイルへの管理されたシンボリックリンクを /usr/bin/ に作成することができます。

パイプ経由のログの使用はディスクファイルを使う場合よりも効率的ですが、Flume がデータをディスクに保存せずにメッセージを配信することになるので、いくらかリスキーな方法です。なぜならイベントが失われる可能性も高まるからです。セキュリティに関して言えば、上の flume ノードインスタンスは Apache のユーザーで実行されることに注意が必要です。Apache のユーザーは、Apache マニュアルによれば一般に root です。

[注記] 注記

ワンショットモードのノードを構成すれば、データを直接コレクタに配信することができます。ただしこれが可能なのは、信頼性のレベルがベストエフォートまたはディスクフェイルオーバーの場合だけです。

上に示した例では、Flume ノードをマスターにコンタクトしないワンショットモードで使っています。残念ながら、ワンショットモードでは、自動チェインやエンドツーエンド (E2E) の信頼性モードを直接使用することはできません。なぜなら、自動チェインはマスターによって生成され、E2E モードは現在のところ、受信確認をマスター経由で配信するからです。

ただし、信頼性の高い E2E モードを利用できる Flume ローカルノードデーモンに対して、ワンショットの Flume ノードがデータを配信するようにすることはできます。この場合、Apache のディレクティブは次のように指定します。

CustomLog "|flume node_nowatch -1 -s -n apache -c \'apache:console|agentBESink(\"localhost\", 12345);\'" common

ついで、次の構成でリスンするよう Flume ノードをセットアップします。

node : rpcSource(12345) | agentE2ESink("collector");

このデーモンノードはマスターに接続するので、auto*Chain を使用できます。

node : rpcSource(12345) | autoE2EChain;
[注記] 注記

エンドツーエンドモードでは、E2E シンクに入ってくるデータの確実な配信を試みます。ここで取り上げている、ワンショットノードから信頼性の高いノードにデータを送るシナリオでは、E2E シンクに届くまでのデータが確実に確保されるわけではありません。ただし、両者間の接続はローカル接続なので、これがエラーを起こすのは、マシンまたはプロセスがエラーを起こした場合だけです。ワンショットノードをディスクフェイルオーバー (DFO) モードに設定すると、デーモンノードの構成が変更された場合にメッセージが失われる可能性を抑えることができます。

4. syslog データの Flume エージェントへのロギング

syslog は、unix の標準的な単一マシン用ロギングサービスです。通常、イベントは、タイムスタンプ、ファシリティ、プライオリティ、およびメッセージから構成される行として発行されます。syslog は、リモートホストにデータを送信するよう構成できます。デフォルトの syslog リモート配信は、当初はベストエフォートサービスの提供を目的として設計されました。現在では、信頼性の向上した (エラー発生時にはメモリバッファリングを行う TCP 接続による) 方法でメッセージを配信する、より高度な syslog サービスも多数存在しています。ただし、信頼性の保証は 1 ホップで、Flume の信頼性の高い配信メカニズムよりは劣ります。

ここでは、2 つの方法を使った syslog データの収集について説明します。最初に、ファイルの末尾を追跡する方法について説明します。その後、Flume の syslog* ソースに直接データを送るための syslog システムの設定について説明します。

4.1. ファイルの末尾の追跡

syslog メッセージを記録する最も簡単な方法は、syslog によって生成されたログファイルの末尾を追跡することです。これらのファイルは一般に /var/log に置かれています。

次にいくつか例を示します。

/var/log/auth.log
/var/log/messages
/var/log/syslog
/var/log/user.log

tail ソースを使えば、Flume ノードでこれらのファイルの末尾を追跡することができます。

tail("/var/log/auth.log")
tail("/var/log/messages")
tail("/var/log/syslog")
tail("/var/log/user.log")

システム構成によっては、Flume ノードプロセスからこれらのファイルにアクセスするときに、パーミッション関連の問題が生じることがあります。

[注記] 注記

Red Hat/CentOS システムでは、オーナーとグループが root 、モードが 0600 (-rw-------) のファイルにログを書き込みます。Flume を root で実行することもできますが、これはお勧めしません。Flume はリモートから任意のプログラムを実行するよう構成できるからです。

[注記] 注記

Ubuntu システムでは、オーナーとグループが root 、モードが 0640 (-rw-r-----) のファイルにログを書き込みます。flume ユーザーを adm グループに追加すると、ユーザー flume で実行される Flume ノードは、syslog によって生成されたファイルを読み取ることができます。

[注記] 注記

ファイルの末尾を追跡する場合、イベントが読み取られた時刻がタイムスタンプとして使われます。

4.2. ソケットを介した syslog イベントの配信

オリジナルの syslog は名前付きパイプ /dev/log をリスンしますが、UDP ポート 514 をリスンするよう構成することができます。(http://tools.ietf.org/search/rfc5424) 。より高度なバージョン (rsyslog、syslog-ng) では、TCP でデータの送受信を行うことができ、インメモリのキューイング/バッファリングも可能です。たとえば、syslog-ng と rsyslog は、デフォルトの UDP ポート 514 のほか、リカバリ機能に優れた TCP ポート 514 を使うよう構成することができます。

[注記] 注記

デフォルトでは、UDP/TCP ポート 514 でリスンできるのは、スーパーユーザーだけです。一般に Unix システムでは、1024 未満のポートにバインドできるのはスーパーユーザーだけです。Flume はスーパーユーザーで実行することができますが、セキュリティ上の観点からこれはお勧めしません。ここで取り上げる例では、ユーザーがバインド可能なポート 5140 を利用する方法を示しています。

syslog の構成をデバッグする場合には、syslog ソースに対して flume dump を使用できます。このコマンドは、受信した syslog データをコンソールに出力します。syslog データが適切なポートに届いているかどうかをテストするには、コマンドラインで次のようにして flume dump コマンドを実行します。

$ flume dump 'syslogUdp(5140)'

コマンドを実行すると、すべての受信イベントがコンソールにダンプされます。

きちんと接続されていることを確認したら、マシン上で Flume ノードを実行し、希望する信頼性レベルのシンクを構成できます。

Flume の syslog* ソースを使う場合、このソースはイベントデータの行全体を保存し、元のデータで見つかったタイムスタンプを使用し、該当するサービスを syslog データの行から取り出そうとします。これらはいずれも Flume イベントのフィールドにマップされますが、 service は例外で、これは特別なメタデータとして各イベントに追加されます (これは RFC で定められた syslog のきまりです)。

したがって、sylog エントリの本体が次のようになっているとすると、

Sep 14 07:57:24 blitzwing dhclient: bound to 192.168.126.212 -- renewal in 710 seconds.

Flume イベントの本体は次のようになります。

Sep 14 07:57:24 blitzwing dhclient: bound to 192.168.126.212 -- renewal in 710 seconds.

イベントは "Sep 14 07:57:24" を日付と時刻のデータに変換し、バケット化できるようにします。元の日付には年を表すデータが含まれていないので、年は現在の年とみなし、さらに、タイムゾーンもないので、ローカルタイムゾーンが使われていると仮定します。host フィールドは "blitzwing" となり、オプションの "service" メタデータフィールドには "dhclient" がセットされます。

4.2.1. syslogd の構成

オリジナルの syslog は syslogd です。syslogd/etc/syslog.conf ファイルで構成します。書式は非常にシンプルです。

syslog はメッセージを受信し、関連する名前を持つさまざまなファシリティにメッセージを送信します (http://tools.ietf.org/search/rfc5424#section-6.2) 。

/etc/syslog.conf ファイルは、基本的にはファシリティと "アクション" のリストから構成されています。これらの "アクション" が表すのは、通常のファイルなどの送信先ですが、名前付きパイプ、コンソール、さらにリモートマシンも指定することができます。具体的には、送信先ホストマシンの前に @ 記号を付けると、リモートマシンを指定できます。ポートが指定されなかった場合、イベントは UDP ポート 514 を介して送られます。

次に示すのは、送信先をマシン localhost のポート 5140 にする例です。

user.*     @localhost:5140

このマシンで実行されている Flume ノードデーモンでは、次のように指定することで、新しいログデータをリスンする syslogUdp ソースを用意することができます。

host-syslog : syslogUdp(5140) | autoE2EChain ;

4.2.2. rsyslog の構成

rsyslog は syslog をそのまま置き換えることができる高度なバージョンで、Ubuntu システムではデフォルトの syslog です。rsyslog は、基本的なフィルタリング、ベストエフォートの配信、1 ホップ先の障害に対応可能なキューイングをサポートしています。

rsyslog は、syslog の構成ファイルの書式を拡張しています。通常の syslogd と同様、次のように指定すると、UDP ポート 514 (標準の syslog ポート) でリスンしているリモートマシンにデータを送信することができます。

*.*   @remotehost

さらに、rsyslog では、TCP ポート 514 でリスンしているリモートホスト宛に、信頼性の高い TCP プロトコルを使ってデータを送信することもできます。それには rsyslog の構成ファイルで次のように @@ というプリフィックスを付けて、TCP を使うよう指定します。

*.*  @@remotehost

同様に、ポート番号をサフィックスとして追加して、特定のポートを送信先に指定することができます。次に示すのは、localhost の TCP ポート 5140 にイベントを配信する例です。

*.*  @@localhost:5140

ローカルマシンで実行されている Flume ノードデーモンでは、次のように指定して論理ノードを追加することで、syslog データを取り込むことができます。

host-syslog : syslogTcp(5140) | autoE2EChain ;

4.2.3. syslog-ng の構成

syslog-ng は、デフォルトの syslog ロギングシステムの代わりによく使われるもう 1 つの syslog です。syslog-ng の構成ファイルの書式はオリジナルの syslog とは異なりますが、各種ファシリティからの syslog データをリモートのさまざまな送信先に送ることができます。また、TCP または UDP が使用できます。

次に示すのは、syslog-ng.conf (一般に /etc/syslog-ng/ にあります) の修正例です。

## set up logging to loghost (which is flume)
destination loghost {
        tcp("localhost" port(5140));
};

# send everything to loghost, too
log {
        source(src);
        destination(loghost);
};

ローカルマシンで実行されている Flume ノードデーモンでは、次のように指定して論理ノードを追加することで、syslog データを取り込むことができます。

host-syslog : syslogTcp(5140) | autoE2EChain ;

5. Scribe イベントの Flume エージェントへのロギング

Flume は、Scribe を使ってログを記録するアプリケーションの下流ノードをエミュレートすることができます。Scribe は、Facebook によるオープンソースのログ集約フレームワークです。Scribe はシンプルな API を持っており、Thrift をコアネットワークトランスポートメカニズムに使用しています。Flume は同じ Thrift IDL ファイルを使っており、Scribe ソースから渡されるデータをリスンすることができます。

Scribe には scribe_cat という名前のサンプルアプリケーションが付属しています。scribe_cat は unix の cat プログラムに似ていて、指定された "category" を付加してデータを下流のホストに送信します。Scribe はデフォルトでは TCP ポート 1463 を使用します。

scribe ソースを使う論理ノードを作成すると、送られてくる Scribe トラフィックをリスンする Flume ノードを構成することができます。作成した論理ノードには、任意のシンクを割り当てることができます。次に示す例では、Scribe ノードがイベントを受信し、これをコンソールと、自動的に割り当てられるエンドツーエンドエージェントに送信します。エンドツーエンドエージェントは、イベントを下流のコレクタプールに配信します。

scribe: scribe | [console, autoE2EChain];

このノードがマスターと通信し、ノードが localhost 上にあるとすると、次のようにして scribe_cat プログラムを使うことで、データを Flume に送信することができます。

$ echo "foo" | scribe_cat localhost testcategory

Scribe ソースは、Scribe イベントを受け取ると、Scribe のカテゴリ情報を Flume の新しいイベントメタデータエントリに変換し、イベントをシンクに配信します。Scribe では時刻に関するメタデータが含まれていないので、作成された Flume イベントのタイムスタンプが、Scribe イベントの到着時刻になります。

     ______
    / ___//_  ______  ____
   / /_/ / / / /    \/ __/
  / __/ / /_/ / / / / __/
 / / /_/\____/_/_/_/\__/
/_/ Distributed Log Collection.