TiDB User Day 2024のアーカイブ動画を公開中!詳細を見る
20220621-165556

執筆者Wink Yao, Head of Global Community at PingCAP
トランスクリエーターFendy Feng
 編集者Ed Huang, Calvin Weng, Tom Dewan

※このブログは2022年6月21日に公開された英語ブログ「Build a Better Github Insight Tool in a Week? A True Story」の拙訳です。

2022年1月初旬、オープンソースの大ファンであるPingCAP CEOのMaxは、GitHub上のすべてのオープンソースプロジェクトを把握するための小さなツールを作れないか、そしてすべてがうまくいけば、オープンソース開発者がより良い洞察を構築できるようにAPIを公開しないか、と本ブログの執筆者であり、PingCAPでHead of Community & Developer Ecosystem Teamを務めるWiink Yaoに尋ねました。実際、GitHubはオープンソースの世界での公開イベントをオープンAPIを通じて継続的に公開しています。 (ありがとう、そしてよくやった!GitHub)。私たちは確かに、データから多くのことを学ぶことができます。

Maxに「1週間しかない」と言われるまで、私はこのプロジェクトに興奮していました。しかし、上司は上司です。時間が限られており、頭を悩ます問題がいくつもありましたが、私はこのプロジェクトに挑戦することにしました。

難題1:過去のデータとリアルタイムのデータの両方が必要

早速調べてみると、2011年からのすべてのGitHubデータを収集・アーカイブし、1時間ごとに更新しているオープンソースプロジェクトGHArchiveを見つけました。ちなみに、CNCFのDevstatsなど、多くのオープンソースの分析ツールもGH Archiveに頼っているそうです。

GH Archiveのおかげで、データソースを見つけることができました。

しかし、もう一つ問題があります。1時間ごとのデータは良いのですが、十分ではありません。私たちは、データをリアルタイムに、あるいは少なくともリアルタイムに近い状態で更新することを望んでいました。そこで、過去1時間以内に発生したすべてのイベントを収集するGitHub event APIを直接使用することにしました。

GH ArchiveのデータとGitHub event APIを組み合わせることで、ストリーミングでリアルタイムのイベント更新ができるようになりました。

GitHubイベントの更新

難題2:データが膨大!

GH Archiveのデータをすべて展開したところ、GitHubのイベントが46億行以上あることがわかりました。これはすごいデータ量です。また、1時間に約30万行が生成・更新されていることにも気づきました。

2011年以降に発生したGitHubのイベントデータ量

ここでデータベースソリューションは難しいでしょう。私たちの目標は、継続的に増加するデータセットに基づき、リアルタイムのデータ洞察を提供するアプリケーションを構築することです。ですから、スケーラビリティは必須です。NoSQLデータベースは優れたスケーラビリティを提供できますが、その後に続くのは、複雑な分析クエリをどう扱うかです。残念ながら、NoSQLデータベースはそれが苦手です。

また、ClickHouseのようなOLAPデータベースを使用する方法もあります。ClickHouseは分析ワークロードに非常によく対応できますが、オンライントラフィックを提供するようには設計されていません。もしこれを選んだ場合、オンライントラフィックのために別のデータベースが必要になります。

データベースをシャーディングし、抽出、変換、ロード (ETL) パイプラインを構築して、新しいイベントをデータウェアハウスに同期させるのはどうでしょうか。それならうまくいきそうですね。

RDBMSによるGitHubデータの扱い方

プロダクトマネージャー (PM) の計画によると、レポジトリ固有またはユーザー固有の分析を行う必要がありました。データ総量は膨大ですが、1つのプロジェクトやユーザーに対してのイベント数はそれほど多くありません。つまり、RDBMSのセカンダリインデックスを使用するのが良いということでした。しかし、上記のようなアーキテクチャを採用する場合、データベースのシャーディングキーの選定に注意が必要でした。例えば、user_idをシャーディングキーとして使用する場合、repo_idに基づくクエリは非常に扱いにくいものになります。

PMからのもう一つの要件は、インサイトツールがOpenAPIを提供することでした。これは、外部からの予測不可能な同時トラフィックが発生することを意味します。

私たちはKafkaやデータウェアハウスの専門家ではないので、このようなインフラを1週間でマスターし構築することは非常に困難なタスクでした。

もう選択は明らかです。PingCAPはデータベースの会社であることをお忘れなく!TiDBはこれにぴったりなようで、自分たちの武器を試す良い機会です。というわけで、TiDBを使ってみましょう!:)

