0x00 前言
数据仓库体系里面的主要内容也写的差不多了,现在补一点之前遗漏的点。这一篇就来聊一下 ETL。
文章结构
- 先聊一下什么是 ETL。 聊一下大致的概念和一般意义上的理解。
- 聊一聊数据流是什么样子。因为 ETL 的工作主要会体现在一条条的数据处理流上,因此这里做一个说明。
- 举个具体的例子来说明。
0x01 什么是 ETL
ETL,是英文 Extract-Transform-Load 的缩写,用来描述将数据从来源端经过抽取(extract)、转换(transform)、加载(load)至目的端的过程。
嗯,怎么理解 ETL 这个东西呢?直接上一个网上搜到的招聘信息看一下:
职位名称: ETL工程师
职位职责:
- 负责ETL系统研发和对外支持工作;
- 设计科学的数据抽取、转换、加载的工作流程,保证数据及时、正确地抽取到数仓中;
- 负责安排ETL工程流程的调度和成功执行;
- 协调数据建模建立风控模型、对数据进行挖掘、优化及统计。
职位要求:
- 熟练掌握数仓方法论,理解维度建模;
- 熟悉hadoop,hive,hbase,spark,flume等工作原理;熟悉kettle,informatica,sqoop等工作;
- 精通hive语法,熟练SQL优化,熟悉python/shell等一种脚本语言;掌握mysql,oracle,sqlserver等数据库;
- 有互联网大数据平台数据开发经验优先。
看上面的要求,有几个点可以关注一下:
- 数仓的理论
- 计算引擎:Hadoop、Spark、Hive
- 数据同步:Flume、Sqoop、Kettle
- 存储引擎:Mysql、Oracle、Hbase等存储平台
我们大致分析一下这些内容。首先说数仓的理论,这个在前面的博客也都有提到,很重要,从理论上指导了怎么来进行数据处理。存储引擎也就不提了。这两者不太算是 ETL 的范畴。
那就聊一下计算引擎和数据同步的工具。我们可以大致理解 ETL 的主要工作就是利用这些工具来对数据进行处理。下面举几个栗子来说明 ETL 的场景:
- Nginx 的日志可以通过 Flume 抽取到 HDFS 上。
- Mysql 的数据可以通过 Sqoop 抽取到 Hive 中,同样 Hive 的数据也可以通过 Sqoop 抽取到 Mysql 中。
- HDFS 上的一些数据不规整,有很多垃圾信息,可以用 Hadoop 或者 Spark 进行处理并重新存入 HDFS 中。
- Hive 的表也可以通过 Hive 再做一些计算生成新的 Hive 表。
这些都算是 ETL,其中 1 和 2 都比较典型,它们把数据从一个存储引擎转移到另一个存储引擎,在转移的过程中做了一定的转换操作。 3 和 4 也同样是 ETL 只是它们更侧重的是数据的加工。
到了这一步,我们不再纠结于具体的 ETL 概念是什么,仅从自己的直观理解上来定义 ETL,不管严谨不严谨,反正这些活 ETL 工程师基本都要干。
ETL 是对数据的加工过程,它包括了数据抽取、数据清洗、数据入库等一系列操作,大部分和数据处理清洗相关的操作都可以算是 ETL。
0x02 数据流长什么样子
举个栗子
举个简单的栗子,下面是一个种数据流的设计,蓝色的框框代表的是数据来源,红色的框框主要是数据计算平台,绿色的 HDFS 是我们一种主要的数据存储,Hive、Hbase、ES这些就不再列出来了。
数据流的分类
我们常说的数据流主要分两种:
- 离线数据
- 实时数据
其中离线数据一般都是 T+1 的模式,即每天的凌晨开始处理前一天的数据,有时候可能也是小时级的,技术方案的话可以用 Sqoop、Flume、MR 这些。实时数据一般就是指实时接入的数据,一般是分钟级别以下的数据,常用的技术方案有 Spark Streaming 和 Flink。
现在的大部分数据流的设计都会有离线和实时相结合的方案,即 Lambda 架构,感兴趣的同学可以了解一下。
0x03 举个栗子
前段时间和一个哥们再聊数据流的设计,正好这里大概描述一下场景和解决方案。
一、场景
- 数据源主要为 Mysql,希望实时同步 Mysql 数据到大数据集群中(肯定是越快越好)。
- 目前每日 20 亿数据,可遇见的一段时间后的规模是 100 亿每日以上。
- 能快速地查到最新的数据,这里包含两部分含义:从 Mysql 到大数据集群的速度快、从大数据集群中查询的速度要快。
二、方案选型
遇到这个场景的时候,根据经验我们主要考虑下面两个点:数据抽取引擎和存储引擎。
数据抽取引擎
这里我们主要考虑两种方案:
- Sqoop 定时抽取 Mysql 数据到 HDFS 中,可以每天全量抽取一份,也可以隔段时间就抽取一份变更的数据。
- Canal 监听 Mysql 的 binlog 日志,相当于是 Mysql 有一条数据久变动,我们就抽取一条数据过来。
优缺点的对比也很明显:
- Sqoop 相对比较通用一些,不管是 Mysql 还是 PostgreSql都可以用,而且很成熟。但是实时性较差,每次相当于是启动一个 MR 的任务。
- Canal 速度很快,但是只能监听 Mysql 的日志。
存储引擎
存储引擎主要考虑 HDFS、Hbase 和 ES。
一般情况下,HDFS 我们尽量都会保存一份。主要纠结的就是 Hbase 和 ES。本来最初是想用 Hbase 来作为实时查询的,但是由于考虑到会有实时检索的需求,就暂定为ES
三、方案设计
最终,我们使用了下面的方案。
- 使用 Canal 来实时监听 Mysql 的数据变动
- 使用 Kafka 作为消息中间件,主要是为了屏蔽数据源的各种变动。比如以后即使用 Flume 了,我们架构也不用大变
- 数据落地,有一份都会落地 HDFS,这里使用 Spark Streaming,算是准实时落地,而且方便加入处理逻辑。在 落地 ES 的时候可以使用 Spark Streaming,也可以使用 Logstach,这个影响不大
四、一些问题
有两个小问题列一下。
- 小文件,分钟级别的文件落地,肯定会有小文件的问题,这里要考虑的是,小文件的处理尽量不要和数据接入流程耦合太重,可以考虑每天、每周、甚至每月合并一次小文件。
- 数据流的逻辑复杂度问题,比如从 Kafka 落地 HDFS 会有一个取舍的考虑,比如说,我可以在一个 SS 程序中就分别落地 HDFS 和 ES,但是这样的话两条流就会有大的耦合,如果 ES 集群卡住,HDFS 的落地也会受到影响。但是如果两个隔开的话,就会重复消费同一份数据两次,会有一定网络和计算资源的浪费。
0xFF 总结
仔细想了一下,数据流应该是我做的最多的一块了,但是总结的时候感觉又有很多东西说不清楚,先大致写一点吧。
前段时间太忙,周末也休息不足,赶快补一篇出来。