50
fluentd を利用した 大規模ウェブサービスの ロギング cookpad id:secondlife / @hotchpotch

fluentd を利用した大規模ウェブサービスのロギング

Embed Size (px)

Citation preview

Page 1: fluentd を利用した大規模ウェブサービスのロギング

fluentd を利用した大規模ウェブサービスの

ロギング

cookpadid:secondlife / @hotchpotch

Page 2: fluentd を利用した大規模ウェブサービスのロギング

提供

Page 3: fluentd を利用した大規模ウェブサービスのロギング

•id:secondlife•@hotchpotch•舘野祐一 / Yuichi Tateno•Shibuya.js 発起人•Asakusa.rb 所属•fluentd コミッタ̶•BiS, ももいろクローバーZ

Page 4: fluentd を利用した大規模ウェブサービスのロギング

仕事•COOKPAD 開発基盤部所属•サービス開発をしやすく=ユーザに価値を届けやすく

•Ruby/Rails のバージョン上げる•ミドルウェアの導入/ライブラリの実装•テスト / CI•デプロイの仕組み

Page 5: fluentd を利用した大規模ウェブサービスのロギング

なぜロギング?

Page 6: fluentd を利用した大規模ウェブサービスのロギング

なぜロギング?

Page 7: fluentd を利用した大規模ウェブサービスのロギング

なぜロギング?

価値 検証

Page 8: fluentd を利用した大規模ウェブサービスのロギング

なぜロギング?

価値 検証

Page 9: fluentd を利用した大規模ウェブサービスのロギング

なぜロギング?

価値 検証現行いまいち

検証に時間がかかる=

ユーザに価値を届けるのが遅れる

解決すべき仕事

Page 10: fluentd を利用した大規模ウェブサービスのロギング

COOKPAD

Page 11: fluentd を利用した大規模ウェブサービスのロギング

COOKPAD

1,500万 UU (pc のみ)

110万レシピ

Page 12: fluentd を利用した大規模ウェブサービスのロギング

ロギング

PV それ以外

Page 13: fluentd を利用した大規模ウェブサービスのロギング

•巨大なデータ•MySQL

•利用方法•バッチで一時集計•中間テーブルに保存

PVログ

Page 14: fluentd を利用した大規模ウェブサービスのロギング

•巨大なデータ•MySQL

•利用方法•バッチで一時集計•中間テーブルに保存

PVログ

Page 15: fluentd を利用した大規模ウェブサービスのロギング

•オンメモリなら高速•一日分ならオンメモリ•バッチ用DB二台(メモリ32G)•オンメモリでない•遅い

PVログ + MySQL

Page 16: fluentd を利用した大規模ウェブサービスのロギング

•保存速度•blackhole + slave で速い•がそれでも詰まる時が

PVログ + MySQL

Page 17: fluentd を利用した大規模ウェブサービスのロギング

•データの保持•巨大・直近のデータしか保持できない•今後スケールしない恐れ•過去ログはバックアップ•即座に利用できない•過去データをサービス開発に利用できない

PVログ + MySQL

Page 18: fluentd を利用した大規模ウェブサービスのロギング

•MySQL へ

•JSON でシリアライズ•create table

他のログ

Page 19: fluentd を利用した大規模ウェブサービスのロギング

•アプリケーションでたくさん記録•insert コスト•もっと手軽に取りたいのに!•データ構造•JSON で入れる -> 集計面倒•create table -> たくさんテーブル…

他のログ+MySQL

Page 20: fluentd を利用した大規模ウェブサービスのロギング

•データストレージ•MySQL でない選択肢も

•ログをたくさんとっても重くならない•データ構造•扱いやすいスキーマレス•だけど高速・スケールする

悩み

Page 21: fluentd を利用した大規模ウェブサービスのロギング

fluentd

Page 22: fluentd を利用した大規模ウェブサービスのロギング

•データストレージ•MySQL でない選択肢も

•ログをたくさんとっても重くならない•データ構造•扱いやすいスキーマレス•だけど高速・スケールする

fluentd

Page 23: fluentd を利用した大規模ウェブサービスのロギング

cookpad での構成

Page 24: fluentd を利用した大規模ウェブサービスのロギング

•構造化ロガー•安定性•パフォーマンス•プラガブル

fluentd

Page 25: fluentd を利用した大規模ウェブサービスのロギング

•MySQL だとカラム追加が必要

•様々な所に気を使う•サービスを落とさない•バッチのコード•みんなログの情報を追加しない

構造化ロガー前

Page 26: fluentd を利用した大規模ウェブサービスのロギング

•MySQL だとカラム追加が必要

•様々な所に気を使う•サービスを落とさない•バッチのコード•みんなログの情報を追加しない

構造化ロガー後

解決

Page 27: fluentd を利用した大規模ウェブサービスのロギング

•MySQL

•insert コスト•blackhole ストレージエンジンでもネットワークコストがそこそこ

•アプリに気軽にログをしこみすぎると遅く…

パフォーマンス

Page 28: fluentd を利用した大規模ウェブサービスのロギング

•fluentd•バッファ + 転送•アプリサーバのローカルに fluentd•定期的に転送•アプリでの処理時間はほぼ0コスト

パフォーマンス

Page 29: fluentd を利用した大規模ウェブサービスのロギング

•処理能力•中央の fluentd は1台、1スレッドで十分処理できてる (m1.large)

