赞
踩
目录
随着大数据技术的飞速发展,企业对于数据处理的效率和实时性的要求也越来越高。Hadoop作为大数据领域的领军技术,长久以来一直承载着海量数据的存储和处理任务。然而,传统的Hadoop数据模型在处理更新和删除操作时的局限性,使得它难以满足实时数据湖等复杂场景的需求。
正是在这样的背景下,Hudi应运而生。Hudi,即Hadoop Upserts Deletes and Incrementals,是一个开源的数据存储层,它旨在解决Hadoop在处理更新和删除操作时的不足,使得大规模分析数据集的实时更新和增量处理成为可能。
本文旨在详细介绍如何搭建和部署Hudi,帮助读者了解并掌握这一强大的数据存储工具。我们将从环境准备、软件安装、配置调整、数据加载到性能优化等各个方面进行阐述,确保读者能够按照步骤顺利地搭建起自己的Hudi环境。
通过本文的学习,读者将能够了解到Hudi的基本原理和架构,掌握其安装和配置方法,并能够利用Hudi实现数据的实时更新和增量处理。无论是数据工程师、数据科学家还是大数据爱好者,都可以通过本文获得Hudi搭建和部署的实用知识和经验。
让我们一同走进Hudi的世界,探索它如何为实时数据湖的建设提供强大的技术支持,并为企业带来更高效、更灵活的数据处理能力。
Hudi(Hadoop Upserts Deletes and Incrementals)是一个开源的数据存储层,旨在优化Hadoop和HDFS上大规模分析数据集的更新、删除和增量处理。Hudi特别关注实时数据湖用例,使得数据工程师和数据科学家能够轻松地管理、查询和分析实时或几乎实时更新的数据集。
支持增量更新和删除:传统上,Hadoop和HDFS是为批量处理而设计的,不支持对数据的更新或删除。然而,随着实时数据处理的需求增长,这种限制变得越来越明显。Hudi通过引入新的数据模型解决了这个问题,允许用户在不重写整个数据集的情况下,对特定记录进行更新或删除。
高效的数据摄取:Hudi提供了多种数据摄取方法,包括批量加载、流式摄取和实时摄取。这使得Hudi能够灵活适应不同的数据处理需求,无论是定期批量加载数据还是持续不断地从数据源摄取数据。
与Hadoop生态系统集成:Hudi与Hadoop生态系统中的其他组件(如Hive、Spark、Flink等)紧密集成,使得用户能够利用这些工具进行数据分析、查询和转换。
优化查询性能:Hudi使用列式存储格式,并结合索引和分区策略,优化了查询性能。这有助于加速数据分析任务,特别是在处理大规模数据集时。
版本控制和回滚:Hudi支持数据的版本控制,这意味着用户可以跟踪数据的更改历史,并在必要时回滚到之前的版本。
简化数据管理:通过使用Hudi,用户可以更容易地管理数据湖中的数据,包括处理数据的生命周期、保留策略和归档等。
1)近实时写入
减少碎片化工具的使用。
CDC 增量导入 RDBMS 数据。
限制小文件的大小和数量。
2)近实时分析
相对于秒级存储(Druid, OpenTSDB),节省资源。
提供分钟级别时效性,支撑更高效的查询。
Hudi作为lib,非常轻量。
3)增量 pipeline
区分arrivetime和event time处理延迟数据。
更短的调度interval减少端到端延迟(小时 -> 分钟) => Incremental Processing。
4)增量导出
替代部分Kafka的场景,数据导出到在线服务存储 e.g. ES。
准备下图的安装包:
具体准备要求:
1)确保安装了JAVA开发工具包(JDK),因为Hudi是基于Java开发的,因此JDK是必需的。确保安装了与Hudi兼容的JDK版本,并配置好环境变量,以便在命令行中能够直接使用。
2)由于Hudi依赖于Apache Hadoop和Apache Spark,因此在安装Hudi之前,需要先安装和配置这两个组件。
3)需要安装并配置 Apache Maven:
Maven是一个项目管理工具,用于自动化构建Java项目,并管理项目的依赖关系。安装Maven后,需要设置其环境变量,并确保可以在命令行中调用Maven命令。
部署maven的原因:
在搭建和部署Hudi的过程中,之所以需要搭建Maven环境,主要是因为Hudi项目本身是基于Java开发的,并且采用了Maven作为项目管理工具。Maven在Java项目开发中扮演了重要的角色,它提供了项目构建、依赖管理等功能,能够大大简化项目的开发和维护过程。
具体来说,Maven通过定义项目对象模型(POM),帮助开发者管理项目的构建过程、依赖关系、生命周期等。对于Hudi项目而言,Maven可以自动处理其所需的Java依赖库,包括其他Java项目或库,确保项目在编译、测试和运行时能够正确引用这些依赖。
此外,Maven还提供了丰富的插件生态系统,这些插件可以扩展Maven的功能,实现诸如代码编译、打包、发布等操作。在Hudi的搭建和部署过程中,这些插件可以帮助我们自动化地完成一些繁琐的任务,提高开发效率。
因此,为了顺利搭建和部署Hudi,我们需要先搭建Maven环境,以便利用Maven的强大功能来管理Hudi项目的构建和依赖关系。这样,我们可以确保Hudi项目在开发和运行过程中能够正确、高效地运行,为后续的数据处理和分析工作提供有力的支持。
4)需要下载Hudi的发布版本
生产生活中 因为数据量比较大,是以TB、PB级别的数据量,所以建议部署在yarn上
①解压缩安装包到/opt/module目录下
tar -zxvf /opt/software/apache-maven-3.6.3-bin.tar.gz -C /opt/module/
②配置maven的环境变量
vim /etc/profile.d/bigdata_env.sh
添加:
- #MAVEN_HOME
- export MAVEN_HOME=/opt/module/apache-maven-3.6.3
- export PATH=$PATH:$MAVEN_HOME/bin
退出保存,刷新环境,使其生效:
source /etc/profile
③验证是否成功
mvn -v
④修改apache-maven-3.6.1/conf目录下的settings.xml文件
(1)添加maven本地仓库路径
跳转到大概55行左右,添加内容:
<localRepository>/opt/software/RepMaven</localRepository>
(2)修改阿里云镜像
跳转到大概160行左右,添加内容:
- <mirror>
- <id>nexus-aliyun</id>
- <mirrorOf>central</mirrorOf>
- <name>Nexus aliyun</name>
- <url>http://maven.aliyun.com/nexus/content/groups/public</url>
- </mirror>
①解压缩安装包到/opt/module目录下
tar -zxvf /opt/software/hudi-0.11.0.src.tgz -C /opt/module/
②修改hudi-0.11.0文件夹目录下的pom.xml文件
(1)111行和113行左右 修改hadoop与hive版本兼容
(2)1170行左右 新增中央仓库repository加速依赖下载
- <repository>
- <id>nexus-aliyun</id>
- <name>nexus-aliyun</name>
- <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
- <releases>
- <enabled>true</enabled>
- </releases>
- <snapshots>
- <enabled>false</enabled>
- </snapshots>
- </repository>
③ 修改源码兼容hadoop3
vim /opt/module/hudi-0.11.0/hudi-common/src/main/java/org/apache/hudi/common/table/log/block/HoodieParquetDataBlock.java
113左右
④修改hudi-0.11.0/packaging/hudi-spark-bundle/文件夹目录下的pom.xml文件
vim /opt/module/hudi-0.11.0/packaging/hudi-spark-bundle/pom.xml
解决spark模块依赖冲突
(1)380行左右 hive
- <exclusions>
- <exclusion>
- <artifactId>guava</artifactId>
- <groupId>com.google.guava</groupId>
- </exclusion>
- <exclusion>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.pentaho</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- </exclusions>
(2)410行左右 hive-jdbc
- <exclusions>
- <exclusion>
- <groupId>javax.servlet</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- <exclusion>
- <groupId>javax.servlet.jsp</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- </exclusions>
(3)430行左右 hive-metastore
- <exclusions>
- <exclusion>
- <groupId>javax.servlet</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.datanucleus</groupId>
- <artifactId>datanucleus-core</artifactId>
- </exclusion>
- <exclusion>
- <groupId>javax.servlet.jsp</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- <exclusion>
- <artifactId>guava</artifactId>
- <groupId>com.google.guava</groupId>
- </exclusion>
- </exclusions>
(4)455行左右 hive-common
- <exclusions>
- <exclusion>
- <groupId>org.eclipse.jetty.orbit</groupId>
- <artifactId>javax.servlet</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- </exclusions>
(5) 在最后手动增加jetty (hive最下边,zookeeper上边)
排除低版本jetty,添加hudi指定版本的jetty
- <!-- 增加hudi配置版本的jetty -->
- <dependency>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-server</artifactId>
- <version>${jetty.version}</version>
- </dependency>
- <dependency>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-util</artifactId>
- <version>${jetty.version}</version>
- </dependency>
- <dependency>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-webapp</artifactId>
- <version>${jetty.version}</version>
- </dependency>
- <dependency>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-http</artifactId>
- <version>${jetty.version}</version>
- </dependency>
⑤修改hudi-0.11.0/packaging/hudi-utilities-bundle/文件夹目录下的pom.xml文件
vim /opt/module/hudi-0.11.0/packaging/hudi-utilities-bundle/pom.xml
(1)350行左右
- <exclusions>
- <exclusion>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- </exclusions>
(2)361行左右
- <exclusions>
- <exclusion>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- </exclusions>
(3)423行左右 hive-service
- <exclusions>
- <exclusion>
- <artifactId>servlet-api</artifactId>
- <groupId>javax.servlet</groupId>
- </exclusion>
- <exclusion>
- <artifactId>guava</artifactId>
- <groupId>com.google.guava</groupId>
- </exclusion>
- <exclusion>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.pentaho</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- </exclusions>
(4)455行左右 hive-jdbc
- <exclusions>
- <exclusion>
- <groupId>javax.servlet</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- <exclusion>
- <groupId>javax.servlet.jsp</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- </exclusions>
(5)476行左右 hive-metastore
- <exclusions>
- <exclusion>
- <groupId>javax.servlet</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.datanucleus</groupId>
- <artifactId>datanucleus-core</artifactId>
- </exclusion>
- <exclusion>
- <groupId>javax.servlet.jsp</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- <exclusion>
- <artifactId>guava</artifactId>
- <groupId>com.google.guava</groupId>
- </exclusion>
- </exclusions>
(6)501行左右 hive-common
- <exclusions>
- <exclusion>
- <groupId>org.eclipse.jetty.orbit</groupId>
- <artifactId>javax.servlet</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- </exclusions>
(7)520行 最后增加hudi配置版本的jetty
- <!-- 增加hudi配置版本的jetty -->
- <dependency>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-server</artifactId>
- <version>${jetty.version}</version>
- </dependency>
- <dependency>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-util</artifactId>
- <version>${jetty.version}</version>
- </dependency>
- <dependency>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-webapp</artifactId>
- <version>${jetty.version}</version>
- </dependency>
- <dependency>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-http</artifactId>
- <version>${jetty.version}</version>
- </dependency>
mvn clean package -DskipTests -Dspark3.0 -Dscala-2.12 -Dhadoop.version=3.1.3 -Pflink-bundle-shade-hive3
参数解析:
mvn
: 这是Maven命令行工具的调用,Maven是一个用于自动化构建Java项目的工具。
clean
: 这个目标(goal)用于清理项目构建的输出目录,通常包括target/
目录,确保从干净的状态开始构建。
package
: 这个目标用于编译项目源代码,执行测试(如果未使用-DskipTests
参数),并打包项目为一个可发布的格式,比如JAR、WAR或EAR文件。
-DskipTests
: 这个参数告诉Maven在构建过程中跳过单元测试。这对于只想构建项目而不运行测试的场景很有用,可以节省构建时间。
-Dspark3.0
: 这个参数可能是一个自定义属性,用于指定项目应该使用Apache Spark 3.0版本的相关依赖。这通常用于项目的pom.xml文件中,通过Maven属性来控制依赖的版本。
-Dscala-2.12
: 类似地,这个参数可能用于指定项目应该使用Scala 2.12版本的相关依赖。
-Dhadoop.version=3.1.3
: 这个参数用于指定Hadoop的版本为3.1.3。Maven将使用这个版本来解析Hadoop相关的依赖。
-Pflink-bundle-shade-hive3
: 这个参数用于激活一个或多个Maven profile。在这里,它激活了名为flink-bundle-shade-hive3
的profile。Profiles是Maven中用于定义不同构建逻辑的一种方式,可以根据不同的环境或需求激活不同的profile。(这个profile与Apache Flink的捆绑、shade(重命名依赖以避免冲突)和Hive 3相关。)
接下来就是等待编译,过程很漫长
………………
………………………………
………………………………………………
………………………………………………………………
………………………………………………………………………………
………………………………………………………………………………………………
………………………………………………………………………………………………………………
就这样等啊等,你等了20分钟左右,出现了下面的画面,就证明你成功了
成功编译之后,进入Hudi自带的客户端
hudi-cli/hudi-cli.sh
- import org.apache.hudi.QuickstartUtils._
- import scala.collection.JavaConversions._
- import org.apache.spark.sql.SaveMode._
- import org.apache.hudi.DataSourceReadOptions._
- import org.apache.hudi.DataSourceWriteOptions._
- import org.apache.hudi.config.HoodieWriteConfig._
- import org.apache.hudi.common.model.HoodieRecord
-
- val tableName = "hudi_trips_cow"
- val basePath = "file:///tmp/hudi_trips_cow"
- val dataGen = new DataGenerator
-
- val inserts = convertToStringList(dataGen.generateInserts(10))
- val df = spark.read.json(spark.sparkContext.parallelize(inserts, 2))
- df.write.format("hudi").
- options(getQuickstartWriteConfigs).
- option(PRECOMBINE_FIELD_OPT_KEY, "ts").
- option(RECORDKEY_FIELD_OPT_KEY, "uuid").
- option(PARTITIONPATH_FIELD_OPT_KEY, "partitionpath").
- option(TABLE_NAME, tableName).
- mode(Overwrite).
- save(basePath)
-
- val tripsSnapshotDF = spark.read.format("hudi").load(basePath + "/*/*/*/*")
- tripsSnapshotDF.createOrReplaceTempView("hudi_trips_snapshot")
- spark.sql("select fare, begin_lon, begin_lat, ts from hudi_trips_snapshot where fare > 20.0").show()
cp hudi-spark3.1-bundle_2.12-0.12.0.jar /opt/module/spark-3.0.3-yarn/jars
spark-shell --conf "spark.serializer=org.apache.spark.serializer.KryoSerializer" --conf "spark.HoodieRecord=org.apache.hudi.common.model.HoodieRecord"
直接复制案例进入spark-shell里面,会得到
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。