TiDBを使ったら:

  • 複雑で柔軟なクエリを含むSQLのサポートができる?答えはYES ☑️
  • スケーラビリティは可能?答えはYES ☑️
  • 高速ルックアップのためのセカンダリインデックスのサポートができる?答えはYES ☑️
  • オンラインサービスの機能を備えている?答えはYES ☑️

すごい!勝者が出たようですね。

セカンダリーインデックスを使用することで、TiDBは29,639行 (46億行の代わりに) のGitHubイベントを4.9 msでスキャン

OSS Insightのようなアプリケーションをサポートするデータベースを選ぶには、TiDBは最適な選択だと思います。その上、そのシンプルなテクノロジースタックは、より迅速な市場投入と、上司の仕事のより迅速な割り当てを意味します。

TiDBを使用した結果、以下のような簡略化されたアーキテクチャを得ることができました。

TiDBを利用した場合の簡略化されたアーキテクチャ

難題3:「強引な」PMがいる!

サブタイトルにあるように、私たちは非常に “強引” なPMを抱えているわけですが、それは必ずしも悪いことではありません。彼の要求は、最初の単一プロジェクトの分析から、複数のリポジトリの比較やランキング、さらにはスターゲイザーやコントリビューターの地理的分布といった多次元的な分析に至るまで、どんどん膨らんでいきました。それよりも切実なのは、締め切りが変わらないことです!!!

高まる要求と厳しい納期の間でバランスを保つ必要がありました。

時間を節約するため、ゼロからサイトを構築するのではなく、拡張性のあるReactのオープンソースの静的サイトジェネレーターであるDocusaurusを使用してサイトを構築しました。また、パワフルなチャート作成ライブラリであるApache Echartsを使用し、分析結果を見栄えの良い、わかりやすいチャートに変換しました。

ウェブサイトを支えるデータベースとしてTiDBを選びましたが、幸いなことにTiDBはSQLを完璧にサポートしています。これにより、バックエンドエンジニアは、複雑で柔軟な分析クエリを処理するためのSQLコマンドを簡単かつ効率的に作成することができます。そして、フロントエンドのエンジニアは、そのSQLの実行結果を見栄えのよいチャートの形で表示するだけでよいのです。

そして、ついに完成したのです。わずか1週間でプロトタイプを完成させ、OSS Insight (open source software insightsの略) と名付けました。その後も微調整を重ね、2022年5月3日に正式リリースしました。

SQLによる分析クエリの扱い方

複雑な分析用クエリをどのように扱うのか、ひとつの例で見てみましょう。

GitHubのコレクションを分析:JavaScriptフレームワーク

OSS Insightは、人気のあるGitHubコレクションを、スター数、イシュー数、コントリビューター数など多くの指標で分析することができます。どのJavaScriptフレームワークが最も多くの課題作成者を抱えているかを特定してみましょう。これは、集計とランキングを含む分析クエリです。結果を得るために必要なのは、SQL ステートメントをひとつ実行するだけです。

SELECT
   /*+ read_from_storage(tiflash[ge]) */
   ci.repo_name  AS repo_name,
   COUNT(distinct actor_login) AS num
FROM
   github_events ge
   JOIN collection_items ci ON ge.repo_id = ci.repo_id
   JOIN collections c ON ci.collection_id = c.id
WHERE
   type = 'IssuesEvent'
   AND action = 'opened'
   AND c.id = 10005
   -- Exclude Bots
   and actor_login not like '%bot%'
   and actor_login not in (select login from blacklist_users)
GROUP BY 1
ORDER BY 2 DESC
;

上記のステートメントでは、collectionおよびcollection_itemsテーブルに、GitHubリポジトリの全コレクションのデータをさまざまな領域で保存しています。それぞれのテーブルには30行あります。イシューの作成者順を知るには、以下のようにcollection_itemsテーブルのリポジトリIDと46億行のgithub_eventsテーブルの実体を関連付ける必要があります。


mysql> select * from collection_items where collection_id = 10005;
+-----+---------------+-----------------------+-----------+
| id  | collection_id | repo_name             | repo_id   |
+-----+---------------+-----------------------+-----------+
| 127 | 10005         | marko-js/marko        | 15720445  |
| 129 | 10005         | angular/angular       | 24195339  |
| 131 | 10005         | emberjs/ember.js      | 1801829   |
| 135 | 10005         | vuejs/vue             | 11730342  |
| 136 | 10005         | vuejs/core            | 137078487 |
| 138 | 10005         | facebook/react        | 10270250  |
| 142 | 10005         | jashkenas/backbone    | 952189    |
| 143 | 10005         | dojo/dojo             | 10160528  |
...
30 rows in set (0.05 sec)

