こんにちは、Tunnelでエンジニアをしている熊谷です。

本記事では「気持ち安らぐログ収集基盤に向けて」という話をします。

気持ち安らぐログ収集基盤に向けて

サービス向上のためにログ収集はとても大切だと思いますが、RoomClipでも日々、様々なログを収集しており、今回のKinesisで取り扱ってるログだけでも30種類近くあります。

ログデータの性質として、当たり前ですがデータ量がひたすら蓄積し続け、サービス拡大やキャンペーン・広告などで流量が爆発的に増えることもあります。その都度、サーバーが停止したり、ネットワークにトラブルが起きたりして対応を迫られるのは極力避けたいものです。

RoomClipでは、ユーザー数増加、サービス拡充につれ、これまでのFluentdでのログ収集基盤では辛くなってきたため、話題奮闘中(?)のAWS Kinesis&Lambdaを取り入れた構成に変更することになりました。また構成を変更するにあたり、トラブルやデータロス無く安定的に動作することはもちろんですが、よりスケーラブルで汎用的な構成を目指しました。

先に結果を言いますと、Kinesis&Labmdaの導入により、ログを安定的に収集することができるようになり、新しいログを追加する際も簡単に安心して行うことができるようになりました。

Kinesis&Lambdaによるログ基盤の考察

Kinesisを利用したログ収集についてネットで調べてみると、基本的な構成として以下のようなフローがよく見つかると思います。

(1) td-agent -> Kinesis -> labmda -> S3

さらにログをクエリで分析するために、Redshift(or Elasticserch)にもデータを入れたいとなると以下のようなフローが見つかります。(この場合、Kinesis Firehoseを導入すれば簡単にできると思います)

(2) td-agent -> Kinesis -> labmda -> S3 -> Lambda -> Redshift (or Elasticsearch)

ただ、取り扱いたいログが1種類の場合であれば上記の構成でいいと思いますが、数十種類のログを扱う場合、ログごとに同じ構成を用意するのは非常に手間で冗長なので、どこかでルーティング処理をいれようとなると思います。その場合の構成は以下のようになります。(ルーティング処理をいれれる箇所はいくつか考えられますが、Redshift手前のLabmdaで処理する場合で考えてみます)

(3) td-agent -> Kinesis -> labmda -> S3     -> Lambda(ルーティング処理) ─> Redshift(table A)                └──> Redshift(table B)

上記の構成であればルーティング規則に則ったログをtd-agentに流し込みさえすれば、自動的にそれぞれのテーブルにデータが挿入されるようになります。

ただ問題点としては、ログ流量が多く、RedshiftへのCOPYが頻発した場合は詰まってしまいます。これらはLambdaでの処理を工夫したりBatchSizeを変更することで多少は上限を引き上げられるかもしれませんが、いずれにせよ、GZIPファイルの数だけRedshift COPY(with JSON GZIP Options)コマンドが走るため、トランザクションが重複し(テーブルロックがかかるため)、クエリ待ちが多発してしまいました。