1日に3,000万件のログを収集し解析するシステムの構築

こんにちは。函館ラボの高橋です。

本日は弊社が手掛けたCouchbaseの導入事例を1つご紹介したいと思います。

弊社では、大量のメールマガジンを配信するシステムを開発しましたが、運用/保守にあたり以下のような問題がありました。

問題

配送エラーとなるメールアドレスに何度もメールを送り続けているとそのプロバイダ全体でメールの受け取りをブロックされてしまう。

配送エラーとなる理由は様々ですが、例えば利用者自身がYahoo!などのフリーメアドの使用を止めたが購読していたメルマガを解除していなかった。等です。 (大抵のフリーメールは一定期間ログインしないと無効なアドレスにされてしまいます。利用している方は注意を!)

一度このプロバイダの受信ブロックが発生してしまうと同じドメインの利用者全員に影響が及んでしまうため被害は甚大です。 この現象を回避するために、チームで検討を重ねた結果メルマガ配送一件一件の成功/失敗を記録し、その配送状況に応じて配送を行うかどうかの判定をするよう改修を施すことに決まりました。

本配信システムで利用するメルマガサービスはアクティブかつユニークなユーザが1000万人以上、多い日だと1日で3000万通のメールを配送します。 それだけの配送結果を逐一記録するのですからDBには1日中アクセスがあるであろうことは容易に想像出来ます。 (3000万件/日の単純計算でも約0.003秒に1件のデータ登録ですね)

現行のシステムで採用しているRDBももちろん候補にはなりましたがやはりそれだけのアクセスがあると、既存のアプリケーションへの影響も懸念されるため配送結果の履歴専用DBを用意することになりました。

そこで、以下を満たすことを必須条件としてシステムを検討しました。

  • 大量データの追加/参照でもパフォーマンスを発揮する
  • 簡単に構築/運用出来る
  • プログラムに組み込むのが容易である
  • 後のデータ量増加も見据え、サーバの追加でスケールしやすいこと

出来るだけ既存のプロダクトを組み合わせ 開発コストを抑えるために Fluentd + Couchbase の組み合わせで対応することに決定しました。 メルマガ配信エンジンが配送した結果をログに出力しそれをFluentdで解析しCouchbaseに登録しようという算段です。

構築手順

Fluentd + Couchbase 連携

次はFluentdが解析した送信ログCouchbaseへドキュメントとして登録する必要があります。 幸い連携pluginがgithubで公開されていましたので採用することにしました。

https://github.com/obieq/fluent-plugin-couchbase

注意

http://fluentd.org/plugin/

上記にFluentdのpluginが記載されていますがページ上部にある「Couch」はCouchDB用ですので気をつけましょう。

が、ここでちょっと問題が起こりました。 実は上記で公開されている連携Pluginですがどうもパスワードの掛ったBucketに対応していません。どこをどう探してもパスワードに該当するパラメーターが無いのです。

通常Couchbaseをセットアップした際には パスワード無の「default」というBucketが作成され特にBucketを指定しなければ、ここにドキュメントが格納されますが業務で使用する際には別のBucketを作成し、パスワードを掛けるのが一般的です。

仕方ないのでforkしてカスタマイズすることにしました。このカスタマイズ版は https://github.com/atware/fluent-plugin-couchbase

こちらで公開していますので、もしよければご自由にお使いください。

カスタマイズ内容は以下になります。

  • DocumentIdの生成
  • パスワード付きBucketとの連携
  • Fluentd のタグ、時間をCouchbaseのドキュメントに持たせる

チューニング

AWSなどを利用し、リソースがふんだんに使える場合にはそれほど気にする必要はないのですが今回はそうもいかなかったので、チューニングにはかなり気を使いました。

といっても、速度面ではさすがCouchbaseといったところで特にチューニングの必要はありませんでした。

問題はメモリサイズとドキュメント量です。 Couchbaseは格納されているドキュメントのメタ情報をメモリに展開するのですが、それが限界に達するとドキュメントが登録されなくなります。

そのため

  • メタ情報(主にDocumentIdの長さ)を出来るだけ小さく
  • 内容が重複するドキュメントを作成しない

    (対象のデータが同一の場合は常に最新のみを保持する)
  • そのうえで、おおよそ何日分のドキュメントを格納できるか

を徹底的に調査しました。

もともとCouchbaseには配送結果を一時的に保存しその後、日次のバッチ処理でRDBに永続化するつもりでした。下の図のようなフローでの運用です。 そのためドキュメントの有効期限を短くしても運用には問題ありませんでしたのでとりあえず有効期限を3日にして運用を開始しました。

運用

Couchbase→RDBの個所は業務色が強過ぎるため割愛しますが

CouchbaseのJavaClientLibraryにはドキュメント操作の各種APIが用意されておりそのAPI経由でドキュメントの参照/更新等のオペレーションを行いますので既存アプリケーションへの組み込みは非常に簡単なものでした。

(トランザクションなどを気にしなくてよい)

運用後は常時4千万~7千万近くのドキュメントを保持しながらピーク時には秒間1,500件のオペレーションを捌き特に問題もなく稼働しています。 また、Couchbaseの特徴として管理画面が非常に多機能な上にわかりやすいので運用面では相当役に立つと思います。

余談ですが、今回の事例で使用したサーバーのスペックは高くはありません。旧型なWebサーバー(Xeon Quad, 6GB RAM)の1台構成です。性能面での参考になればと思います。

今回導入したFluentd + Couchbase の組み合わせはログ解析・調査ではかなり有効な手段であることも実感しました。 また別の案件で機会があれば積極的に採用したいと思います。