Fluentd&Kinesis&Lambdaによる柔軟で高可用性なログ収集基盤の構築

  • 127
    いいね
  • 0
    コメント

概要

Fluentdによるログ収集基盤を、Lambda&Kinesisを利用した形で構成を変更したので、その時のメモ。
先に一言で感想を述べるのであれば、巷の噂通り、Kinesis&Lambdaは素敵でした。

Fluentd Aggregatorが抱える問題点

ログデータをFluentdのForwarder & Aggregatorを経由し、S3とRedshiftに保存するような構成でしたが、Aggregatorは冗長化しづらくボトルネックとなっていました。

Screen Shot 2016-07-17 at 9.34.06 AM.png

ログ収集に求める要件

ログ収集の構成を改善するにあたり、先に挙げた目の前の問題点を解決するのは勿論ですが、他にも様々な要件があり、大別すると以下4つ。

  • 信頼性: データをロスなく収集することができる。
  • 安定性: ログ量に関係なく安定的なパフォーマンスを維持できる。
  • 冗長性: 安全かつ簡単にスケーリングが可能
  • 汎用性: 複数ログを複数サービスに転送可能。

これらの要件を満たすことができる技術ということで、AWS Kinesis(&Lambda)の登場です。

AWS Kinesis & Lambdaとは?

AWS開発者ガイドから、それぞれの特徴と制限をざっくりと調べてみると以下の通り。

Kinesisの特徴と制限

Fluentdの場合は、PUSH型

  • 特徴
    1. 簡単管理: フルマネージド
    2. リアルタイム: ストリーミングタイプの継続処理
    3. 伸縮自在: シームレスにスループットやボリュームを変えることができる。
    4. インテグレーション(S3, Redshift, Dynamo)
    5. リアルタイム処理: KCL(Kinesis Client Library)を用いて容易にリアルタイムストリーミングデータの処理が実装可能。
    6. Low Cost: コスト効率が高い。
  • 制限
    1. 1レコードあたりの容量: 25KB
    2. 1シャードあたりの転送量: 1MB/秒、1000レコード/秒
    3. シャード数上限: 25シャード (申請すれば引き上げ可能らしい)
    4. ストリームの保持期間は24時間 (1週間まで延長可能)

Lambdaの特徴と制限

  • 特徴
    • コードを書くだけでいい(対応言語:Nodejs,Java,Python)
    • オートスケールする
    • インフラの管理が不要
    • メモリ容量: 128mb〜1.5GB
    • CPU: メモリ容量に対して変動
    • タイムアウトは15s〜300sで設定可能(デフォルト15s)
  • 制限
    • 同時実行可能数: 100/s

Kinesis&Lambdaのログデータの流れ

データの流れを図にしてみると以下の通り。

FluentdのAggregaterの場合は、単純にデータのルーティング処理でデータが通過していくだけという形(PUSH型)でしたが、Kinesisの場合は、データを保持し続け(デフォルト24時間)、それをLambdaが取りにいくという形(PULL型)になります。

従来のLog Aggregatorでは、例えばサーバー・ネットワークで問題が起きてログデータが欠損した場合、復旧は困難でしたが、そこをKinesisが担保してくれます。さらにLambda側で何か問題が起きた場合でも、Lambdaでは処理を再実行させることもできますし、処理を一旦停止しておくこともできます。 (素晴らしい・・)

Screen Shot 2016-07-17 at 9.35.48 AM.png

KPLとKCLとは?

ログ収集でKinesisとLambdaを導入するにあたり、重要なライブラリがKPCとKCLです。簡単に言ってしまうと、データを送信する際に1レコードずつ送信するのではなく、1レコード内に複数レコード集約してまとめて送ってしまおう、というもので、スループットが劇的に向上します。
(ちなみにこれらを使わずにKinesisを利用することもできます。)

  • KPL(Kinesis Producer Library) : ログを集約する。
    • コア部分はC++で実装
    • プロトコルバッファ実装
    • リトライ、シャード数最適化、レコード集約、メトリクス送信
  • KCL(Kinesis Client Library) : 集約されたログを展開(Disaggregation)する。

それぞれのライブラリはgithubにてAWSから提供されています。

Kinesis&Lambdaを活用したログ収集構成

WEBアプリケーションのログデータをS3とRedshiftに保存しているのですが、KinesisとLambdaの導入により、以下のように構成を変更しました。

MyRoomClip.020.jpeg

Fluentdの設定: Kinesis利用時の最適設定

Kinesisを導入にあたりFluentdの設定も見直しが必要になってきます。設定は、各々の環境や負荷状況により異なると思いますので、Fluentd・Kinesis・Lambdaの主要な設定項目を図にまとめてみました。
ログデータはこまめに送るよりは、なるべく一纏めに送るような設定にしたほうがパフォーマンスが良くなります。
実際に運用しながら微調整していくことが必要かなと思います。