次に、実行プランを見てみましょう。TiDBはMySQLの構文と互換性があるので、実行プランはMySQLと非常によく似ています。

下図で、赤枠の部分に注目してください。collection_itemsテーブルのデータはdistributed [row] を介して読み込まれており、このデータはTiDBの行ストレージエンジンであるTiKVで処理されることを意味しています。github_eventsというテーブルのデータはdistributed [column] で読み込まれ、このデータはTiDBのカラム型ストレージエンジンであるTiFlashで処理されることを意味しています。TiDBでは行単位と列単位のストレージエンジンを使い分け、同じSQLステートメントを実行します。これはOSS Insightにとって、クエリを2つのステートメントに分割する必要がないので、とても便利です。

TiDBの実行プラン

TiDBは次のような結果を返します。

+-----------------------+-------+
| repo_name             | num   |
+-----------------------+-------+
| angular/angular       | 11597 |
| facebook/react        | 7653  |
| vuejs/vue             | 6033  |
| angular/angular.js    | 5624  |
| emberjs/ember.js      | 2489  |
| sveltejs/svelte       | 1978  |
| vuejs/core            | 1792  |
| Polymer/polymer       | 1785  |
| jquery/jquery         | 1587  |
| jashkenas/backbone    | 1463  |
| ionic-team/stencil    | 1101  |
...
30 rows in set
Time: 7.809s

あとは、その結果をApache Echartsで以下のように、より可視化されたチャートに書き出すだけです。

イシュー作成者が多いJavaScriptフレームワーク

Note:各チャートの右上にあるREQUEST INFOをクリックすると、各結果のSQLコマンドを取得できます。

フィードバック:皆大好き!

2022年5月3日にOSS Insightをリリースしてから、ソーシャルメディアやメール、プライベートメッセージなどで、多くの開発者、エンジニア、研究者、さまざまな企業や業界のオープンソースコミュニティに関心を持つ方々から、大きな評価をいただいています。

これほど多くの方がOSS Insightを面白い、役に立つ、貴重だと感じてくださっていることに、この上ない喜びと感謝の気持ちでいっぱいです。また、私のチームが短期間でこのような素晴らしいプロダクトを作り上げたことを誇りに思っています。

Twitterで開発者や組織から寄せられた賞賛の声

学んだこと

このウェブサイトを構築する過程を振り返ると、私たちは多くの新しい学びを得ることができました。

まず1つ目は、正しい選択をすれば、速いということは雑ということではありません。インサイトツールを1週間で作るのは大変なことですが、TiDB、Docusaurus、Echartsなどの素晴らしいオープンソースプロジェクトのおかげで、効率的にかつ品質に妥協することなく、インサイトツールを構築することができました。

そして2つ目は、適切なデータベース、特にSQLをサポートするデータベースを選択することが重要です。TiDBは分散型SQLデータベースで、トランザクションとリアルタイムの分析ワークロードの両方を処理できる優れたスケーラビリティを備えています。数十億行のデータを簡単に処理し、SQLコマンドで複雑なリアルタイムクエリを実行することができます。さらに、TiDBを使用することで、そのリソースを活用し、より早く市場に投入し、迅速にフィードバックを得ることができます。

PingCAPのプロジェクトに興味がある方は、ぜひGitHubのリポジトリにPRを投稿してください。また、Twitterで私たちをフォローすれば、最新情報を得ることができます。

私たちのワークショップに参加してみませんか?OSS Insightについてさらに深く学び活用したい場合は、ワークショップ (※英語) に参加してみましょう。


このブログは、OSS Insightのウェブサイトで最初に公開されました。

Keep reading:
HTAPの魅力:TiDBとAlloyDBの比較・分析
リアルタイム分析HTAPデータベース構築への長い道のり
RetoolとTiDB Cloudを使って30分でリアルタイムカンバンを作る


Want to explore TiDB without installing any software? Go to TiDB Playground

Have questions? Let us know how we can help.

Contact Us

TiDB Cloud Dedicated

TiDB Cloudのエンタープライズ版。
専用VPC上に構築された専有DBaaSでAWSとGoogle Cloudで利用可能。

TiDB Cloud Serverless

TiDB Cloudのライト版。
TiDBの機能をフルマネージド環境で使用でき無料かつお客様の裁量で利用開始。