将数据流式传输到 BigQuery 中的旋转日志表中

Stream data into rotating log tables in BigQuery

我想使用 insertAll 将一些时间序列数据流式传输到 BigQuery 中,但只保留最近 3 个月(比如说)以避免无限制的存储成本。通常的答案是 save each day of data into a separate table 但 AFAICT 这需要提前创建每个这样的 table。我打算直接从使用仅具有 bigquery.insertdata 范围的令牌授权的不安全客户端流式传输数据,因此他们将无法自己创建每日 table。我能想到的唯一解决方案是 运行 一个安全的每日 cron 作业来创建 tables —— 不理想,特别是因为如果它失败,数据将被丢弃直到 table已创建。

另一种方法是将数据流式传输到单个 table 中,并随着 table 的增长使用 table decorators 来控制查询成本。 (我希望所有查询都针对特定时间范围,因此装饰器在这里应该非常有效。)但是,无法从 table 中删除旧数据,因此存储成本将在一段时间后变得不可持续。我也想不出任何方法来 "copy and truncate" table 原子地,这样我就可以将旧数据分成每天 tables 而不会丢失当时流式传输的行。

关于如何解决这个问题有什么想法吗?如果您的解决方案允许我将旧数据重新聚合到时间上更粗略的行中,从而以相同的存储成本保留更多历史记录,则可加分。谢谢。

编辑:刚刚意识到这是 的部分副本。

你已经分区解决了。如果 table 创建是一个问题,在 appengine 中有一个每小时 cron 来验证今天和明天总是创建 tables。 appengine 很可能不会超过免费配额,并且它有 99.95% 的正常运行时间 SLO。 cron 永远不会停止。

我们大多数人都在做与您描述的相同的事情。

但是我们不使用 cron,因为我们提前创建了 tables 1 年或在某些项目上提前 5 年。您可能想知道我们为什么这样做,什么时候这样做。

我们在开发人员更改模式时执行此操作。我们进行部署,我们 运行 一个脚本负责 old/existing tables 的模式更改,并且脚本从未来删除所有那些空的 tables 和只是重新创建它们。我们没有使用 cron 使我们的生活复杂化,因为我们知道架构更改的确切时刻,即部署,并且在这么长的时间段内提前创建 tables 没有任何缺点。当创建用户或他们关闭帐户时,我们也会在基于 SaaS 的系统上基于租户执行此操作。

这样我们就不需要 cron,我们只是知道部署需要在架构更改时执行这个额外的步骤。

关于在我对您的 table 进行一些维护时不要丢失流式插入,您需要在应用程序级别解决您的业务逻辑。您可能有某种消息队列,例如 Beanstalkd 将所有行排队到一个管中,然后工作人员将其推送到 BigQuery。当 BigQuery API 响应错误并且您需要重试时,您可能会使用它来解决问题。使用简单的消息队列很容易做到这一点。因此,当您暂时停止或重命名某些 table 时,您将依赖于此重试阶段。流式插入将失败,很可能是因为 table 尚未准备好进行流式插入,例如:已临时重命名以执行一些 ETL 工作。

如果您没有此重试阶段,您应该考虑添加它,因为它不仅有助于重试 BigQuery 失败的调用,而且还允许您进行一些维护 window。

如果您查看流式 API 发现文档,就会发现一个名为 "templateSuffix" 的新实验领域,其中有非常相关的描述。

我还要指出,官方文档尚未发布,因此在使用该字段时应该特别小心——尤其是在生产环境中。实验领域可能存在错误等。我想到的要注意的事情是:

  • 以非向后兼容的方式修改基础 table 的架构。
  • 以与基础 table 不兼容的方式直接修改已创建 table 的架构。
  • 通过此后缀直接流式传输到创建的 table -- 行插入 ID 可能不适用于跨边界。
  • 在创建的 table 正在积极流式传输到时对其执行操作。

而且我确定其他事情。无论如何,我只是想指出这一点。我相信官方文档会更详尽。