本文由 简悦SimpRead 转码,原文地址 osinsight.io
帮助开发团队采用开放源码技术和实践。由软件工程师和社区撰写,......
2022年1月初,我们的CEO Max,一个开源的忠实粉丝,问我的团队是否可以建立一个小工具来帮助我们了解GitHub上所有的开源项目;并且,如果一切顺利的话,我们应该开放API来帮助开源开发者建立更好的洞察力。事实上,GitHub通过开放的API不断发布其开源世界中的公共事件。(谢谢你,做得好!Github)。我们当然可以从数据中学习到很多东西!
我对这个项目很兴奋,直到Max说。"你只有一个星期的时间"。好吧,老板就是老板! 虽然时间很紧,而且我们面临着多个令人头疼的问题,但我还是决定接受这个挑战。
头疼1:我们需要历史和实时数据。
经过快速研究,我们找到了GHArchive,这是一个开源项目,收集和归档2011年以来所有GitHub的数据,并每小时更新一次。顺便说一句,很多开源的分析工具,比如CNCF的Devstats也是依靠GH Archive。
感谢GH Archive,我们找到了数据源。
但还有一个问题:每小时的数据是好的,但还不够好。我们希望我们的数据是实时更新的,或者至少是接近实时的。我们决定直接使用GitHub事件API,它收集了过去一小时内发生的所有事件。
通过结合GH档案和GitHub事件API的数据,我们可以获得流式的实时事件更新。
GitHub事件更新
头痛2:数据是巨大的!
在我们对GH Archive的所有数据进行解压后,我们发现有超过46亿行的GitHub事件。这是个很大的数据量! 我们还注意到,每小时大约有30万行的数据被生成和更新。
2011年以后发生的GitHub事件的数据量
数据库的解决方案在这里会很棘手。我们的目标是建立一个基于持续增长的数据集提供实时数据洞察力的应用程序。所以,可扩展性是必须的。NoSQL数据库可以提供良好的可扩展性,但接下来的是如何处理复杂的分析查询。不幸的是,NoSQL数据库在这方面并不擅长。
另一个选择是使用OLAP数据库,如ClickHouse。ClickHouse可以很好地处理分析工作负载,但它不是为服务在线流量而设计的。如果我们选择它,我们将需要另一个数据库来处理在线流量。
分片数据库,然后建立一个提取、转换、加载(ETL)管道,将新的事件同步到数据仓库,怎么样?这听起来是可行的。
RDBMS如何处理GitHub的数据?
根据我们产品经理(PM)的计划,我们需要做一些针对 repo 或用户的分析。虽然总的数据量很大,但对于单个项目或用户来说,事件的数量不会太大。这意味着使用RDBMS中的二级索引将是一个好主意。但是,如果我们决定使用上述架构,在选择数据库分片键时,我们必须谨慎。例如,如果我们使用 "user_id "作为分片键,那么基于 "repo_id "的查询就会非常棘手。
PM的另一个要求是,我们的洞察力工具应该提供OpenAPI,这意味着我们会有来自外界的不可预测的并发流量。
由于我们不是Kafka和数据仓库方面的专家,在短短一周内掌握并建立这样一个基础设施对我们来说是非常困难的。
现在的选择是显而易见的,别忘了PingCAP是一家数据库公司! TiDB似乎是一个完美的选择,这也是我们吃自己的狗粮的好机会。所以,为什么不使用TiDB! :)
如果我们使用TiDB,我们能否得到:
- 支持SQL,包括复杂和灵活的查询?☑️
- 可扩展性?☑️
- 支持二级索引以实现快速查询?☑️
- 在线服务的能力?☑️
哇!这下子可好了!我们的冠军是谁?看来我们有了一个赢家!
通过使用二级索引,TiDB在4.9ms内扫描了29,639行(而不是46亿行)GitHub事件_
要选择一个数据库来支持像OSS Insight这样的应用,我们认为TiDB是一个很好的选择。 此外,其简化的技术栈意味着更快地进入市场,更快地交付我老板的任务。
在我们使用TiDB之后,我们得到了一个简化的架构,如下图所示。
我们使用TiDB后的简化架构
头痛3:我们有一个 "爱出风头 "的PM!
正如副标题所示,我们有一个非常 "咄咄逼人 "的总理,这并不总是一件坏事。) 他的要求不断延伸,从最开始的单一项目分析到多个资源库的比较和排名,再到其他多维度的分析,比如追星族和贡献者的地理分布。更为紧迫的是,截止日期保持不变!!。
我们必须在不断增长的需求和紧迫的期限之间保持平衡。
为了节省时间,我们使用Docusaurus建立了我们的网站,这是一个开源的静态网站生成器,在React中具有可扩展性,而不是从头开始建立一个网站。我们还使用了Apache Echarts,一个强大的图表库,将分析结果转化为好看且容易理解的图表。
我们选择了TiDB作为数据库来支持我们的网站,它完美地支持SQL。这样,我们的后端工程师就可以编写SQL命令,轻松高效地处理复杂而灵活的分析查询。然后,我们的前端工程师只需要将这些SQL执行结果以好看的图表形式显示出来。
最后,我们成功了。我们仅用一周时间就完成了我们的工具原型,并将其命名为OSS Insight,即开源软件洞察力的简称。我们继续对它进行微调,并在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
;
在上面的语句中,collections和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来说是非常方便的,因为它不需要把查询分成两条语句。
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框架
注意:你可以点击每个图表右上方的 "REQUEST INFO "来获取每个结果的SQL命令。
反馈。人们喜欢它!
在我们于5月3日发布OSS Insight之后,我们在社交媒体上,通过电子邮件和私人信息,收到了许多开发者、工程师、研究人员以及各公司和行业中热衷于开源社区的人的热烈掌声。
我更加兴奋和感激的是,有这么多人认为OSS Insight很有趣,很有帮助,很有价值。我也为我的团队在这么短的时间内做出这么好的产品而感到骄傲。
开发人员和组织在Twitter上给予的掌声
经验教训
回顾我们用来建立这个网站的过程,我们学到了许多令人耳目一新的教训。
首先,快速并不意味着肮脏,只要我们做出正确的选择。 在短短一周内建立一个洞察力工具是很棘手的,但感谢那些美妙的、现成的、开源的项目,如TiDB、Docusaurus和Echarts,我们以高效率和不影响质量的方式实现了它。
其次,选择正确的数据库至关重要--特别是支持SQL的数据库。 TiDB是一个分布式的SQL数据库,具有很好的可扩展性,可以处理交易和实时分析工作负载。在它的帮助下,我们可以轻松地处理数十亿行的数据,并使用SQL命令来执行复杂的实时查询。此外,使用TiDB意味着我们可以利用它的资源,更快地进入市场并及时获得反馈。
如果你喜欢我们的项目或有兴趣加入我们,欢迎你提交你的PR到我们的GitHub仓库。你也可以在Twitter上关注我们,了解最新信息。
注
如果你想获得自己的见解,你可以加入我们的研讨会并尝试使用TiDB来支持你自己的数据集。