到目前为止,您已经学会了如何使用标准连接器(如MySQL和Pinot)将Presto连接到数据湖。此外,您还学会了如何使用Presto的Java类和方法编写自定义连接器。最后,您连接了一个客户端到Presto以运行通用或自定义查询。现在是时候在一个高级、更实际的场景中使用Presto,以解决大数据管理的主要挑战:表查找、对数据的并发访问以及访问控制。
在本章中,我们将概述数据湖仓架构,并实现一个实际的场景。本章分为两个部分。在第一部分中,我们介绍数据湖仓的架构,重点关注其主要组件。在本章的第二部分,您将使用Presto和完全开放的组件实现一个实际的数据湖仓场景。
湖仓的出现
数据湖的第一代主要基于Hadoop分布式文件系统(HDFS),展示了大规模分析的潜力。因此,许多组织形成了由数据湖和数据仓库组成的数据平台架构,它们之间通过管道和工作流连接起来。然而,由此产生的平台非常复杂,存在可靠性、数据新鲜度和成本等问题。
为了克服这些问题,组织试图在数据湖和数据仓库方面进行工作负载的扩展,但取得的成功有限。在数据湖方面,虽然诸如Presto之类的系统显著提高了性能,但更复杂的管道和工作流,如多个写入者或执行失败,需要极大的复杂性来处理,或者导致不可靠的结果(例如,损坏或过时的文件)。在数据仓库方面,尝试将更多的数据科学和机器学习(ML)工作负载引入这些系统,例如用于AI和ML的Snowflake以及Amazon Redshift中的ML。然而,即使有了这些进展,机器学习,特别是模型训练,在数据仓库上并不是一种天然的匹配,而且主要的模型开发框架仍然依赖于直接文件访问。
数据湖是在2000年代末引入的。从那时起,我们在云计算、分布式系统和人工智能方面取得了巨大的进展。这些趋势推动了确保数据湖会留存下来的用例。创新者一直在寻找提高数据湖内部数据管理能力的方法。在2010年代中期,一些技术崛起,通过附加元数据和协议来增强数据湖中的文件,引入了数据管理功能,例如ACID事务、高效更新和版本控制。
在2020年和2021年初,Databricks的Michael Armbrust及其同事引入并创造了"湖仓"这一术语,作为数据湖顶部的统一数据管理系统,结合了数据仓库和数据湖的优势,使其既能支持传统的数据仓库工作负载(即SQL),也能支持高级分析(例如数据科学、机器学习和人工智能)。几年后,湖仓成为了一个真正的数据存储、管理和处理系统。
数据湖仓的架构
图5-1显示了一个数据湖仓的架构,由以下主要组件组成:数据湖,包括表格式、文件格式和文件存储;数据科学和机器学习层;SQL查询引擎;元数据管理层;以及数据治理层。数据湖仓摄取从操作性来源提取的数据,如结构化、半结构化和非结构化数据,并将其提供给分析应用,如报告、仪表板、工作空间和应用程序。
由于本书专注于Presto,而Presto是为SQL工作负载设计的,我们将专注于SQL数据湖仓,不包括数据科学和机器学习工作负载的组件。简单地说,我们可以将SQL数据湖仓架构分为四个明确的组件:数据湖;查询引擎;元数据管理层,帮助查询引擎快速访问数据;以及数据治理层,确保数据在可用性、可用性和一致性方面的质量。本章的其余部分将重点介绍每个单独的组件,它们的功能以及它们如何相互交互。
数据湖
正如在第1章中讨论的那样,数据湖是企业存储所有数据的地方。数据湖也是SQL数据湖仓架构的关键组件之一。数据湖包括文件存储、文件格式和表格格式。数据湖必须相对廉价,以存储数据,并允许任何应用程序利用基本的API以字节流的形式读取和写入文件。
文件存储
文件存储表示存储所有数据的服务。文件存储对存储在其中的数据类型是不可知的。相反,它将文件视为字节的集合。通常,这些文件存储可以分为文件系统(如HDFS)或对象存储的类别。Amazon Simple Storage Service (S3)、Google Cloud Storage 和 Azure Blob Storage 是最受欢迎的对象存储。在本章中,我们将使用 MinIO 作为对象存储,因为您可以在本地安装它,而且不像最受欢迎的对象存储那样需要额外的费用。
文件存储处理并存储大量数据。根据部署的情况,单个lakehouse部署的规模可以从几个 terabytes 到 exabytes 不等。鉴于数据的巨大规模,文件存储是经济有效的。
文件格式
除了简单地存储字节块之外,存储在数据湖中的大多数文件都是使用通常针对数据访问进行优化的常见开放格式。Parquet 和 ORC 是最常见的现代 lakehouse 文件格式。它们都是基于列的存储格式,可以更有效地存储具有两个关键特征的数据。
首先,它们在文件内部存储元数据索引,与数据一起。因此,处理引擎可以快速确定查询所需的数据是否存在,而无需扫描所有数据。
其次,它们是基于列的存储,这意味着特定列的所有数据都紧密存储在文件中。一般而言,在 SQL 引擎中,列中的所有数据将包含相同类型的数据。这使得文件能够实现更高的压缩比和更有效的数据湖内空间利用率。
表格式
虽然将数据存储在 Parquet 或 ORC 等文件格式中对数据本身来说是很好的,但仅使用单一文件集表示单个表可能会有一些限制。简而言之,您还必须存储有关表的结构、演变和历史的附加元数据,以及与数据文件相关的附加元数据及其协议称为表格式。
表格式在文件格式之上引入了另一层元数据,以为表提供更丰富的抽象,允许进行高性能的高级数据管理,例如 ACID 事务、数据版本控制(即时间旅行)、模式演变以及高效的 IUD 操作(即插入、更新和删除)。这个额外的元数据层还允许进行更低级别的文件优化,如文件大小的合理调整(例如,较大的文件更适用于分析)和聚类(例如,优化数据共位)。
在实践中,表格式由存储在数据湖中的附加协议和元数据组成。您可以采用其他方法来实现表格式的元数据层,但这超出了本书的范围。广泛采用的表格式通过附加的元数据文件增强数据湖中的数据文件(例如 Parquet)。
所有现有的表格式都添加了一个日志级别,记录了对原始对象存储进行的所有插入/更新操作。图 5-2 显示了表格式在对象存储中的组织方式。各种表格式在它们如何管理日志级别方面有所不同。
ChatGPT
今天主要的表格式有 Apache Hudi、Apache Iceberg 和 Delta Lake。它们都是开源的,并且背后都有一个主要的商业实体。诸如 ACID 事务和数据版本控制等最常见的功能在所有这些格式中几乎相同。因此,自然而然地,每个表格式在设计上都有略微不同的重点。
Apache Hudi Uber引入了 Hudi,将数据仓库事务功能引入数据湖。Hudi提供了一个名为 Hudi DeltaStreamer 的开源实用程序,用于从流行的源(例如 Hudi 格式的 SQL 数据库)摄取数据。Presto支持Hudi连接器。在编写本书时,Hudi连接器仅支持读操作。有关更多详细信息,请参阅Presto文档。
Apache Iceberg Netflix创建了Apache Iceberg,其最初的项目目标之一是在S3兼容的对象存储中扩展非常大的表。它可以快速提供来自PB级数据集的目录列表的结果。目前,Iceberg不提供从流行源(例如 SQL 数据库)摄取数据的任何实用程序,也不需要进行最小的编码工作。Presto支持Iceberg连接器,提供读写功能。有关更多详细信息,请参阅Presto文档。
Delta Lake Databricks创建了Delta Lake(现在是Linux Foundation项目),以在数据湖中启用ACID事务。Delta Lake允许对象存储添加新数据并一致地读取该数据,因此多个用户读取数据时将获得该数据的相同版本。目前,Delta Lake仅提供了从流行源(例如 SQL 数据库)摄取数据的专有实用程序,而且几乎不需要编码工作。Presto支持Delta Lake连接器。在编写本书时,Delta Lake连接器仅支持读操作。有关更多详细信息,请参阅Presto文档。
查询引擎
查询引擎执行分析处理,使用户和其他应用能够从底层数据中得出见解。从成本和复杂性的角度来看,该引擎是一个关键的计算层。在本书中,我们使用 Presto 作为主要的查询引擎。
与传统数据仓库相比,湖仓库中的SQL查询引擎是独特的,因为数据存储组件完全与计算组件分离。这种责任的分离使得可以单独扩展计算容量,而不必与存储容量捆绑在一起,与传统数据仓库相比,可能带来成本节约和用户额外的灵活性。
元数据管理
我们将元数据管理定义为包括计算引擎正常访问和管理(例如更新)底层数据湖文件所需的技术元数据。元数据管理不包括与数据治理相关的元数据,例如用于数据访问控制的元数据。
通常,数据湖摄取来自不同源头的数据。数据湖使用元数据目录来跟踪存储在其中的数据并进行数据发现(表查找)。元数据对于了解可用数据、其位置以及数据湖如何访问它是至关重要的。
Hive Metastore(HMS)是最流行的元数据目录之一。HMS为Hive表和分区元数据提供了集中存储。客户端通过metastore服务API访问它。Presto支持Hive连接器。有关更多详细信息,请参阅 Presto 文档。
图 5-3 显示了 Presto 如何使用元数据目录执行表查找。首先,Presto客户端使用位于pq模式下的glue目录中的表transactions运行查询。在收到查询后,Presto向元数据目录询问transactions表的位置。元数据将完整路径返回给Presto以访问transactions表。接下来,Presto运行查询并将结果返回给Presto客户端。元数据目录不仅包含文件位置,还可以包括其他有助于优化查询的有用元数据,例如关于表的信息(表名、列名和列类型)、索引和视图。
数据治理
Lakehouse包含一个数据治理层。数据治理是指管理、控制和保护组织的数据资产,以确保数据质量、完整性、隐私和符合相关法规和政策。数据治理领域的示例包括: 访问控制 谁可以在什么级别访问数据(例如,只读,特定表、列或行)?
- 发现
个人如何发现数据?
- 语义定义
特定数据在领域或业务中的含义是什么?
- 数据谱系
这些数据是如何创建的,你能追溯到它的来源吗?
- 数据可观察性
了解数据的健康状况和质量。
覆盖所有这些数据治理领域将需要一本专门的书。因此,我们将重点放在访问控制上。
数据访问控制
数据访问控制是一种安全措施,通过限制访问仅限于经授权的用户,来保护数据在数据Lakehouse中的安全性。组织通过控制谁可以访问数据以及他们可以对数据执行什么操作,来防止未经授权的访问和对敏感或机密信息的滥用。
管理员可以通过设置表5-1中描述的细粒度权限,为用户授予不同级别的数据访问控制。
图5-4显示了不同级别的数据访问控制的示例。在数据库安全级别上,用户只能访问数据库A。在表格安全级别上,他们只能访问表格C。在列安全级别上,用户只能访问列E和F。最后,在行安全级别上,他们只能访问行G和H。
构建数据湖仓
在第1章中,我们介绍了我们的案例研究,重点是将Presto连接到数据湖。现在是时候扩展在图1-7中描述的场景,将Presto纳入数据湖仓的架构中。
图5-5显示了我们将在本节实现的方案的架构。图中用深灰色突出显示主要组件,用浅灰色突出显示辅助组件。作为对象存储,我们将使用MinIO使用Hudi表格式存储数据。为了初始化MinIO存储,我们将实现一个MinIO客户端,并为了在MinIO存储中写入数据,我们将在Spark中实现一个数据流。我们不会直接使用Presto,因为目前它不支持在Hudi格式中进行写操作。然后,我们将连接Presto到Hive Metastore,从MinIO存储中检索数据。Hive Metastore将使用MySQL数据库作为内部存储。最后,我们将连接一个Presto客户端到Presto,以从MinIO存储中获取数据。我们将每个组件都实现为Kubernetes集群中的单独的pod,这个集群已经在第2章中实现了。
您可以在本节中描述的代码在书的GitHub存储库中的目录05/下找到。 我们将通过执行以下增量步骤来实现这个场景:
- 配置MinIO
- 配置HMS
- 配置Spark
- 在HMS中注册Hudi表
- 连接并查询Presto
配置MinIO
请参考 05/data_lakehouse/minio.yaml 配置 MinIO。使用在 Docker Hub 上可用的 quay.io/minio/minio:RELEASE.2022-06-17T02-00-35Z 镜像将 MinIO 容器实现为 ReplicationController。然后,使用 minio server /data --console-address :9090 命令启动存储服务。 将此命令添加到 minio.yaml 文件中的容器规格中:
yaml
spec:
containers:
- name: minio
image: quay.io/minio/minio:latest
command:
- /bin/bash
- -c
args:
- minio server /data --console-address :9090
MinIO 需要用户名和密码进行访问,因此使用 MinIO Docker 镜像所需的两个环境变量 MINIO_ROOT_USER 和 MINIO_ROOT_PASSWORD 进行设置:
yaml
env:
- name: MINIO_ROOT_USER
valueFrom:
secretKeyRef:
key: minio_root_user
name: minio-secrets
- name: MINIO_ROOT_PASSWORD
valueFrom:
secretKeyRef:
key: minio_root_password
name: minio-secrets
将 MinIO 机密存储为 Kubernetes 集群的一个独立组件,命名为 minio-secrets。在 minio-secrets.yaml 文件中找到此组件的实现。 MinIO 从 9000 端口接受新连接,因此在 minio.yaml 文件中添加一个服务,监听两个端口,9090 用于控制台,9000 用于新连接:
yaml
apiVersion: v1
kind: Service
metadata:
name: minio
spec:
ports:
- name: minio-console
port: 9090
targetPort: 9090
- name: minio-api
port: 9000
targetPort: 9000
type: LoadBalancer
selector:
app: minio
要部署 MinIO 对象存储,请运行以下命令:
lua
kubectl create -f minio-secrets.yaml --namespace presto
kubectl apply -f minio.yaml --namespace presto
在浏览器中指向 http://localhost:9090/ 以访问 MinIO Web 界面。使用存储在 minio-secrets 中的凭据登录。存储不包含任何存储桶。
为 MinIO 填充数据
使用 MinIO 客户端(在本例中为 mc)定义存储的初始结构。我们将创建两个桶:warehouse,其中将包含原始数据,以及metastore,其中将包含 Hudi 格式的数据。此外,我们将在 warehouse/data 中添加一个名为 customers.csv 的示例表。
表 5-2 显示了 customers 表的快照。
该表尚未以 Hudi 格式存储。我们将使用 Spark 将表转换为 Hudi 表并将其存储在 metastore 分支中。
在 Kubernetes 集群中将 MinIO 客户端部署为一个独立的 pod。请参阅 05/data_lakehouse/mc.yaml 以配置 MinIO 客户端。
将 MinIO 客户端容器实现为 ReplicationController,使用在 Docker Hub 上提供的 minio/mc 镜像。
使用 Docker Hub 上提供的 minio/mc 镜像,并配置 sleep infinity 命令以保持 pod 处于运行状态:
yaml
containers:
- name: mc
image: minio/mc
command: ["sleep"]
args: ["infinity"]
从 minio-secrets 中读取 MINIO_USERNAME 和 MINIO_PASSWORD 环境变量,以访问 MinIO 存储:
yaml
env:
- name: MINIO_USERNAME
valueFrom:
secretKeyRef:
key: minio_root_user
name: minio-secrets
- name: MINIO_PASSWORD
valueFrom:
secretKeyRef:
key: minio_root_password
name: minio-secrets
最后,在主机文件系统中将包含示例表的 /data 目录作为外部目录挂载:
yaml
containers:
- name: mc
# 其他规格
mountPath: "/data/"
volumes:
- name: data
hostPath:
path: "/absolute/path/to/data/storage"
要部署 MinIO 对象存储,请运行以下命令:
arduino
kubectl apply -f mc.yaml --namespace presto
然后,进入 MinIO 客户端容器并创建两个桶:warehouse 用于原始数据和metastore 用于 HMS:
bash
/usr/bin/mc config host add minio http://minio:9000\
${MINIO_USERNAME} ${MINIO_PASSWORD}
/usr/bin/mc mb minio/warehouse;
/usr/bin/mc mb minio/metastore;
最后,使用数据目录的内容填充 warehouse 桶:
bash
/usr/bin/mc cp --recursive /data minio/warehouse;
再次访问 MinIO web 界面。您应该会看到两个桶:metastore(为空)和 warehouse(包含 data/customers.csv),如图 5-6 所示。
配置HMS
我们将使用HMS作为MinIO存储和Presto之间的中介。在我们的配置中,HMS将仅访问MinIO存储的metastore桶,我们将在其中插入Hudi表。
要配置HMS,首先创建HMS将用于存储数据的MySQL节点。请参阅 05/data_lakehouse/mysql-metastore.yaml。
arduino
kubectl apply -f mysql-metastore.yaml --namespace presto
接下来,使用以下信息配置 05/dockerfiles/hive-metastore/conf/hive-site.xml 文件:
- MinIO端点:
xml
<property>
<name>fs.s3a.endpoint</name>
<value>http://minio:9000</value>
</property>
- MinIO凭据,jdo.option.ConnectionUserName 和 javax.jdo.option.ConnectionPassword:
xml
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>admin</value>
</property>
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>admin</value>
</property>
- Metastore仓库目录。将其设置为 s3a://metastore/warehouse/。
- MySQL配置参数:
xml
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.cj.jdbc.Driver</value>
</property>
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://mysql-metastore:3306/metastore_db?createDatabaseIfNotExist=true</value>
</property>
然后,构建 Spark Docker 镜像,位于 05/dockerfiles/hive-metastore 目录中:
erlang
docker build -t hive-metastore .
最后,使用 05/data_lakehouse/hive-metastore.yaml 在 Kubernetes 集群中创建 HMS 节点:
arduino
kubectl apply -f hive-metastore.yaml --namespace presto
图 5-7 显示了我们将组织MinIO存储的方式。有两个桶:warehouse 用于原始数据,metastore 用于 Hudi 表。
配置Spark
我们将使用 Spark 将 warehouse/data 桶中包含的原始 customer.csv 表转换为 metastore/warehouse 桶中的 hudi_customer 表。
首先,构建 Spark Docker 镜像,位于 05/dockerfiles/spark 目录中:
erlang
docker build -t spark .
然后,创建指向 05/data_lakehouse 目录中包含的 spark.yaml 文件的 Kubernetes pod:
arduino
kubectl apply -f spark.yaml --namespace presto
图 5-8 概述了到目前为止实现的 lakehouse 场景。您已部署了三个主要组件(MinIO、HMS 和 Spark)以及两个辅助组件:MySQL metastore 和 MinIO 客户端。
注册 Hudi 表到 HMS
迄今为止,MinIO 对象存储只包含一个名为 customers.csv
的表,位于 warehouse/data
路径下。我们将使用 Spark 将 CSV 表转换为 Hudi 表。
进入 Spark 容器,并使用 MinIO 和 HMS 配置启动 Spark shell:
ini
spark-shell \
--packages org.apache.hadoop:hadoop-aws:3.3.1, \
org.apache.hudi:hudi-spark3.2-bundle_2.12:0.11.1 \
--conf spark.hadoop.fs.s3a.access.key="dbuser" \
--conf spark.hadoop.fs.s3a.secret.key="minio123" \
--conf spark.hadoop.fs.s3a.endpoint=http://minio:9000 \
--conf spark.hadoop.fs.s3a.path.style.access=true \
--conf spark.hadoop.hive.metastore.uris=\
"thrift://hive-metastore:9083" \
--conf spark.sql.warehouse.dir="s3a://metastore/" \
--conf spark.sql.catalog.spark_catalog.type=hive \
--conf spark.sql.catalog.spark_catalog.uri=thrift://hive-metastore:9083 \
--conf spark.sql.catalog.spark_catalog.warehouse=s3a://metastore/ \
--conf spark.sql.catalog.spark_catalog\
=org.apache.spark.sql.hudi.catalog.HoodieCatalog \
--conf spark.sql.extensions\
=org.apache.spark.sql.hudi.HoodieSparkSessionExtension \
--conf spark.serializer=org.apache.spark.serializer.KryoSerializer \
"${@-}"
在 Spark shell 中,我们使用 Scala 作为编程语言。查看 05/data_lakehouse/scripts/hudi-customers-create.scala
以获取更多详细信息。
在 Spark shell 中,首先导入所需的库:
arduino
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.spark.sql.functions.monotonicallyIncreasingId
然后,从 warehouse/data
桶加载 customers.csv
表:
arduino
val df = spark.read.options(Map("header" -> "true")
).csv("s3a://warehouse/data/customers.csv")
接下来,在数据集中添加 HMS 所需的 uuid
列:
ini
val df2 = df.withColumn("uuid", monotonicallyIncreasingId)
最后,将表保存到 MinIO 作为 Hudi 表:
scss
df2.write.format("hudi").
options(getQuickstartWriteConfigs).
option(RECORDKEY_FIELD_OPT_KEY, "id").
option(PRECOMBINE_FIELD_OPT_KEY, "dob").
option(TABLE_NAME, tableName).
mode(Overwrite).
saveAsTable("hudi_customers")
访问 MinIO Web 界面,打开 metastore/warehouse
桶。您应该会看到客户表的 Hudi 版本,如图 5-9 所示。
连接和查询 Presto
我们将连接 Presto 到 HMS 来查询 hudi_customer 表。从版本 0.275 开始,Presto 原生支持 Hudi,因此我们可以直接配置一个 Hudi 连接器。我们将使用 Presto 沙箱作为 Presto 实例。请参考 05/data_lakehouse/presto-coordinator.yaml 配置 Presto 协调器。准备包含所有 Presto 配置文件的目录 (05/data_lakehouse/conf) 并将其挂载到 Presto 实例中。使用 Hudi 连接器在 Presto 中读取 Hudi 表。Hudi 连接器需要以下参数:
ini
connector.name=hudi
hive.metastore.uri=thrift://hive-metastore:9083
除了连接器名称,还需指定 MinIO 端点 (hive.s3.endpoint) 和兼容的 S3 存储 (hive.s3.path-style-access=true)。
Presto 沙箱需要 MinIO 凭据作为环境变量。在 presto-coordinator.yaml 文件中设置它们:
yaml
spec:
containers:
...
env:
- name: AWS_ACCESS_KEY_ID
valueFrom:
secretKeyRef:
key: minio_root_user
name: minio-secrets
- name: AWS_SECRET_ACCESS_KEY
valueFrom:
secretKeyRef:
key: minio_root_password
name: minio-secrets
如果您的本地计算机资源不足以运行完整的 Presto 集群,请仅实例化 Presto 协调器。在部署 Presto 协调器后,部署一个 Presto 客户端,如第 4 章中所述。在这一节中,我们将使用 Presto CLI,在 Presto 协调器中运行。
登录 Presto 协调器并启动 Presto CLI,使用 presto-cli 命令:
arduino
sh-4.2# presto-cli
请注意,在前几章中我们使用 presto 命令运行 Presto CLI。在这里,命令是不同的,因为我们使用另一个 Docker 镜像来运行 Presto。
然后,将数据库设置为要查询的数据库(hudi.default):
arduino
presto> use hudi.default;
USE
列出数据库中的可用表:
sql
presto:default> show tables;
Table
----------------
hudi_customers
(1 row)
最后,运行以下查询到 Hudi 表:
sql
presto:default> SELECT last,gender,dob,zip,city,state
FROM hudi_customers
WHERE first = 'Sharon';
last | gender | dob | zip | city | state
------------+--------+------------+-------+------------+-------
Mclaughlin | F | 1954-07-05 | 94015 | Daly City | CA
Ayala | F | 1956-09-01 | 94619 | Oakland | CA
Harper | F | 1978-06-21 | 95827 | Sacramento | CA
Clark | F | 1976-09-17 | 99160 | Orient | WA
(4 rows)
Query 20230203_062422_00005_93snn, FINISHED, 1 node
Splits: 17 total, 17 done (100.00%)
0:06 [86 rows, 427KB] [15 rows/s, 75.9KB/s]
查询结果表明,数据湖仓库已经完美设置并运行。
总结
在本章中,您回顾了数据湖仓库的基本组件,包括数据湖存储、数据湖表格格式、查询引擎、元数据目录和数据访问控制,作为数据治理的一个特定案例。数据湖存储使您能够以对象存储格式存储数据,这对大数据更有效。MinIO 和 Amazon S3 是数据湖存储的示例。数据湖表格格式使您能够在访问数据时管理事务和类似操作,从而保持数据一致性以及通常的所有 ACID 操作。Hudi 格式是数据湖表格格式的示例。查询引擎提供了在数据湖仓库中访问许多目录的单一点。Presto 是查询引擎的示例。元数据目录为数据湖提供了高效的表格查找和数据发现。HMS 是表格查找的示例。最后,访问控制提供了定义谁可以访问数据的所有规则,甚至在细粒度级别上。
在章节的第二部分,您实现了一个包含 Presto、MinIO、HMS、Spark 和 Hudi 的数据湖仓库场景。首先,您将一个简单的表格转换为 CSV 文件,并将其存储为 Hudi 表格。然后,您将其存储在 HMS 元数据存储中,并通过 Presto 进行访问。
在第 6 章中,您将学习如何进行 Presto 管理。