理系学生日記

おまえはいつまで学生気分なのか

rsyslogで信頼性のあるデータ転送

ログサーバにログを集中管理しようというとき。fluentd を使うこともありますが、古きよき syslog で転送することもあります。 このようなログの転送を Enterprise でしようと思うと、ログの消失ができる限り無いように、という点に気をつける必要があります。

元来、syslog over TCP では十分な信頼性があるログ転送はできないという議論があり、このあたりは rsyslog の main author である Reiner Gerhards 氏の On the (un)reliability of plain tcp syslog... - Rainer Gerhards を参照してください。

ここはこうする

ログサーバが 1 つの場合、クライアント側は以下のような設定になります。

ここでクライアント側は rsyslog を使うことを前提としていますが、サーバ側は syslog サーバであれば問題ないはずです。

*.* action(type=”omfwd”
        queue.type=”LinkedList”
        queue.filename=”example_fwd”
        action.resumeInterval="30"
        action.resumeRetryCount="-1"
        queue.saveonshutdown="on"
        target="example.com" Port="6514" Protocol="tcp")

説明

信頼性のある通信を行おうとしたときに重要なのは、クライアント→サーバに送るメッセージに取りこぼしが無いことです。 従って、求められるのは

  • クライアント側のメッセージ転送キューの長さが十分であること
  • サーバと通信ができない場合(転送に失敗する場合にリトライができること)
  • メッセージ転送前にクライアントが異常になったときに、未転送のメッセージが保存されること

になります。

メッセージ転送キュー

前提として、ここでの「キュー」は、下図の Action Queue の 1 つを意味しています。

メッセージ転送キューを十分にする設定が、queue.type=”LinkedList”queue.filename=”example_fwd” になります。

rsyslog が現時点でサポートしているキューの種類は、LinkedListFixedArray の 2 つです。FixedArray は名前の通り固定長の容量なので、それを超過してしまうと最悪、メッセージがロストします。このため、信頼性がある転送を行おうと思うと、LinkedList を指定する必要があるでしょう。 queue.filename をこの設定に組み合わせると、rsyslog においては、キューが「Disk-Assisted Memory Queues」として扱われます。このキューは、通常はメモリ上に保持され、キューが一杯になってきたり、ディスクに書き出す必要がある場合にのみディスクにファイル出力して管理するというタイプのキューです。

これにより、クライアント側の都合でメッセージがロストするということを防げます。

リトライ

action.resumeIntervalaction.resumeRetryCount あたりを設定すれば良いです。 マニュアルとしては以下を参照。

未転送メッセージの保存

rsyslog が落ちたりするときにキューの中にあるデータをディスクに書き出してくれるオプションです。"on" にしとく。

さらなる信頼性のために

1 台のサーバがぶっこわれた場合、もう 1 台に Fail-over させるという設定を rsyslog では当然サポートしています。 この設定、action.ExecOnlyWhenPreviousIsSuspended で制御できるはずなんですが、まだ良く分かっていない…。

参考文献