title: 数据湖基础知识以及Mac安装Iceberg教程
date: 2021-10-20 19:47:14
tags:
计算机科学领域的任何问题都可以通过增加一个间接地中间层来解决
关于数据湖为什么会出现我觉得有一句话概括的非常好,
大数据领域发展至今已经经历了相当长时间的发展和探索,虽然大数据技术的出现和迭代降低了用户处理海量数据的门槛,但是有一个问题不能忽视,数据格式对不同引擎适配的对接
这句话是什么意思呢?我们在使用不同的引擎进行计算时,需要将数据根据引擎进行适配。这是相当棘手的问题,比如说我用Spark进行计算,但是底层的文件可能是TXT存储的,可能是Hive ORC存储的,或者是经过HDFS的一些压缩算法处理的数据,那么我Spark就需要支持读取TXT文件,读取ORC文件,读取snappy文件 and so on.为了将计算引擎和数据剥离开来,结合的不那么紧密,大牛们出现了一种新的解决方案:
介于上层计算引擎和底层存储格式之间的一个中间层。
这个中间层不是数据存储的方式,只是定义了数据的元数据组织方式,并且向引擎层面提供统一的类似传统数据库
中"表"的语义。它的底层仍然是Parquet、ORC等存储格式。重新应证了那句话。
计算机科学领域的任何问题都可以通过增加一个间接的中间层来解决。
基于此,Netflix开发了Iceberg数据湖(更主要的是基于Hive的数据湖方案不能满足需求),目前已经是Apache的顶级项目,除此之外还有Hudi,delta数据湖方案。
我们可以看到数据湖是一个在计算平台和存储平台中间的一个类似中间件的东西,用于解决多种数据源,多种计算引擎
之间的连接关系,数据湖中的数据可以包括来自于关系型数据库中的结构化数据(行和列)、半结构化数据(如CSV、日
志、XML、JSON)、非结构化数据(如email、文档、PDF等)和二进制数据(如图像、音频、视频)。除此之外引申出
来的还有关于元数据的管理,源数据的多种Schema种类样式都要满足。概括一下成熟的数据湖应该满足以下需求:
(1)需要支持比较丰富的数据 Schema 的组织;
(2)它在注入的过程中要支撑实时的数据查询,所以需要 ACID 的保证,确保不会读到一些还没写完的中间状态的脏数据;
(3)例如日志这些有可能临时需要改个格式,或者加一列。类似这种情况,需要避免像传统的数仓一样,可能要把所有的数据重新提出来写一遍,重新注入到存储;而是需要一个轻量级的解决方案来达成需求。
在继续了解数据湖之前我们先来了解一下相关大数据架构,主要分为两种架构,分别是lambda & kappa,我们先来
说lambda架构。lambda是一种比较传统的大数据架构,广泛应用于现在的大数据数仓平台中,其中主要的特点就是流批
分离,比如我们批处理数据会在每天夜间12点运行一次,计算昨天一天的数据然后覆盖到druid或者clickhouse中,保证数
据的准确性,但是对于今天的实时数据查询来说我们就只能通过实时程序来计算好之后存到druid或者clickhouse中,因为
离线层采用分布式存储系统,这样哪怕程序崩溃也不大可能会损伤到数据。
Lambda架构优缺点如下:
优点:
(1)离线层采用分布式存储管理历史信息,即使系统崩溃也不太可能损伤到数据
(2)有效平衡了速度与可靠性
(3)容灾而兼具弹性的数据处理架构
缺点:
(1)Lambad架构维护成本很高。很显然,这种架构下数据存在两份、schema不统一、 数据处理逻辑不统一,整个数仓系统维护成本很高
(2)Lambda中的实时数仓中一般使用kafka当做中间件,但是kafka不支持OLAP操作,大多数业务希望可以在DWD、DWS层进行即席查询,kafka无法满足
(3)Lambda实时数仓kafka仅支持append不支持update/delete
Kappa 架构不能被简单视作 Lambda 架构的替代品,相反,它是在离线层对满足业务需求不是必须实时的一个备选
项。该架构适合实时处理不同事件,下图展示了其整体结构
其中中间的消息件一般采用kafka,因为其多分区,顺序append data,可水平拓展的特性迎合了关键需求。一般实时架构
选用的是Flink+Kafka架构,如果数据量极大的情况,一般kafka的过期时间设置的都比较短,比如一天甚至几小时,但是
如果数据出现峰值情况,导致数据积压验证的话,可能导致kafka中数据不能被及时消费出来在Kafka中过期导致数据丢
失。
Kappa架构优缺点:
优点:
(1)无需离线层
(2)只有当代码变更时才需要重新处理
(3)可以使用固定内存进行部署
(4)可用于具备水平扩展性的系统
(5)机器学习是实时的,所以所需资源更少
缺点:
(1)缺少离线层可能导致数据处理或数据库更新时发生错误,所以往往需要异常管理器来调解矛盾,恢复数据。
(2)数据链路更加复杂,如果我们需要对DWD层的实时数仓数据进行数据分析的时候就需要将DWD层的Kafka中的数据
写入到ClickHouse或者hive中,增加了链路复杂性
(3)Kappa架构是严重依赖于消息队列的,消息队列本身的准确性严格依赖它上游数据的顺序,但是,消息队列越多,
发生乱序的可能性越大。
上面分别讲述了两种架构的优缺点,这时候有人就提出了,有没有一种技术能够保证数据高效回溯能力,架构稳定,支持
数据更新,支持数据的流批读写,做到分钟级别的数据接入。
于是乎,各大厂商针对上面的需求,分别推出了自己的数据湖方案,现在基本呈现三足鼎立的局势,Delta,Hudi,以及Iceberg。
上面我们了解了关于一个数据湖应该具有的特性以及lambda架构和Kappa架构,下面我们来看看Netflix发起的数据湖项
目Iceberg,Iceberg的表数据架构图:
有几点需要注意一下:
(1)新快照不会覆盖旧快照,旧的快照中依然保存了早期数据的Manifest File,新旧快照共同组成了表的快照Metadata
的一部分。
(2)数据文件datafile支持多种格式如parque,orc,avro等格式。
(3)有了快照,读数据的时候只能读到快照所能引用到的数据,还在写的数据不会被快照引用到,也就不会读到脏数
据。多个快照会共享以前的数据文件,通过共享这些 Manifest File 来共享之前的数据。
(4)Manifest List再往上是快照元数据(快照Metadata),记录了当前或者历史上表格 Scheme 的变化、分区的配置、
所有快照 Manifest File 路径、以及当前快照是哪一个。同时,Iceberg 提供命名空间以及表格的抽象,做完整的数据组织
管理。
有了Iceberg这种神器之后,新一代的数仓基于Flink以及Iceberg的设计横空出世
这样无论是流处理还是批处理,我们的存储都是进入到了Iceberg数据湖中,不用再分开做流批处理的两套代码,以及不用
大量依靠kafka这种消息中间件,下面我们总结一下这个新架构的优点。
(1)解决Kafka存储数据量有限的问题,kafka使用成本较高,数据湖所有数据都是基于HDFS实现的文件管理系统,数据
量可以巨大基本不用担心
(2)DWD层,ODS层依然支持OLAP查询,原先的实时数仓如果想查询这两层的数据需要通过Flink将数据导入到OLAP查
询平台(ClickHouse、Druid、Hive)
(3)批流存储都是基于Iceberg以及HDFS之后,就可以完全复用一套数据质量管理体系,数据血缘关系同样也只做一套
即可
(4)依靠数据湖架构设计的实时数仓可以看做是一种Kappa架构的升级,kappa的优点在数据湖数仓中依然存在,
schema统一,数据处理逻辑统一,开发人员不用再维护两套代码。
上面基于Iceberg构建的架构看起来就像是把Lambda架构中的Kafka和HDFS结合到了一起,并且我们知道Iceberg也是可
以基于HDFS上存储的,那么他究竟是在HDFS上做了哪些操作让其可以作为实时数仓的存储了呢?
(1)支持流式写入-增量拉取,目前主要基于Flink即可实现流式写入,但是这里有个问题,因为频繁的写文件导致小文件
可能会增多,数据湖需要在这方面做出处理,还有就是实时处理程序需要知道哪些文件是新增的哪些是旧的,每次只需要
处理新增的文件即可,这个也是离线数仓做不到实时的关键原因之一,离线数仓的做法就是处理完一整批数据之和给下游
说我这批数据处理完了,你可以使用了。那Iceberg如何实现读写增量拉取的呢?这个需要我们上面提到的表数据组织架
构。
其中的s0表示第一次产生的快照,s1表示第二次产生的快照,同样新快照是包含了旧快照中的数据的,根据快照中的
manifest文件Iceberg可以确定哪些文件是旧文件,哪些是新文件,有快照了我们就可以根据快照中的内容判断文件是新增
的还是原先就存在的。
(2)解决小文件过多的问题,目前iceberg的spark代码中有原生的合并小文件代码,flink的合并代码社区还在积极开发
中,详细可以看一下issue
Versions:
Hive 3.1.2 (hive --version)
Hadoop 3.3.1 (hadoop version)
Flink Version: 1.11.1 (flink --version)
注意事项
(1)上面的版本是我自己本机的安装,可能其他版本也可以,但是Flink最好是选用1.11版本的,因为Iceberg官网有这
样一句话
Apache Iceberg supports both [Apache Flink](https://flink.apache.org/)‘s DataStream API and Table API to write records into an Iceberg table. Currently, we only integrate Iceberg with Apache Flink 1.11.x.
(2)Mac使用brew安装指定版本的flink需要将flink项目clone到本地然后找到flink的提交记录,然后安装指定版本对应的
commit id,详细参考这里!,但是需要说明的是,我这样安装同样是报错的,所以最终采用了下载版本的对应压缩包直接
解压在本地目录使用.
(3)环境变量必须要配置,我当时没有配置是运行失败了的,配上肯定是保险的,因为Mac程序员一般会用homebrew安
装软件,会发现不用像原先Linux,或者windows需要配置环境变量才能使用
Mac使用Homebrew安装软件的时候,软件包的二进制文件会被创建软连接然后放到/usr/local/bin中,而Mac开机时,会自动读取该文件,使用某个命令时会根据链接文件找到命令的实际位置并执行。
需要配置的环境变量如下所示:
#注意:需要将地址换成你自己的安装地址
#添加完成之后记得进行 source 操作,让修改马上生效
export HADOOP_HOME=/usr/local/Cellar/hadoop/3.3.1/libexec
export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_291.jdk/Contents/Home
#需要注意的是hadoop classpath会自动将相关包的路径打出来,不用一个个手动敲
export HADOOP_CLASSPATH=hadoop classpath
export PATH=$HADOOP_CLASSPATH:$HADOOP_HOME:$JAVA_HOME/bin:$PATH
(4)我们后面创建HiveCatlog创建修改Hive表数据则需要连接Hive的元数据,那么就意味着需要启动Hive metastore服
务,我们平常对Hive metastore元数据服务没有什么感觉,下面有一段关于Hive Metastore的简短介绍,更详细信息可以
参考!知乎回答 & !cloudera官网介绍
Hive Metastore是Hive用来管理库表元数据的一个服务,有了它上层的服务不用再跟裸的文件数据打交道,而是可以基于结构化的库表信息构建计算框架。现在除了Hive之外很多计算框架都支持以Hive Metastore为元数据中心来查询底层Hadoop生态的数据,比如Drill, Presto, Spark等等。
我们在Mac上启动Hive Metastore服务命令
hive --service metastore
了解了上面的注意事项之后我们开始下载Iceberg的jar包,下载地址
下载好之后我们将Iceberg的Jar包(iceberg-flink-runtime-0.11.1.jar)和用来连接hive的jar包(flink-sql-connector-hive-
3.1.2_2.11-1.11.0.jar)放到flink目录中的lib目录
#进入flink-sql,进入前记得打开Hive元数据服务
./sql-client.sh embedded \\n
-j /Users/liu/Documents/flink-1.11.1/lib/iceberg-flink-runtime-0.11.1.jar \\n
-j /Users/liu/Documents/flink-1.11.1/lib/flink-sql-connector-hive-3.1.2_2.11-1.11.0.jar \\n shell
创建Hive的Catalog,即可以建立已HDFS为基础的数据湖表
Flink SQL> CREATE CATALOG hive_catalog WITH (
> 'type'='iceberg',
> 'catalog-type'='hive',
> 'uri'='thrift://localhost:9083',
> 'clients'='5',
> 'property-version'='1',
> 'warehouse'='hdfs://localhost:9000/user/hive/warehouse'
> );
本文主要记录数据湖的基础知识,以及如何在Mac上安装Iceberg,其中的注意事项是我出现过的问题,如果有什么疑问或者不理解的地方欢迎随时交流。