在上篇结尾处我提到“如果现在让我重新选择,我会使用哪个可视化工具?”我的答案是 Redash,原因主要不是功能层面,而是技术层面。本篇就从项目关注度与活跃度,项目的技术架构,源代码的规模与质量,这三个方面来比较一下 Superset,Redash 与 Metabase。
看一个项目在 Github 上的星数,是评判一个项目成熟度最快速的方法。那除了星数以外,项目的 Github 页面上还有什么重要信息呢?这里我建议大家去看一看项目的 Insights。首先我们来看 Superset 最近一个月的活跃度
这张图告诉我们以下几个信息
接着我们来看项目的长期指标,提交历史与贡献者的分布
项目的开发很平稳,最近一年的提交数量与之前相比维持在一个稳定的水平。但 Superset 有一个潜在风险就是近半年来几乎所有的提交都来自同一个开发者。对于如此规模的项目来说,这不是一件好事。首先,随着受关注度的提高,单个人的输出可能无法满足社区里的各种需求,项目的迭代速度会因些受到影响。其次,项目可能会因为主力开发者的个人因素遭巨大影响,例如他对项目的热情减退,或是因为工作原因无法继续投入等等。所以理想情况是能有两个或以上的主力开发者。
我们可以用类似的方法分析 Redash 与 Metabase 这两个项目,三个项目的总体情况在下表中
项目星数上月提交数量上月PR主力开发者
从中可以发现,虽然 Superset 在 Github 上的星数遥遥领先其他两个项目,但从迭代速度与开发者数量上来说是落后的。
Redash 在之前的三年时间里一直只有一个主力开发者,但在 2017.10 之后有另一个主力开发者加入。总体来说,Superset 与 Redash 仍是个人秀,只有 Metabase 背后有一个团队在支撑。从产品的完成度与更新速度上看,Metabase 也是三个项目中最好的。
这里说的技术架构包括开发用的语言,核心框架,以及所用到的第三方组件等。目前,我看开源项目的技术架构,主要考查以下几个方面
1),2),3)的重要性是显而易见的,这里对 4)做一个补充说明。这里的对外接口,一般就是指 RESTful API。为什么这很重要呢?首先,如果一个项目有出色 RESTful API,它就很容易与其它系统对接。并且可以在不改动源码的前提下,做很多的二次开发。其次,虽然在界面上操作很直观,但要做大量重复劳动时,写脚本调用 API 来完成操作会更高效。例如,公司的报表有很多是类似,用 API 来创建这些报表可以避免界面上的重复操作,减少错误。
接下来我们就从上述 4 个方面对 Superset 做一个技术分析。
Superset 的后端用 Python 开发,主要用到的开源组件包括
我当前团队的主力语言是 Python,所以这是一个加分项。SQLAlchemy 是非常成熟的数据库 ORM 解决方案,也没毛病。但问题出在了 FAB 上。注意,不要把这个开源组件与 Flask 混为一谈,FAB 是构架在 Flask 之上的一个应用开发框架,可以根据数据库的表结构,自动生成增删查改的前端界面,功能上类似 Django Admin。
FAB 在初期可能可以为 Superset 的开发节省一些写前端代码的时间,但从中长期来说,它严重限制了 Superset 界面的灵活性。在上篇文章中,我就吐槽过 Superset 里 Dasbhoard 的管理不方便,权限系统复杂,其实就是受制于 FAB。另外,FAB 本身已处于半死状态,从 Github 上的记录看,从 2016 后就没什么更新了。
在我看来,Superset 的开发者在选 FAB 做为核心框架时是有欠考虑的。在选框架时,我觉得应该为自己选择一组称手的工具,而不是一件半成品。好的工具可以至始至终为你提升开发效率。而半成品虽然在初期能让你快速搭出一个 MVP,但长远来看一定会挡你的路。FAB 就属于后者。如果做简单的管理系统或是开发原型,FAB 是不错的选择。但 Superset 的目标是成为一个优秀的开源商业分析平台,FAB 注定会成为绊脚石。
在前端,Superset 借助 FAB 来生成大部分管理界面,而图表或是 SQL 编辑器等对交互性要求很高的界面,则由 React + Redux 来实现。这种混合的模式让前端代码显得有些乱,说到底还是 FAB 留下的祸根。
Superset 的部署还是很简单的。Web 服务器是一个标准的 WSGI 应用,存储层支持用任意的 SQL 数据库(只需 SQLAlchemy 支持),所以部署方面无论是高可用还是水平扩展都很方便。
至于 API 接口方面,FAB 原生支持 RESTful API,可以对大部分对象做 CRUD 操作。但认证方式不够灵活,只能通过 cookie,这对于脚本或是服务器端调用不太友好,所以我们对 Superset 做的第一个扩展就是添加了 API Token 的认证方式。
Redash 的服务器端同样是用 Python 来写的,Web 框架以 Flask 为基础,并充分利用了 Flask 的插件生态圈,主要用了以下的组件
个人觉得 Redash 的选择比 Superset 更明智,选用的都是典型的工具型组件,不会对项目将来的发展产生限制。并且以上列出的三个开源组件都是很成熟的项目,在 Python 社区中被广泛应用。
Redash 的前端是一个纯的单页应用,用 AngularJS(1.5)实现,结构清晰,代码整洁。但众所周知,AngularJS 在 v2 之后做了巨大的架构调整,所以 AngularJS v1的处境就有些尴尬。这和目前 Python 2 的处境类似。短期内不会有问题,长期来讲是个隐患。
在部署上,Redash 除了 SQL 数据库外,还依赖于 Redis,但 Redis 只用来保存查询锁(防止多个相同查询同时进行),不需要做持久化。总体上说,Redash 的部署也比较简单。另外,Redash 直接提供了 AWS 上的镜像,以及开发环境的 docker-compose 配置,无论是对运维人员还是开发人员都蛮贴心的。
Redash 也提供了完整的 RESTful API 接口,它前端的单页应用就是通过这套 API 与后端通讯的,所以理论上在前端界面上做的任何事,都可以用 API 来完成。它的 API 原生支持 API Token 的认证方式。
总体而言,Redash 在技术架构上做得比 Superset 更出色。
Metabase 的后端是用 Clojure 写的,前端是用 React + Redux 写的单页应用。
由于我对 Clojure 几乎一无所知,所以后端架构方面也就不好做什么评价了。React + Redux 是目前最流行的前端开发框架之一,Metabase 的系统切分与模块化做得非常出色,所以在前端架构方面 Metabase 我给满分。
Metabase 是三个项目中唯一提供完整 API 文档的项目,这使得开发者即使完全不会 Clojure,依然可以凭借丰富的 API 与文档完成许多二次开发。
部署方面,Metabase 提供了 Jar 文件,Mac 应用程序,Docker 镜像等方式可以让使用者在本地快速尝试该项目。而在生产环境中,它提供了如何在 AWS、Heroku、Kubernetes 上部署的详尽文档,可谓体贴入微。
以下是截至 2017 年 1 月 21 日,三个项目的源代码的行数与测试代码行数。
项目前端代码行数/测试行数后端代码行数/测试行数
从源代码规模来看,Metabase 的规模明显大于另两个项目,这一方面说明 Metabase 的功能更丰富。另一方面,庞大的代码库会使阅读源码与二次开发的难度更大。Superset 的规模略大于 Redash,这也与两个项目的定位相符。
源代码的质量可以做定量与定性的分析,功能代码与测试代码的行数比可以做为一个重要的定量指标,这方面 Metabase 遥遥领先于另两个项目。Superset 与 Redash 做得也还不错,基本处于相同的水平。除此之外,定量分析也可以看单元测试的覆盖率,以及一些静态代码分析工具的结果,这里就不赘述了。
定性的分析则是通过阅读源代码,对代码的逻辑条理与可读性做一个主观评估。在这方面,我的主观评价是 Metabase 的代码品质最高,不仅整体代码结构清晰,模块切分合理,而且代码整洁度到了一个相当变态的水准,看起来赏心悦目。Redash 的代码结构也很干净,可以排第二,Superset 稍略一筹排在末位。这个结果与定量分析的结论是基本一致。
本文以 Superset,Redash,Metabase 三个项目的比较为例,介绍了开源项目选择上的一些原则。在本文的开头,我提到如果重新选择一个数据可视化工具,我会选择 Redash。这主要是因为 Redash 本身拥有合理的技术架构,而 Python 也恰好是团队最熟悉的语言。
当然,不得不提,对 Metabase 这个项目越是深入了解,越觉得它背后一定有非常出色的团队。这个产品从里到外,处处渗透一种追求卓越的品质感,希望它能获得更多的关注与更大的成功!
今天分享就到这里,欢迎大家留言讨论!
-----------------
欢迎关注我的微信公众号:yecomment