MyRoomClip.031.jpeg

設定例。

<match kinesis.**>
  type kinesis_producer
  region ap-northeast-1
  stream_name YOUR_KINESIS_NAME
  include_tag_key true

  buffer_type file
  buffer_chunk_limit 1m
  buffer_queue_limit 512
  buffer_path /var/log/td-agent/buffer/

  flush_interval 15s
  try_flush_interval 1
  queued_chunk_flush_interval 1
  num_threads 1
  detach_process 1
</match>

複数ログの取り扱いについて: Lambdaでのルーティング処理

ログの種類がアクセスログだけとか1種類だけならいいのですが、実際にサービスを運用すると様々な種類のログが出力され、必要なログもサービスに合わせて増えていくと思います。その度に、新しくKinesisとLambdaを構築するのは冗長的ではなく、手間がかかります。そのため、Kinesisには全てのログを流し込み、Lambdaでログを分類し、それぞれS3、Redshiftテーブルに放り込むというやり方ができます。

下記の図は、仮にログがaccess,photo,userと3種類あった場合のログデータの流れを表したものです。(Kinesis&Lambaの組み方は色々あると思いますので、あくまで一例として)

MyRoomClip.032.jpeg

備考 (メモ)

ラムダ関数が失敗した場合はどうなるか?

Q: 関数がイベントの処理に失敗した場合はどうなりますか?

Amazon S3 バケット通知およびカスタムイベントに関しては、コードにエラーがある場合、サービスまたはリソースの上限を超えた場合、AWS Lambda は関数の実行を 3 回試行します。Amazon DynamoDB ストリームおよび Amazon Kinesis ストリームなどお客様に代わって AWS Lambda がポーリングする指定イベントソースに関しては、開発者のコードにエラーがある場合、Lambda はデータの有効期限が切れるまで実行を試行します。Amazon Kinesis および Amazon DynamoDB コンソール、AWS Lambda が関数に向けて生成した Amazon CloudWatch メトリクスを使用して進行状況をモニタリングできます。エラーまたは実行スロットリング率に基づいて、Amazon CloudWatch アラームを設定することもできます。

Kinesisと連携した際のLambdaの同時実行回数は?

Amazon Kinesis または DynamoDB のストリームを読み取る Lambda 関数の場合、Lambda ではストリームのシャードごとに関数が同時に実行されます。たとえば、Amazon Kinesis ストリームに 100 のシャードがある場合、関数の実行数はどの時点でも最大 100 件になります。関数は、(イベントソース定義内で設定したバッチサイズを上限として) レコード数に応じて呼び出され、1 秒に複数回、アクティブな各シャードからの読み取りを順次行います。たとえば、Amazon Kinesis ストリームに 10 のアクティブなシャードがあるとします。この場合、Lambda 関数の同時実行数は 10 件となります。

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/intro-core-components.html#concurrent-executions

プロトコルバッファ(Protocol Buffer)とは?

Protocol Buffersのデザインの目的はシンプルさとパフォーマンスである。とりわけ、XMLより高速になるようデザインされている。Google は XML との比較で、3〜10倍小さく、20〜100倍高速であると主張している[2]。Google が挙げている例では、XML では 69 バイト以上の物が Protocol Buffers では 28 バイトであり、パースに 5〜10 マイクロ秒かかるのが、0.1〜0.2 マイクロ秒ですむとしている。

https://ja.wikipedia.org/wiki/Protocol_Buffers

参考URL

・Amazon Kinesisの集約データをAWS Lambdaで処理する by AWS Solution Archtectブログ (2016/2)
http://aws.typepad.com/sajp/2016/02/process-amazon-kinesis-aggregated-data-with-aws-lambda.html

・秒間数万のログをいい感じにするアーキテクチャ (2016.6.3)
https://speakerdeck.com/kanny/miao-jian-shu-mo-falseroguwoiigan-zinisuruakitekutiya

・Kinesis Producer Library(KPL)とfluentdとLambdaを連携してKinesisのスループットを上げる (2016.6.5)
http://dev.classmethod.jp/cloud/aws/high-throughput-messaging-system-with-kinesis-kpl-fluentd-lambda/

・AWS Black Belt Tech シリーズ 2015 (2015.9.4)
http://www.slideshare.net/AmazonWebServicesJapan/aws-black-belt-tech-2015-amazon-kinesis

・AWS Black Belt Techシリーズ Amazon (2014.5.28)
http://www.slideshare.net/AmazonWebServicesJapan/aws-black-belt-tech-amazon-kinesis

・BufferedOutput pluginの代表的なoptionについて
http://qiita.com/tatsu-yam/items/bd7006e483f3b3c64309