3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

15万件のLINEオープンチャットを毎時クロールする「オプチャグラフ」のデータパイプライン構築

Last updated at Posted at 2025-07-09

🎯 はじめに

こんにちは、オプチャグラフの開発者です。

オプチャグラフは、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つのカテゴリ(ランキング・急上昇)を担当します。

並列化の技術的考察:

  1. プロセス間の競合回避

    • 各プロセスは独立したファイルに結果を保存
    • 親プロセスはファイルの取得件数チェックのみ(ロック不要)
  2. 負荷分散の工夫

    • カテゴリを正順・逆順で割り当て
    • 人気カテゴリ(ゲーム等)と不人気カテゴリを組み合わせ
    • 処理時間の平準化を実現
  3. エラーハンドリング

    • プロセスごとに独立したエラーログ
    • 部分的な失敗でも他のカテゴリは継続
    • リトライは次回の定期実行の30分前に自動回復

💾 (2) 差分検出とデータマージ

インテリジェントな更新戦略

全15万件のうち、実際に更新が必要なのは1時間あたり約1-2%のみ。この特性を活かした差分更新システムを構築しました。

差分検出の詳細:

  1. ハッシュ値による高速比較

    • 名前、説明文、メンバー数を結合してハッシュ生成
    • 前回取得時のハッシュと比較
    • 変更があった場合のみDBアクセス
  2. MySQL更新パターンの分類

    新規発見: 約100-200件/時(INSERT)
    メンバー数変更: 約1,000-2,000件/時(UPDATE)
    メタデータ変更: 約50-100件/時(UPDATE)
    削除・非公開: 約10-50件/時(フラグ更新)
    
  3. バルクインサートの活用

    • 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コネクション枯渇
  • レスポンスタイム悪化

静的ファイル戦略の詳細

  1. 生成タイミングの最適化

    • クローリング完了直後に全ランキング生成
    • gzip圧縮で容量を1/5に削減
    • 生成時刻をメタデータとして保存
  2. キャッシュ階層の設計

    L1: ブラウザキャッシュ(1分)
    L2: CDNキャッシュ(5分)
    L3: 静的JSONファイル(60分)
    
  3. 部分更新の実現

    • ランキングは静的配信
    • 個別詳細は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円程度のレンタルサーバーでも、大規模なデータ分析サービスを安定運用できることを実証しました。

🔗 リンク

オープンソースプロジェクトとして公開していますので、ぜひコードを見てみてください。PRやIssueもお待ちしています!


この記事は、オプチャグラフのソースコードとデータベースをAIアシスタントClaude(Anthropic)が分析し、技術的な考察を加えて生成したものです。

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?