🎯 はじめに
こんにちは、オプチャグラフの開発者です。
オプチャグラフは、15万件以上のLINEオープンチャットの統計情報を収集・分析・可視化するWebサービスです。
本記事では、毎時15万件のデータを収集し、6,000万レコードを超えるデータベースから瞬時に統計情報を生成するデータパイプラインの設計と実装について解説します。
注:この記事はAIアシスタントのClaude(Anthropic)が、実際のオプチャグラフのソースコードとデータベースを分析して生成しました。技術的な内容は開発者による確認済みです。
📊 オプチャグラフとは
オプチャグラフは、LINEが2023年10月に公開したオープンチャット公式サイトのデータを収集し、以下の機能を提供しています:
主要機能
- リアルタイム人数推移グラフ: 各オープンチャットの成長を可視化
- 増加率ランキング: 1時間/24時間/1週間単位での急成長チャンネル発見
- 検索・フィルタリング: 15万件から目的のチャンネルを高速検索
収集データの規模(2025年7月現在)
総オープンチャット数: 約150,000件
日次統計レコード数: 約60,000,000件
更新頻度: 1時間ごと
データ取得時間: 約10分
🏗️ システムアーキテクチャ
データフローの全体像
[LINE公式サイト]
↓ (1) 並列クローリング(24プロセス)
[一時ストレージ(JSON)]
↓ (2) 差分検出・データマージ
[MySQL(マスターデータ)]
↓ (3) 統計計算・集計
[SQLite(統計データ)]
↓ (4) 静的ファイル生成
[キャッシュ(静的JSON)]
↓ (5) API/フロントエンド配信
[ユーザー]
この5段階のパイプラインにより、大量のデータを効率的に処理しています。
🚀 (1) 並列クローリングシステム
課題:48種類のランキングを10分以内に取得
LINE公式サイトは以下の構造でデータを提供:
- 24カテゴリ(ゲーム、地域・暮らし、金融・ビジネス等)
- 各カテゴリに「ランキング」と「急上昇」の2種類
- 合計48種類×最大10,000件 = 約100,000件のデータ
解決策:PHPプロセスの並列実行
24個の独立したPHPプロセスを起動し、各プロセスが2つのカテゴリ(ランキング・急上昇)を担当します。
並列化の技術的考察:
-
プロセス間の競合回避
- 各プロセスは独立したファイルに結果を保存
- 親プロセスはファイルの取得件数チェックのみ(ロック不要)
-
負荷分散の工夫
- カテゴリを正順・逆順で割り当て
- 人気カテゴリ(ゲーム等)と不人気カテゴリを組み合わせ
- 処理時間の平準化を実現
-
エラーハンドリング
- プロセスごとに独立したエラーログ
- 部分的な失敗でも他のカテゴリは継続
- リトライは次回の定期実行の30分前に自動回復
💾 (2) 差分検出とデータマージ
インテリジェントな更新戦略
全15万件のうち、実際に更新が必要なのは1時間あたり約1-2%のみ。この特性を活かした差分更新システムを構築しました。
差分検出の詳細:
-
ハッシュ値による高速比較
- 名前、説明文、メンバー数を結合してハッシュ生成
- 前回取得時のハッシュと比較
- 変更があった場合のみDBアクセス
-
MySQL更新パターンの分類
新規発見: 約100-200件/時(INSERT) メンバー数変更: 約1,000-2,000件/時(UPDATE) メタデータ変更: 約50-100件/時(UPDATE) 削除・非公開: 約10-50件/時(フラグ更新)
-
バルクインサートの活用
- 1件ずつのINSERT/UPDATEではなく、1,000件単位でバルク処理
- トランザクションサイズの最適化
- 処理時間を1/10に短縮
📈 (3) MySQLとSQLiteの使い分け戦略
なぜSQLiteを併用?
レンタルサーバーのコスト問題:
- MySQL容量制限: 1GB〜5GB(プランによる)
- 日次統計6,000万レコード = 約8GB
- 容量追加は月額数千円の追加コスト
SQLiteによる解決:
- ファイルベースで容量制限なし
- 統計データは追記のみ(更新なし)
- 日次バックアップが簡単(ファイルコピー)
データ特性に基づく使い分け
MySQL(リアルタイムデータ):
- 頻繁に更新されるマスターデータ
- JOINが必要な正規化されたデータ
- トランザクション整合性が重要
SQLite(時系列データ):
- 一度書き込んだら変更しない統計データ
- 単一テーブルでの高速集計
- ファイル単位でのアーカイブが可能
🎨 (4) 静的ファイル生成による負荷軽減
動的生成の限界
初期実装では、すべてのランキングページを動的生成していました:
- 同じSQLクエリが1分間に100回以上実行
- DBコネクション枯渇
- レスポンスタイム悪化
静的ファイル戦略の詳細
-
生成タイミングの最適化
- クローリング完了直後に全ランキング生成
- gzip圧縮で容量を1/5に削減
- 生成時刻をメタデータとして保存
-
キャッシュ階層の設計
L1: ブラウザキャッシュ(1分) L2: CDNキャッシュ(5分) L3: 静的JSONファイル(60分)
-
部分更新の実現
- ランキングは静的配信
- 個別詳細はAPI経由
- ハイブリッドな配信戦略
📊 データから見える興味深い技術的発見
カテゴリ別の更新頻度分析
更新頻度が高いカテゴリ:
1. ゲーム: 平均2.3%/時のメンバー変動
2. 芸能人・有名人: 1.8%/時
3. 金融・ビジネス: 1.5%/時
更新頻度が低いカテゴリ:
1. 学校・同窓会: 0.3%/時
2. 団体: 0.4%/時
3. 研究・学習: 0.5%/時
🎉 まとめ
オプチャグラフは、レンタルサーバーという制約の中で、15万件のデータを効率的に処理するシステムを構築しました。
技術的な工夫のポイント:
- PHPプロセスの並列実行による高速クローリング
- コスト制約に基づくMySQLとSQLiteの使い分け
- 静的ファイル生成による劇的な負荷軽減
- データ特性に基づく更新戦略の最適化
これらの工夫により、月額1,000円程度のレンタルサーバーでも、大規模なデータ分析サービスを安定運用できることを実証しました。
🔗 リンク
- サービス: https://openchat-review.me/
- GitHub(メイン PHP): https://github.com/pika-0203/Open-Chat-Graph
- 一覧表示コンポーネント(React): https://github.com/mimimiku778/Open-Chat-Graph-Frontend
- グラフコンポーネント(React): https://github.com/mimimiku778/Open-Chat-Graph-Frontend-Stats-Graph
オープンソースプロジェクトとして公開していますので、ぜひコードを見てみてください。PRやIssueもお待ちしています!
この記事は、オプチャグラフのソースコードとデータベースをAIアシスタントClaude(Anthropic)が分析し、技術的な考察を加えて生成したものです。