了解可靠性
本文档介绍 BigQuery 的可靠性功能,例如可用性、耐用性、数据一致性、性能一致性、数据恢复以及错误处理注意事项的回顾。
此简介针对三个主要注意事项:
- 确定 BigQuery 是否适合您的作业。
- 了解 BigQuery 可靠性的维度。
- 确定特定用例的特定可靠性要求。
选择 BigQuery
BigQuery 是一种全托管式企业数据仓库,旨在存储和分析大量数据集。它提供了一种以一致的性能注入、存储、读取和查询 MB 至 PB 级数据的方法,而需管理任何底层基础架构。由于 BigQuery 的强大功能和性能,它非常适合用于一系列解决方案。 其中一些内容详细记录为参考模式。
通常,BigQuery 非常适合注入和分析大量数据的工作负载。具体来说,它可以有效地部署用于实时和预测数据分析(使用流式注入和 BigQuery ML)、异常值检测以及其他以可预测性能分析大量数据的用例。但是,如果您正在寻找支持在线事务处理 (OLTP) 样式应用的数据库,则应考虑可能更适合这些用例的其他 Google Cloud 服务,例如 Spanner、Cloud SQL 或 Bigtable。
BigQuery 中的可靠性维度
可用性
可用性定义了用户从 BigQuery 读取数据或向其中写入数据的能力。对于这两种操作,BigQuery 可以提供 SLA 承诺的 99.99% 的高可用性。这两种操作都涉及两个组件:
- BigQuery 服务
- 执行特定查询所需的计算资源
服务的可靠性是用于检索数据的特定 BigQuery API 的一个函数。计算资源的可用性取决于运行查询时用户可用的容量。如需详细了解 BigQuery 的基本计算单元以及产生的槽资源不足,请参阅了解槽。
耐用性
SRE 手册的实现 SLO 章节中讨论了耐用性,并将其描述为“可以成功读取的数据的比例”。
数据一致性
一致性定义了用户在数据被写入或修改后对于查询这些数据的期望。数据一致性的一个方面是确保数据注入的“正好一次”语义。如需了解详情,请参阅加载数据的示例用例和重试失败的作业插入中的“解决方案的可靠性”。
性能一致性
一般来说,性能可以用两个维度表示。延迟时间衡量长时间运行的数据检索操作(如查询)的执行时间。吞吐量衡量 BigQuery 在特定时间段内可以处理的数据量。由于 BigQuery 的多租户、可横向扩缩设计,其吞吐量可扩容到任意数据大小。延迟时间和吞吐量的相对重要性由具体用例决定。
数据恢复
服务中断后的数据恢复能力可以通过以下两种方法衡量:
- 恢复时间目标 (RTO)。发生突发事件后可以接受的数据不可用时间。
- 恢复点目标 (RPO)。可以接受突发事件之前收集的数据丢失的量。
在一个可用区或区域发生多天或破坏性服务中断的情况下(这种情况不太可能发生),这些考量因素尤为重要。
制定灾难恢复计划
虽然“灾难”一词可能会让您想起自然灾害,但本部分的范围涵盖单独的机器丢失到某个区域的灾难性丢失等特定故障。前者是 BigQuery 自动处理的日常事件,而后者是客户可能需要设计其架构以在必要时处理的情况。了解灾难规划涉及的客户责任范围非常重要。
BigQuery 提供业界领先的 99.99% 正常运行时间 SLA。这可通过 BigQuery 的区域性架构实现。该架构可在两个不同的可用区写入数据,并预配冗余的计算容量。请务必注意,BigQuery SLA 对于区域(例如 us-central1)和多区域(例如美国)是相同的。
自动场景处理
由于 BigQuery 是区域级服务,因此 BigQuery 应负责自动处理机器(甚至整个可用区)丢失的情况。BigQuery 基于可用区而构建,这对用户来说是抽象的。
机器丢失
机器故障是 Google 需要大量处理的日常事件。BigQuery 会自动处理机器故障,而不会影响到包含的可用区。
在后台,查询的执行过程会分解为多个小任务,可并行分派给多台机器。通过将工作重新分配到其他机器,系统可自动处理机器性能突然丢失或下降的问题。这种方法对于缩短尾延迟时间至关重要。
BigQuery 利用 Reed-Solomon 编码来高效、持久地存储数据的可用区副本。如果发生极其罕见的多个机器故障并导致可用区副本丢失,则数据还会以相同方式存储在至少一个其他可用区中。在这种情况下,BigQuery 将检测问题并为数据创建新的可用区副本以恢复冗余。
可用区丢失
任何给定可用区中的计算资源的基础可用性不足以满足 BigQuery 的 99.99% 的正常运行时间 SLA。因此,BigQuery 为数据和计算槽提供自动可用区性冗余。虽然短期有效的可用区性服务中断并不常见,但确实会发生。但是,BigQuery 自动化将在任何严重中断的一两分钟内将查询故障切换到另一个可用区。已在运行中的查询可能不会立即恢复,但新发出的查询将立即恢复。这将表现为运行中的查询需要很长时间才能完成,而新发出的查询会快速完成。
即使某个可用区长时间不可用,但由于 BigQuery 会同步将数据写入两个可用区,因此数据也不会丢失。这样,即使可用区丢失,客户也不会遭遇服务中断故障。
故障类型
故障分为两种类型:软故障和硬故障。
软故障是指硬件未损坏的操作缺陷。例如,电源故障、网络分区或机器崩溃。一般而言,如果发生软故障,BigQuery 绝不会丢失数据。
硬故障是指硬件损坏的操作缺陷。硬故障比软故障严重。硬故障的示例包括洪水、恐怖袭击、地震和飓风造成的破坏。
可用性与耐用性
创建 BigQuery 数据集时,请选择存储数据的位置。此位置是以下位置之一:
- 地区:特定的地理位置,例如爱荷华州 (
us-central1
) 或蒙特利尔 (northamerica-northeast1
)。 - 多区域:包含两个或更多地理位置的大型地理区域,例如美国 (
US
) 或欧洲 (EU
)。
在任何一种情况下,BigQuery 都会将数据副本自动存储在所选位置中一个区域内的两个不同 Google Cloud 区域中。
除了存储冗余外,BigQuery 还维护多个可用区的冗余计算容量。通过将冗余存储和计算跨多个可用性可用区进行组合,BigQuery 可提供高可用性和耐用性。
如果发生机器级故障,BigQuery 将继续运行,延迟时间不超过几毫秒。所有当前正在运行的查询仍会继续处理。如果发生区域性软故障或硬故障,预期不会丢失任何数据。但是,当前正在运行的查询可能会失败,需要重新提交。区域性软故障(例如由电源中断、销毁的转换器或网络分区导致)是经过充分测试的路径,会在几分钟内自动缓解。
如果发生地区性软故障(例如网络连接发生地区性中断),则可能导致地区在重新联网之前不再可用,但不会导致数据丢失。如果发生地区性硬故障,例如某个灾难销毁了整个地区,则可能会导致存储在该地区中的数据丢失。BigQuery 不会自动提供其他地理区域中数据的备份或副本。您可以创建跨区域数据集副本来增强灾难恢复策略。
如需详细了解 BigQuery 数据集位置,请参阅位置注意事项。
场景:区域丢失
BigQuery 在物理区域丢失等极为罕见且前所未有的意外情况下不提供耐用性和可用性。“区域和多区域”配置也是如此。因此,在此类情况下,维护耐用性和可用性需要客户进行一些规划。在出现临时丢失(例如网络服务中断)的情况下,如果 BigQuery 的 99.99% SLA 不足以保证可用性,则应考虑冗余可用性。
为避免在发生破坏性的区域性丢失时出现数据丢失,您需要将数据备份到另一个地理位置。例如,您可以定期将数据快照导出到另一个不同地理区域的 Google Cloud Storage 中。您可以按照批量数据处理使用场景中的说明完成此操作。
对于 BigQuery 多区域,您应该避免备份到多区域范围内的区域。例如,不要将美国的数据备份到 us-central1 区域。区域和多区域可能会共用故障域,因此会同时遭遇灾难。请改为将您的数据备份到非美国区域,例如 northamerica-northeast1
。如果数据驻留要求需要将备份存储在美国,则最好将两个区域配对(如 us-central1 和 us-east1)。
为避免延长不可用时间,您需要在两个分离的 BigQuery 位置同时复制数据以及预配槽。与上述类似,请避免混用区域和多区域,因为它们可能会同时遭遇灾难。
区域冗余设置最可靠的架构是运行热-热模式(也称为“活跃-活跃”)。这意味着您的工作负载同时在主要区域和次要区域并行运行。虽然费用更高,但这可确保次要区域获得持续验证;另外,当需要故障切换到该区域时,次要区域可以正常运行。如果区域性服务中断期间的可用性不太重要,则将数据备份到其他区域可确保耐用性。
场景:意外删除或数据损坏
借助 BigQuery 的多版本并发控制架构,BigQuery 支持时间旅行。借助此功能,您可以查询过去 7 天内任何时间点的数据。这样可以实现自行恢复在 7 天窗口内意外删除、修改或损坏的数据。时间旅行甚至可以恢复于已删除的表。
BigQuery 还支持截取表的快照。借助此功能,您可以在同一区域内明确备份数据,以获得超过 7 天的时间旅行窗口。快照纯粹是元数据操作,不会产生额外的存储字节。虽然这样有益于防止意外删除,但它不会提高数据的耐用性。
用例:实时分析
在此使用场景中,系统不断将流式数据从端点日志注入到 BigQuery 中。为了防止整个区域的 BigQuery 长时间不可用,您需要持续在其他区域复制数据并预配槽。由于注入路径中使用了 Pub/Sub 和 Dataflow,该架构对 BigQuery 不可用性具有弹性,因此这种高级别的冗余可能不值得付出这样的费用。
假设用户使用导出作业将 us-east4 中的 BigQuery 数据配置为每晚导出到 us-central1 中的 Archive Storage 类别下的 Cloud Storage。这可以在 us-east4 发生灾难性数据丢失时提供持久备份。在此情况下,恢复点目标 (RPO) 为 24 小时,因为上次导出的备份在最坏情况下最长可达 24 小时。恢复时间目标 (RTO) 可能是几天,因为数据需要从 Cloud Storage 备份恢复到 us-central1 中的 BigQuery。如果 BigQuery 预配的可用区与备份所在的可用区不同,则需要先将数据转移到此区域。另请注意,除非您事先在恢复区域中购买冗余槽,否则根据请求的数量,预配所需的 BigQuery 容量可能会产生额外延迟。
用例:批量数据处理
在此使用场景中,每日报告必须按固定的截止时间完成,然后发送给监管机构,这对业务至关重要。通过运行整个处理流水线的两个单独实例来实现冗余可能是值得的。使用两个单独的区域(如 us-west1 和 us-east4)可提供地理区域隔离和两个独立故障域,以防某个区域长时间不可用,甚至发生永久性区域丢失。
假设我们需要正好交付一次报告,我们需要协调成功完成的两个流水线的预期情况。合理的策略是从首先完成的流水线中选取结果,例如,在成功完成后通知 Pub/Sub 主题。或者,覆盖结果并重新设置 Cloud Storage 对象的版本。如果稍后完成的流水线写入损坏的数据,您可以通过从 Cloud Storage 恢复首选完成的流水线写入的版本来进行恢复。
错误处理
以下是解决影响可靠性的错误的最佳实践。
重试失败的 API 请求
BigQuery 的客户端(包括客户端库和合作伙伴工具)在发出 API 请求时应使用截断指数退避算法。这意味着,如果客户端收到系统错误或配额错误,它应该多次重试请求,但应具有随机且不断增加的退避时间间隔。
采用这种重试方法可使您的应用在遇到错误时更加稳健。即使在正常操作条件下,您也可以预期大约万分之一的请求会失败,如 BigQuery 的 99.99% 可用性 SLA 中所述。在异常情况下,此错误率可能会增加,但如果错误是随机分布的,则指数退避算法策略可以缓解除最严重的情况之外的其他所有情况。
如果请求持续失败并显示 5XX 错误,您应向 Google Cloud 支持团队上报。请务必明确传达请求失败对您业务的影响,以便使问题获得正确的分类。另一方面,如果请求持续失败并显示 4XX 错误,那么应该可以通过更改应用来解决该问题。如需了解详情,请参阅错误消息。
指数退避算法逻辑示例
指数退避逻辑通过将重试之间的等待时间增加到最长退避时间来重试查询或请求。例如:
向 BigQuery 发出请求。
如果请求失败,则等待 1 + random_number_milliseconds 秒后再重试请求。
如果请求失败,则等待 2 + random_number_milliseconds 秒再重试请求。
如果请求失败,则等待 4 + random_number_milliseconds 秒后再重试请求。
依此类推,等待时间上限为
maximum_backoff
。继续等待并重试,直至达到重试次数上限,但不会增加重试之间的等待时间。
请注意以下几点:
等待时间为
min(((2^n)+random_number_milliseconds), maximum_backoff)
,其中,n
会在每次迭代(请求)后增加 1。random_number_milliseconds
是小于或等于 1,000 的毫秒数(随机值)。这种随机化有助于避免出现以下情况:许多客户端同步并同时执行重试操作,导致同步发送每一波请求。每次重试请求后,系统都会重新计算random_number_milliseconds
值。最大退避时间 (
maximum_backoff
) 通常为 32 或 64 秒。最适当的maximum_backoff
值取决于用例。
客户端在达到最大退避时间后可以继续重试。此后执行的重试不需要继续增加退避时间。例如,如果客户端使用的最大退避时间为 64 秒,则在达到此值后,客户端可以继续每 64 秒重试一次。到了特定时间点后,客户端应停止无限重试。
重试之间的等待时间和重试次数取决于您的用例和网络条件。
重试失败的作业插入
如果“仅一次”插入语义对您的应用很重要,则在插入作业时还有其他考量因素。如何实现“最多一次”语义取决于您指定的 WriteDisposition。写入处置方式会告知 BigQuery 在表中已存在要写入的数据时应执行的操作:失败、覆盖或附加。
使用 WRITE_EMPTY
或 WRITE_TRUNCATE
处置方式,只需重试任何失败的作业插入或执行即可实现这一语义。这是因为作业注入的所有行都以原子方式写入表。
使用 WRITE_APPEND
处置方式时,客户端需要指定作业 ID 以防止重试再次附加相同的数据。它的原理是 BigQuery 将拒绝尝试使用先前作业中的 ID 的作业创建请求。这样可以实现任何给定作业 ID 的“最多一次”语义。然后,在通过 BigQuery 确认所有先前尝试都失败后,您可以在新的可预测作业 ID 下重试,从而实现“仅一次”语义。
在某些情况下,由于暂时性问题或网络中断,API 客户端或 HTTP 客户端可能无法收到作业已插入的确认信息。重试插入时,该请求将失败,并返回 status=ALREADY_EXISTS
(code=409
和 reason="duplicate"
)。可以调用 jobs.get
来检索现有作业状态。在现有作业的状态为 retrieved
之后,调用方可以确定是否应创建具有新作业 ID 的新作业。
用例和可靠性要求
BigQuery 可能是各种架构的关键组件。根据用例和部署的架构,可能需要满足不同的可用性、性能或其他可靠性要求。在本指南中,我们选择两个主要用例和架构进行详细讨论。
实时分析
第一个示例是事件数据处理流水线。 在此示例中,使用 Pub/Sub 从端点注入日志事件。接着,流处理 Dataflow 流水线对数据执行一些操作,然后使用 Storage Write API 将数据写入 BigQuery。然后,这些数据会用于临时查询(例如用于重新创建可能产生特定端点结果的事件序列),以及馈入近乎实时的信息中心,以便通过可视化功能检测数据中的趋势和模式。
此示例要求您考虑可靠性的多个方面。由于端到端数据新鲜度要求非常高,因此注入过程的延迟时间至关重要。数据写入 BigQuery 后,可靠性被视为用户以一致且可预测的延迟时间发出临时查询的能力,以及确保利用该数据的信息中心反映可用的最新信息。
批量数据处理
第二个示例是基于金融服务行业法规遵从的批处理架构。关键要求是在固定的夜间截止时间之前向监管机构提交每日报告。只要生成报告的每晚批处理过程都在此截止时间之前完成,则可以视为足够快。
数据需要从 BigQuery 提供,并与其他数据源一起用于信息汇总、分析和最终生成 PDF 报告。保证这些报告准时无误地提交是关键的业务要求。因此,需要确保数据注入以及正确且在一致的时间范围内生成报告以满足要求的截止时间,这种可靠性是关键所在。