前段时间给大家分享了阿里的数仓建设
《阿里数据仓库研发规范》,本文主要讲解下创业型公司是如何建设数仓的。本文将重点探讨数据处理层中数据仓库的建设,有提到早期的数据服务中存在不少问题,虽然在做运营Dashboard系统时,对后台数据服务进行了梳理,构建了数据处理的底层公共库等,但是仍然存在一些问题:
于是,我们考虑建设一个适于分析的数据存储系统,该系统的工作应该包含两部分:第一,根据需求抽象出数据模型;第二,按照数据模型的定义,从各个数据源抽取数据,进行清洗、处理后存储下来。虽然数据仓库的学术定义有很多版本,而且我们的系统也没有涉及到多部门的数据整合,但是符合上述两个特点的,应该可以归结到数据仓库的范畴了,所以请允许笔者将本文命名为“数据仓库的建设”。 下图所示,为现阶段我们的数据仓库建设方案。数据主要来源于MySQL和MongoDB中的业务数据、Elasticsearch中的用户行为数据与日志数据;ETL过程通过编写Python脚本来完成,由Airflow负责任务流的管理;建立适于分析的多维数据模型,将形成的数据存入MySQL中,供数据应用层使用。可以看到,数据仓库本身既不生产数据也不消费数据,只是作为一个中间平台集中存储数据,整个系统实现的重点在于数据建模与ETL过程,这也是日常维护中的重点。
将数据落地到哪里是首先要考虑的问题,笔者考虑的因素主要有这么几点:一是数据量大小和增长速度,二是要能实现SQL或者类SQL操作,有多表联合、聚合分析功能,三是团队技术栈。可选的技术方案有MySQL、Oracle和Hive,最终选择了基于MYISAM存储引擎的MySQL,部分原因如下:
根据数据分析的需求抽象出合适的数据模型,是数据仓库建设的一个重要环节。所谓数据模型,就是抽象出来的一组实体以及实体之间的关系,而数据建模,便是为了表达实际的业务特性与关系所进行的抽象。数据建模是一个很宽泛的话题,有很多方法论值得研究,具体到业务上不同行业又会有不同的建模手法。这里主要结合我们的实践来简单地谈一些认识和方法。 目前业界有很多数据建模的方法,比如范式建模法、维度建模法等等。遵循三范式,我们在做业务数据库设计时经常会用到,这种方法对业务功能进行抽象,方便功能扩展,但是会额外增加分析的复杂度,因此笔者更倾向于维度建模法。维度建模法,是Kimball 最先提出的概念,将数据抽象为事实表与维度表两种,而根据二者之间的关系将整体的模型划分为星型模型与雪花模型两种。这种建模方法的优势在于,根据各个维度对数据进行了预处理,比如按照时间维度进行预先的统计、分类等等,可以提高数据分析应用时的效率,是适于分析的一种方法。具体来看看几个概念:
举个例子,业务场景是:一款做连锁企业招聘工作的产品,比如为麦当劳的所有连锁门店招聘员工,现在要分析“每家门店的招聘情况如何?”。结合具体业务,我们引入六个维度:时间维度、地区维度、品牌维度、门店维度、职位维度、申请渠道;数据指标上,主要有申请工作人数、申请工作次数、聘用人数、拒绝人数,每个指标分别有增量值和总量值两种;数据粒度上,时间维度细分到以小时为单位,地区维度细分到市一级。下图所示便是相应的星型模型,有三点值得一提:
ETL这块,由于前期我们做了不少工作来构建底层数据分析公共库,能有效的帮助我们进行数据抽取与处理,因此,现阶段还没有引入诸如Kettle这样的开源工具,主要采用编写Python脚本来实现。这里主要谈谈增量更新机制与任务流管理两个问题的策略。
增量更新的背景是这样的:第一,上面有提到,对于可变的维度表,我们添加了prod_xxxx_id字段来唯一标识,实现信息覆盖更新。对于事实表,为了反映历史状态,表中的数据通常是不可逆的,只有插入操作,没有删除或者修改操作,表示在过去一段时间内完成的事实业务数据,更新的方法就是插入新的数据。第二,ETL通常是近实时的,需要依赖schedule触发更新,因此每次需要更新的信息就是上一次更新时间与当前时间之间的变化数据。笔者采用的策略是:
于是,我们开始考虑引入一个任务流管理系统,基本想法是:第一,要能解决上述的问题;第二,最好能与Python友好的兼容,毕竟团队的主要技术栈是Python。经过调研,发现Airflow是当前最适合我们的。Airflow是Airbnb公司开源的一款工作流管理系统,基于Python编写,兼容crontab的schedule设置方法,可以很简单的描述任务之间的逻辑与依赖,并且提供了可视化的WebUI用于任务管理与查看,任务失败时可以设置重试与邮件通知。这里贴一张官方的截图来一睹其风采。
Airflow有三个重要的概念:DAG、Task和Operator。DAG(directed acyclic graphs),有向无环图,用来表示任务的依赖结构;Task表示一个具体的任务节点;Operator表示某个Task的执行体是什么,比如BashOperator是执行一个Bash脚本,PythonOperator是执行一段python代码等等。使用Airflow,首先要编写对应的任务脚本,通常脚本需要做三件事:第一,描述DAG的属性(比如schedule、重试策略等),第二,描述Task属性(比如Operator是什么),第三,描述Task的依赖情况。进一步的认识可以参考官方文档。
以上便是现阶段我们的数据仓库发展与建设方法,虽然比较简单,但是目前基本能满足需求。随着数据规模的增长和业务的复杂化,未来还有很多路要走:如何合理的建模?如何有效的利用数据?如何提高数据分析效率?期待更多的挑战!