- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试在使用谷歌存储作为存储层的增量表之上创建一个外部 BQ 外部表。在增量表上,我们执行包含删除的 DML。
我可以在所有增量文件都存在的 gs 存储桶之上创建一个 BQ 外部表。但是,它甚至拉取删除记录,因为 BQ 外部表无法读取 delta 的事务日志,其中它说明要考虑哪些 Parquet 文件以及要删除哪个 Parquet 文件。
除了以编程方式将数据从 delta 复制到 BQ 之外,有没有一种方法可以将 BQ 中 delta 表(gs 位置)的最新快照公开为外部表?
最佳答案
所以这个问题是在一年多以前提出的,但我对 Oliver 的回答进行了巧妙但强大的补充,消除了数据重复和额外的加载逻辑。
第 1 步 按照 Oliver 的建议生成 symlink_format_manifest 文件;您可以在每次更新时触发它,也可以按照 here 的说明将 tblproperty 添加到您的文件中到更新增量表时自动创建这些文件;
ALTER TABLE delta.`<path-to-delta-table>` SET TBLPROPERTIES(delta.compatibility.symlinkFormatManifest.enabled=true)
第 2 步创建指向增量表位置的外部表
> bq mkdef --source_format=PARQUET "gs://test-delta/*.parquet" > bq_external_delta_logs
> bq mk --external_table_definition=bq_external_delta_logs test.external_delta_logs
第 3 步 创建另一个指向 symlink_format_manifest/manifest 文件的外部表
> bq mkdef --autodetect --source_format=CSV gs://test-delta/_symlink_format_manifest/manifest > bq_external_delta_manifest
> bq mk --table --external_table_definition=bq_external_delta_manifest test.external_delta_manifest
第 4 步使用以下查询创建 View
> bq mk \
--use_legacy_sql=false \
--view \
'SELECT
*
FROM
`project_id.test.external_delta_logs`
WHERE
_FILE_NAME in (select * from `project_id.test.external_delta_logs`)' \
test.external_delta_snapshot
现在,只要您的增量表从 test.external_delta_snapshot View 刷新,您就可以获得最新的快照,而无需任何额外的加载或数据复制。 这个解决方案的一个缺点是,如果模式发生变化,您必须手动或使用 BQ 客户端等从您的 spark 管道向表定义添加新字段。对于那些对这个解决方案如何感到好奇的人有效,请继续阅读。
这是如何运作的;
符号链接(symbolic link) list 文件包含指向当前增量版本分区的新行分隔格式的 parquet 文件列表;
gs://delta-test/......-part1.parquet
gs://delta-test/......-part2.parquet
....
除了我们的增量位置之外,我们通过将此 list 文件视为 CSV 文件(它实际上是一个单列 CSV 文件)来定义另一个外部表。我们定义的 View 利用了提到的 _FILE_NAME 伪列 here ,它指向表中每一行的 Parquet 文件位置。如文档中所述,_FILE_NAME 伪列是为指向存储在 Cloud Storage 和 Google Drive 中的数据的每个外部表定义的。
所以在这一点上,我们有加载最新快照所需的 parquet 文件列表,并且能够使用 _FILE_NAME 列过滤我们想要读取的文件。我们定义的 View 只是定义了这个过程来获取最新的快照。每当我们的增量表更新时, list 和增量日志表都会查找最新的数据,因此我们将始终获得最新的快照,而无需任何额外的加载或数据重复。
最后,众所周知,在外部表上执行比 BQ 托管表更昂贵(执行成本),因此最好像 Oliver 建议的那样尝试双写入,并像您要求的那样尝试外部表解决方案。存储比执行成本更低,因此在某些情况下,将数据保存在 GCS 和 BQ 中的成本可能低于像这样保存外部表的成本。
关于pyspark - 如何在 GCS 中的增量表之上创建 BQ 外部表并仅显示最新快照,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66859215/
GCS Transfer Service是定期传输数据的一个很好的解决方案。将一个存储桶同步到另一个存储桶(目标存储桶具有存档存储类)的适当设置是什么? 我担心的一个问题是,如果服务正在检查相同的对象
我正在尝试使用 Envoy 代理将请求路由到 GCS。我能够通过代理路由实际的存储请求。但是当我在 GCS 连接器设置中设置此 fs.gs.proxy.address 参数时,OAuth token
这个问题在这里已经有了答案: Is it necessary to recreate a Google Container Engine cluster to modify API permissi
GCS = 谷歌云存储 GAE = 谷歌应用引擎 如果给定目录(模拟目录,因为不存在真实目录)中有大量文件,我该如何管理: 在我的 GAE Python 代码中列出用于某些处理的所有文件? 按文件名降
GCS 文件 API 已于 2015 年 7 月 28 日关闭。在我的开发服务器中,我收到以下警告: The Google Cloud Storage Java API is deprecated a
我想将 400MB 的文件上传到 Google Cloud Storage。以下是我用来获取上传网址并在 angularjs 中发布的代码片段 Java Servlet: UploadOptions
一个简单的 Python 代码,用于列出 Google Cloud Storage 中特定文件夹中的对象: from apiclient import discovery import apiclie
管理Terraform状态文件的最佳方式是通过云端的统一的存储,如谷歌云就用GCS。 首先要创建一个Bucket:
我目前正在尝试编写一些代码以将 Google 存储桶中的一些“区域”对象转换为“冷线”,但出现以下异常: {The service storage has thrown an exception: G
我需要从 GCS 存储桶中的文件夹中删除数百万个对象。 这是我目前的实现。 bucket = self.storage_client.bucket(bucket_name) blobs = bucke
我已经安装了 hadoop 3 版本的 GCS 连接器,并将以下配置添加到 core-site.xml,如 Install.md 中所述.目的是将数据从本地集群中的 hdfs 迁移到云存储。 核心站点
我正在尝试使用 Java 存储客户端从远程服务器读取文件行数。 还尝试了 gsutil cat gs://{bucket_name}/file.txt | wc -l < 还有其他办法吗? 最佳答
我从开始 client = storage.Client() bucket = client.get_bucket(BUCKET_NAME) 我知道如何: 列出 bucket
如果有任何文件上传到 Google 云存储,我们将通过 Google 云功能自动处理文件。我们使用 python 编写了代码。 https://cloud.google.com/functions/d
关注谷歌的 Getting Started我使用以下代码获取远程目录中所有文件的列表 class GCSFileStorage { String bucket = "bucket_name";
我想获取存储在 Google Cloud Storage 中的文件的文件元数据。实际上,我们需要文件的媒体链接,以便可以下载文件或将 URL 添加到下载页面。 Blob blob = storage.
我使用 scala 开发应用程序,通过 hdfs 上的服务帐户凭据从 GCS 下载加密文件(使用客户提供的加密 key 的加密文件) val path = new Path(keyfile) val
当我通过 Console 从 bucket 中的“文件夹”中删除所有文件时,该文件夹也消失了,因为没有目录这样的东西 - 整个bucket 之后的路径是关键。 但是,当我通过 REST API 以编程
我现在觉得有点傻。我一直在阅读大量文档和 stackoverflow 问题,但我无法正确理解。 我在 Google Cloud Storage 上有一个文件。它在桶“test_bucket”中。在这个
我正在使用在 Google 计算引擎上运行的 node.js 应用程序为每个用户创建 GCS 存储桶。存储桶创建是每个用户的一次性事件。但是当我尝试运行该程序为 20 个用户并行创建唯一的存储桶时,出
我是一名优秀的程序员,十分优秀!