【Show HN】生イベントを捨てて「答え」を蓄積する!爆速OSS分析ライブラリ「Trifle」
Show HN: Trifle – Open-source analytics that stores answers, not events
Trifleは、生イベントをそのまま保存するのではなく、ネストされたカウンタを集計して保存するオープンソースの時系列分析ライブラリです。既存のデータベースをそのまま活用できるのが強みです。10年間で2度のフルスクラッチを経て、現在では本業の現場で1日あたり約10億イベントの追跡に使用されています。2015年、自作のRails用APMとしてスタートしました。当初はActiveSupport::Notificationsを利用していましたが、ある大規模なスクレイピングアプリがシステムをパンクさせたことを機に、「事前定義された時間バケットにカウンタを集計し、一度の書き込みで複数のバケットをインクリメントする」というコアアイディアが生まれました。2021年、本業で分析基盤が必要になった際、データウェアハウスの概念を取り入れて汎用的な分析ライブラリとして再設計しました。Redis、Postgres、MongoDBと変遷してきたため、Trifle::Statsは統一されたDSLを維持しながら、ニーズに応じてバックエンドを変えられるドライバ構成になっています。書き込み負荷が高い環境では、PGよりもMongoDBの方が効率的でした。肝となるのはネストされた値の集計です。以下のコードをご覧ください。Trifle::Stats.track(key: 'requests::aws::s3_uploads', values: {count: 1, status: { request.response_code => 1 }, size: payload.bytes, duration: { sum: request.duration, count: 1 }})このように書くことで、リクエスト数、成功率、ステータスコード、処理時間などを一度に複数の時間バケットへ反映できます。午前2時のバケットデータは以下のようになります。{ count: 14, status: { 200: 12, 500: 2 }, size: 5628341, duration: { sum: 43, count: 14 } }成功率や平均処理時間は保存時に計算するのではなく、クエリ時に「合計÷件数」で算出します。ダッシュボード作成の手間を省くため、Elixir製の視覚化レイヤー「Trifle App」も開発しました。現在はライブラリ側もRuby、Elixir、Goで利用可能で、互換性も保たれています。1日1億件のバックグラウンドジョブ(約10億イベント)を処理しており、MongoDBのジャーナリング設定を調整するなど、安全性を一部トレードオフにすることで非常に低コスト(Hetznerの3ノード構成で月額1000ドル程度)で運用できています。もちろん制限もあり、ペイロードに数万ものキーを持たせたり、ディメンション設計を誤るとドキュメントが肥大化します。設計段階での工夫は必要です。ライブラリはMITライセンス、Appはソース公開のELv2ライセンス(セルフホスト無料)です。投資家資金なしの個人開発ですが、興味を持っていただければ幸いです。アーキテクチャや技術的な失敗談など、何でも聞いてください!