Bigquery事件流提供"无法获取网址"有时

时间:2015-07-01 08:34:15

标签: google-bigquery

我们刚刚对bigquery进行了一些流媒体事件测试,这部分取得了成功,但我注意到一个事件丢失了(大约20个),当我搜索日志时,我注意到这个特定事件由于

而失败
Caused by: java.io.IOException: Could not fetch URL: https://www.googleapis.com/bigquery/v2/projects/<project-name>/datasets/<datasetname>/tables/events_app6_v6_201507/insertAll
    at com.google.appengine.api.urlfetch.URLFetchServiceImpl.convertApplicationException(URLFetchServiceImpl.java:140)
    at com.google.appengine.api.urlfetch.URLFetchServiceImpl.fetch(URLFetchServiceImpl.java:45)
    at com.google.apphosting.utils.security.urlfetch.URLFetchServiceStreamHandler$Connection.fetchResponse(URLFetchServiceStreamHandler.java:502)

所以我对任何人的问题都注意到了:

A)插入失败的可能性有多大?

B)我们处理这类错误的最佳模式是什么。

考虑到我们正在播放大量的事件,并且没有时间进行任何冗长的错误处理。

一种方法是简单地忽略错误,但我们不能接受失去5%的事件。

提前致谢!

1 个答案:

答案 0 :(得分:2)

由于流媒体的有效载荷大小有限,请参阅Quota policy它更容易谈论时间,因为有效载荷以同样的方式限制我们两个人,但我也会提到其他副作用

我们为每个流媒体请求测量1200-2500毫秒,这在过去的一个月中是一致的,如图所示。

enter image description here

我们看到了几种副作用,但是:

  • 请求随机输入类型&#39;后端错误&#39;
  • 请求随机失败,类型为&#39;连接错误&#39;
  • 请求随机失败,类型为&#39;超时&#39; (注意这里,因为只有一些行失败而不是整个有效载荷)
  • 其他一些错误消息是非描述性的,而且它们非常含糊,以至于它们无法帮助您,只需重试即可。
  • 我们每天都会看到数百起此类故障,因此它们几乎不变,与云健康状况无关。

对于所有这些,我们在付费Google Enterprise支持中打开了案例,但不幸的是他们没有解决它。它接缝推荐的选项,因为这是一个指数退避与重试,甚至支持告诉这样做。个人并不能让我开心。

此外,失败率符合我们在SLA中的99.9%正常运行时间,因此没有理由反对。

关于SLA需要注意的事项,它是一个非常严格定义的结构,细节是here。 99.9%的正常运行时间未直接转换为失败率。这意味着如果BQ在一个月内有30分钟的停机时间,然后在该时间段内进行10,000次插入但在该月的其他时间没有进行任何插入,则会导致数字被串联。这就是我们建议指数退避算法的原因。 SLA明确地基于正常运行时间而不是错误率,但从逻辑上讲,如果您在不同时间使用退避重试设置在整个月中进行流式插入,则两者之间会密切相关。从技术上讲,如果你已经设置了适当的重试机制,那么如果你在月内进行插入,你应该平均经历大约1/1000次失败的插入。

您可以查看有关项目运行状况的此图表: https://console.developers.google.com/project/YOUR-APP-ID/apiui/apiview/bigquery?tabId=usage&duration=P1D

您需要构建重试机制来重新排列事件。如前所述,&#39;超时&#39; type是特殊的,因为只有一些行是超时的,有些是成功的。这意味着您需要解析响应,并查看哪些响应并仅重新排队。如果您重新排列所有有效负载,则最终可能会出现重复项。

您需要使用async processes重新考虑该方法。为了更快地完成,您需要并行运行多个工作程序,流式传输性能将是相同的。只有10名工人并行,这意味着时间将减少10倍。

后台处理IO绑定或cpu绑定任务现在是大多数Web应用程序中的常见做法。有大量软件可以帮助构建后台作业,其中一些基于Beanstalkd等消息传递系统。

基本上,您需要在封闭网络中分配插入作业,确定优先级,然后使用(运行)它们。嗯,这正是Beanstalkd所提供的。

Beanstalkd提供了在管中组织作业的可能性,每个管对应于作业类型。

你需要一个可以将作业放在管上的API /生产者,让我们说这行的json表示。这是我们用例的杀手级功能。所以我们有一个获取行的API,并将它们放在管上,这只需要几毫秒,因此您可以实现快速响应时间。

另一方面,你现在在一些管子上有一堆工作。你需要一个代理人。代理人/消费者可以预约工作。

它还可以帮助您进行作业管理和重试:成功处理作业后,消费者可以从管中删除作业。在失败的情况下,消费者可以埋葬这份工作。这项工作不会被推回管中,但可供进一步检查。

消费者可以释放一份工作,Beanstalkd会将这项工作推回管中,并将其提供给其他客户。

可以在大多数常见语言中找到Beanstalkd客户端,web interface可用于调试。