使用 BigQuery 从 GCS 读取数据失败 "Not Found",但日期(文件)存在

Reading data from GCS with BigQuery fails with "Not Found", but the date (files) exists

我有一项服务不断更新 Hive 格式的 GCS 存储桶中的文件:

bucket
    device_id=aaaa
        month=01
            part-0.parquet
        month=02
            part-0.parquet
        ....
    device_id=bbbb
        month=01
            part-0.parquet
        month=02
            part-0.parquet
        ....

如果今天我们在 month=02 并且我 运行 使用 BigQuery 执行以下操作:

SELECT DISTINCT event_id
FROM `project_id.dataset.table` 
WHERE month = '02';

我收到错误:Not found: Files /bigstore/bucket_name/device_id=aaaa/month=02/part-0.parquet

我检查了一下,查询时文件就在那里 运行。

如果我运行

SELECT DISTINCT event_id
FROM `project_id.dataset.table` 
WHERE month = '01';

我得到的结果没有任何错误。我想这个错误与我在查询数据时修改数据有关。但据我了解,GCS 不应该是这种情况,这是来自他们的文档。

Because uploads are strongly consistent, you will never receive a 404 Not Found response or stale data for a read-after-write or read-after-metadata-update operation.

我看到一些帖子说这可能与我的桶有关Multi-region

还有其他见解吗?

可能是由于某种原因导致您收到此错误。

  • 当您将数据从 Cloud Storage 加载到 BigQuery table 时, 包含 table 的数据集必须在同一区域或 多区域 location 作为 Cloud Storage 存储桶。
  • 由于consistency,对于存储桶,元数据更新强烈 read-after-metadata-update 操作一致,过程 可能需要一些时间才能完成更改。
  • 不推荐使用 Multi-region 存储桶。

在这种情况下,这可能是由于一致性,因为当您在执行查询的同时更新文件 GCS 时,所以当您执行查询时,parquet 文件可供读取,而您没有没有得到错误,但下次 parquet 文件不可用时,因为服务正在更新文件而你得到了错误。

不幸的是,没有简单的方法来解决这个问题,但这里有一些选择:

  • 您可以将 pub/sub 例程添加到存储桶 and/or 文件中并快速启动 您在服务完成文件更新后的查询。
  • 制作一个工作流程,阻止更新他们的文件 存储桶,直到他们的查询完成。
  • 如果查询失败并显示“未找到”文件 ABCD,并且您有 已验证 ABCD 存在于 GCS 中,然后重试查询 X 次。
  • 您需要将数据备份到另一个您不会的位置 不断更新这些文件,一天一次。
  • 您可以将数据移动到您不会拥有的托管存储中 这个问题是因为你可以做快照。