美图拥有亿级用户,每天都有数千万用户使用美图的各类产品,从而积累了大量的用户数据。随着APP的不断迭代和用户的快速扩张,产品、运营、市场等越来越依赖数据来优化产品功能、跟踪运营效果、分析用户行为等,随之而来的是越来越多的数据统计,分析和其他需求。那么如何应对和满足日益增长的数据统计和分析需求呢?业务的不断发展如何推动架构实现的变革?本文将介绍大数据业务与技术的碰撞产物之一:美图大数据统计分析平台的架构演进,希望本次分享能给大家带来一些解决数据业务与架构的思考。做过大数据相关开发的同学应该都知道,数据统计是一件比较尴尬的事情。第一,可能不是很技术的东西,对技术人员的成长不是很好。第二,可能是一个比较重复的工作,需要重复工作去解决一些简单的需求。美图其实有很多app,每个app基本都有对应的产品运营、销售、数据分析的同学。这些同学会要求各种数据统计,比如数据报表或者数据分析需求。这么多分析或者数据统计的需求,美图是怎么解决的?今天主要想介绍一下美图的解决方案。内容主要分为三个部分:统计业务与技术的碰撞。美图统计平台架构实现。正在做什么以及对未来的一些计划。统计业务和技术的碰撞基本上是我自己的体验。刚开始一个人做这个业务的时候,会遇到一些比较有意思的点,大概分为三个阶段:在项目的前期,我们应该如何处理一些问题?对产品的最初需求。当用户量爆发,业务数据源上来的时候,我们怎么迭代。作为一个有点追求的技术人员,如何才能脱离一些业务,获得一些成长。01.项目前期这个阶段的特点非常明显:以美拍为例,前期整体数据量较小;统计要求比较少,主要是一些基本的统计指标;产品迭代速度非常快,要求数据的统计指标要快速跟上产品的迭代速度。图1这个阶段的解决方案现在看来很简单:一种是业务服务器可能有多个节点来保证可用性,每个业务节点的服务都会打印相应的日志到本地磁盘,然后通过rsync方法统一将日志同步到数据存储节点。在该节点上编写一些简单的shell或PHP脚本实现统计逻辑,配置相应的crontab定时触发统计任务,最后将数据结果存储在MySQL中供展示层调用和呈现报表。02.快速发展阶段当用户数量突然爆发时,数据量会不断增加,对产品运营和数据分析的需求也会增加。相应的,第一阶段的解决方案也会存在比较大的问题,主要表现为:单点存储的容量非常有限。计算瓶颈很快就会遇到瓶颈。在很多情况下,由于计算瓶颈,统计报告会延迟到第二天输出。我们使用shell或PHP脚本来实现统计逻辑。整体后续维护成本比较高,不方便调整一个统计逻辑或者增加一些过滤条件。图2于是我们做了一些调整:实现了一套数据采集系统,负责服务器端日志的数据采集,最后将数据存储在HDFS中。前面我们提到了存储和计算的单点问题,所以我们搭建了一个Hadoop集群来解决单点存储和计算。基于Hive解决统计逻辑相关代码编写过多。03.有抱负的程序员当需求不断扩大时,作为一个有追求的程序员,他们会考虑到有很多重复的代码,即使我们有一层Hive来写相应的代码,最后再做一层数据过滤或一些聚合。其实每一个统计需求我们都需要写一个相应的Java实现。这种工作量非常枯燥和重复。图3一个有抱负的程序员可能不愿意每天做重复性的工作。因为在平时接触业务和实现过程中,深有体会,统计业务逻辑的过程基本都是一样的。所以考虑把这样一个比较通用的业务处理流程抽象出来。基本流程是从数据源Query中提取数据,然后做一些业务聚合或者过滤,最后将数据存储到DB中。它在代码实现层面做了一层抽象,抽象出一个统计组件,包括Query、Aggregator、DBStore,然后实现一些不同的Query和Store场景。做了这样一层抽象之后,相对于之前的方案,生产力有了很大的提升。那个时候自己一个人一天能做四五个统计需求,经过抽象之后,从理解需求到实现,一天大概能做七八个统计需求,整体效率有了很大的提升.美图统计平台的架构实现了以上抽象之后,还有很多痛点:数据业务方面并了解它们。他们的产品是什么样子的,或者他们运营的是做什么活动,商业沟通背景的成本非常高。即使做了抽象,还是会有一些相应的重复代码。还需要做一个统计组件来选择相应的查询,相应的业务逻辑处理和存储层的DBstore。运维成本高。当时需要在线做一个任务,需要修改一些shell等脚本。说到个人成长,当一个人长期做这样的事情,个人的技术成长就会出现比较大的瓶颈。图4基于以上痛点,下面介绍一下我们是如何解决这些事情的。我们考虑搭建一个平台,让商家使用我们的平台,我们只是提供服务。图4是我们当时平台化的总体思路。比如左边的业务端有很多报表数据需求,也可能有APP数据场景、商业广告的数据需求。我们希望提供这样一个平台,业务数据需求方在上面配置自己想要的数据指标,这个平台负责数据的计算、存储,最后吐出相应的数据给数据应用方。再者,在搭建这个平台的时候,我们可能需要考虑以下几个重要的点:我们可能需要对统计任务有一个比较清晰的元数据描述,可以描述这些统计任务的计算方式,计算子是什么。这个统计任务的数据源从哪里来,数据需要存储在哪里更适合业务查询。需要一个调度中心来统一调度所有统计任务的执行。以保证任务的最终正确执行。基于以上几点,认为需要一些不同的模块来负责上述功能。我们大致设计了三个模块:JobManager模块主要是为用户提供一个更方便配置的平台,可以管理任务元数据信息和其他数据仓库,APP信息管理等。Scheduler模块是任务调度中心,它是负责调度所有的统计任务。JobExecutor任务执行模块负责从查询、聚合到最终结果存储的任务。下面详细介绍这三个模块的大概功能点和实现方法。01.JobManager模块该模块主要是一个抽象的统计任务,对任务元数据进行统一的配置管理。如图5所示,主要是需要提供一个应用端,在这个平台上配置自己想要的数据。还有一点就是我们需要有一个集成的数据仓库。集成数据仓库的主要目的是为了业务方查看其对应业务表的信息。图5右边的block主要是元数据统计任务的描述,主要包括这些大block,比如数据的来源,什么是统计算子,特殊场景的存储介质或者数据过滤器,维度聚合和任务之间依赖关系的描述。02.任务调度模块Scheduler目前实现比较简单,是单点方式。目前实现的有几点:可以根据任务的优先级进行调度。可以根据任务定时的策略进行调度。能够调度工作流就是依赖的调度。图603任务执行模块JobExecutor如图6所示,根据任务的来源信息,从插件池中组装出具体的Query组件,然后在具体的Query层运行相应的数据(如作为蜂巢)。数据出来之后,在维度上进行一些过滤,聚合。图7最终根据任务信息组装数据存储层的组件,并将统计数据结果写入存储层。说完三个模块,我们再来回顾一下这个统计平台的基本结构。左边是一个管理元数据的JobManager,根据元数据执行统计任务的整体标准流程:查询、过滤、维度聚合和存储。有了这样的基础框架,可以满足一些基本的数据统计场景,但是如果要支持更多的数据统计业务场景,还需要更多的功能扩展(图8)。在图8中,功能扩展大致有四个方向。对于临时取数据的场景,并不是所有的业务都需要例行运行。有很多临时运行数据的场景。例如,分析师需要临时查看相应APP的功能数据,或者运营需要查看临时的组织活动。数据指标等,通常会遇到很多临时访问的对应需求。为了解决临时访问数据的需求,我们有两个功能。一是提供直接填写SQL的功能,支持有SQL基础的用户临时提取数据。本篇是扩展Hive自带的antlr做HOL语法分析。经过分析,需要验证HOL的合法性,主要是排除一些Insert、Delete等操作,并且限制运行次数的时间范围,以免长时间占用集群计算资源。尽可能丰富数据源。在平时的需求中,越来越多的MySQL数据需要从业务端导入,用于简单的数据统计或者Join计算。所以我们有一个基于Sqoop开发的插件,支持将业务MySQL数据库表导入Hadoop。第三个是Bitmap,是美图自研的系统。主要是方便多维去重和相应的加、存等计算。它的原理主要是基于位之间的运算。多存储目前大部分数据都存储在MongoDB中,介于传统关系型数据库和NoSQL之间。既能满足大部分业务查询场景,又能保证分布式数据存储。二是存在临时比较大数据导出的情况。业务方需要获取比较大批量的数据,可以将这些数据导入到HDFS中,然后业务用户可以从HDFS中导出数据,用于不同的业务应用。第三种也支持一些普通的文本,比如csv等。第四种是MySQL,目前支持分表的一些存储策略。最后一块是丰富统计算子。目前实现了去重、数组、TopN等统计算子。数据可视化如图9所示,因为存储层是多种多样的,原来的做法是我们的??存储层直接暴露给应用的数据后台,他们从我们的存储层查询数据分析。图9中的方法有一些缺点。第一个是如果数据平台没有把存储层做透明,显示层的开发需要学习Hbase、MySQL、Mongo等,学习成本比较大。其次是数据安全的考虑,或者说数据存储的统一管理,这样不好。所以后面集成了一套统一通用的API,提供了一套自定义统一数据的协议,方便展示层。统一对接数据展示。但是以后还是会出现一些问题。我们需要考虑平台化的数据安全,如图10所示。图10比如正常情况下,美拍后台只能获取美拍相关的数据,不允许美拍后台获取美拍相关的数据其他应用程序的商业广告。因此,我们实现了统一的认证中心CA,即业务方后端需要去CA获取相应的授权令牌,然后在请求统一通用API时带上accesstoken。作为通用服务提供者,通用API会去CA验证token是否合法。如果合法,则在存储层查询相应的数据,最后返回给应用端。美图统计平台的整体架构有一个统一的任务调度中心来调度所有的统计任务,然后JobExecutor负责从插件池中找到对应的插件,做一些查询、过滤等。图11.最终数据存储在数据库中。会有一个统一的API封装存储层,然后接入CA出于一些安全的考虑。最后,每个数据后台都连接到通用API进行数据展示。正在做什么以及未来小舞台的规划。12目前正在做的有两件事情,还没有正式上线或接入。01.分布式调度第一部分是自己开发一套分布式调度。这套调度主要是基于一个通用的调度平台。它不仅可以调度统计任务,还可以调度所有离线计算任务和离线统计任务。接下来,所有的统计任务都会迁移到这个通用的分布式调度平台上进行统一的任务调度,取代目前单点的简单版调度中心。未来我们还会支持资源隔离和资源调度。02.数据可视化第二块是数据可视化。上一节我们刚刚看到,业务方所有的数据后台都需要反复访问我们统一的通用API,这是很多重复性的工作。另一个痛点是它确实涉及到一些比较大的应用程序。比如美拍的整体统计报表很多,后台可能有几百条这样的数据。如果一个数据需求者想看到自己的数据,那么他们会从上百个数据指标中定位。自己的数据指标很难。数据可视化平台就是为了解决这样的问题。我不需要所有业务方都访问这个通用API。在同一平台上,您可以选择所需的数据源或您自己的可视化报告,然后呈现您自己的个性化数据指标,不需要把我们的API和所有应用的数据后台打通。然后做一些图形演示。所以数据可视化主要是做统计,提供定制化、个性化的数据报表,有点类似于网易的bdp或者阿里的dataV等平台。另外两个是我们计划在接下来的一段时间内做的事情:第一,数据分析师经常抱怨这个数据有没有更快的查询方式,所以考虑构建一个OLAP服务,比如基于kylin。二是实时统计。刚才我说的不是定期的统计需求,就是临时的统计需求,不是实时的。所以本片考虑到后面的平台也可以满足实时统计的需求,可以更快速的满足实时统计的需求。