パフォーマンス

Page 30: fluentd を利用した大規模ウェブサービスのロギング

•11月下旬から合計100台弱で運用•本体は安定している•一回だけ古いバージョンで自然死•エラーになるのはプラグイン•対策して pull request

安定性

Page 31: fluentd を利用した大規模ウェブサービスのロギング

•buffered•転送先/保存先が落ちてても再送•一時的に数分止めても、ちゃんと再送•保存先 mongodb

•6時間止めても、ちゃんと保存

安定性

Page 32: fluentd を利用した大規模ウェブサービスのロギング

•さまざまなInput Plugin•tail / TCP / HTTP etc...•さまざまなOutput Plugin•s3 / mongo / td / hdfs ...

•Rubyで書ける

プラガブル

Page 33: fluentd を利用した大規模ウェブサービスのロギング

•PV系のLog•MySQL からの移行検討中

•その他ロギング全部•もうすでに移行•mongodb

fluentd

Page 34: fluentd を利用した大規模ウェブサービスのロギング

cookpad での具体的な利用法

Page 35: fluentd を利用した大規模ウェブサービスのロギング

•すべてのアプリサーバは td-agent•CentOS なので rpm で

•td-agent は自前のRuby1.9.2入り•構成管理は puppet•基本的に設定ファイルは変わらない

fluentd 構成

Page 36: fluentd を利用した大規模ウェブサービスのロギング

<match cookpad.**> type tcp host fluentd-proxy-01 retry_limit 9 <secondary> host fluentd-proxy-02 </secondary></match>

Page 37: fluentd を利用した大規模ウェブサービスのロギング

•中央の転送用サーバ•Ruby 1.9.2 (RVM)

•git で設定ファイル管理•Gemfileで各種fluentd/plugin利用

•よく変更するため

fluentd 構成

Page 38: fluentd を利用した大規模ウェブサービスのロギング

# Gemfilesource :rubygems

gem "yajl-ruby"gem “bson_ext”gem "fluent-plugin-mongo", :git=>'git://git-01/fluent-plugin-mongo'gem "fluentd", '0.10.8'# ...

Page 39: fluentd を利用した大規模ウェブサービスのロギング

$ git pull --rebase$ bundle install$ bundle exec fluentd \ -c fluentd.conf \ -d fluentd.pid \ -o fluentd.log

Page 40: fluentd を利用した大規模ウェブサービスのロギング

Rails からの利用class CookpadLogger  class RailsLogger < ::Fluent::Logger::TextLogger    def initialize(rails_logger)      super()      @rails_logger = rails_logger    end

    def post_text(text)      @rails_logger. debug("[CookpadLogger]\t" + text)    end  end

Page 41: fluentd を利用した大規模ウェブサービスのロギング

class CookpadLogger def self.create_logger(tag = 'cookpad') case Rails.env when 'production' Fluent::Logger::FluentLogger.new(tag) when 'test' Fluent::Logger::TestLogger.new else RailsLogger.new(Rails.logger) end end

Rails からの利用

Page 42: fluentd を利用した大規模ウェブサービスのロギング

it “PVログにユーザの アクセスが記録されていること” log = CookpadLogger.pvlog.queue.last log[:user_id].should == user.id

テスト時

Page 43: fluentd を利用した大規模ウェブサービスのロギング

class CookpadLogger module PVLog def post(tag, data) super tag, normalize(data) end def normalize(data); do_something data; end end

def self.pvlog @@pv_log ||= lambda { logger = create_logger ‘cookpad.pvlog’ logger.extend PVLog }.call end

ロガーへの実装追加

Page 44: fluentd を利用した大規模ウェブサービスのロギング

Tips•バッファからすぐ処理•$ pkill -USR1 -f fluentd•flush_interval 1s # 設定に•設定ファイルを再読み込み•$ pkill -HUP -f fluentd•(ただしGemfile/ライブラリ更新時はうまくいかない)

Page 45: fluentd を利用した大規模ウェブサービスのロギング

嵌ったこと•td-agent の設定ファイルの反映後の再起動漏れ

•初期設定のまま運用してしまった•設定でルーティングにミスっても ”エラーにならない”

•集計時、ちょっと少ないことに気づいて調査

•ngrep で転送されてないサーバが!

Page 46: fluentd を利用した大規模ウェブサービスのロギング

こうなったら嬉しいな•fluentd の設定ファイルをもっと柔軟に•今ほぼ全部の plugin を独自 git のレポジトリで管理

•正規表現/フィルター等…•変数等使えないため設定のコピペが…•それ Ruby の DSL で?

Page 47: fluentd を利用した大規模ウェブサービスのロギング

ログの重要性•数値は “何が正しいか” の指針に•ログを取る、が fluentd で簡単に•きちんと統計を考えられるエンジニア•巨大データ処理 -> Map/Reduce の出現で簡単に

•どのデータに何の価値があり、それを仕事に結びつけらるか

Page 48: fluentd を利用した大規模ウェブサービスのロギング

提供

Page 49: fluentd を利用した大規模ウェブサービスのロギング

提供データを通じて料理をより楽しくしていきたいデータマイニングエンジニア

大募集中です!

Page 50: fluentd を利用した大規模ウェブサービスのロギング

提供質問?

Rails

AWS MySQLEMRmongodb

サービス開発統計

Rubyfluentd

パフォーマンスmiyagawa