2014-07-02 46 views
3

我们利用google-api-php-client库将大量服务器端数据流式传输到BigQuery中。流媒体的效果很好,除了表现。BigQuery利用PHP流式传输'insertAll'性能

我们的负载测试为我们提供了1000ms(1秒)的平均时间,将一行数据流传输到BigQuery中。我们不能让客户等待超过200毫秒。我们已经测试了更小的有效载荷,时间保持不变。客户端的异步调用不是我们的选择。

的代码的“瓶颈”行是:

$service->tabledata->insertAll(PROJECT_NUMBER, DATA_SET, TABLE, $request); 

具有库的机罩调用插入该行看了下被简单地卷曲请求(Curl.php in the library)。

有没有什么办法可以修改insertAll()使其更快?我们并不关心结果,所以一场即燃即用的会为我们工作。我们已经尝试在底层cCURL请求中设置CURLOPT_CONNECTTIMEOUT_MS和CURLOPT_TIMEOUT_MS,但它不起作用。

+1

查看pfsocket打开。它应该通过简单地重复使用以前使用的套接字来提供适度的性能增益。我怀疑谷歌提供这个在lib中,所以你不得不自己滚动和手动处理所有的标题。 – r3wt

+0

是的,我应该在帖子中提到我们确实研究过“fsockopen”并且它确实有效(<100ms) - 直到我们由于大量请求(〜5K p/s)而开始用尽套接字时, 。虽然没有调查pfsocket .. –

+0

你有没有尝试所有必要的性能调整为你的操作系统?文件句柄,连接等 – r3wt

回答

3

阅读您的所有评论和旁注。您选择的方法不能缩放,也不会缩放。您需要重新思考异步过程的方法。

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

基本上,您需要在封闭网络中分配插入作业,优先考虑它们并消耗(运行)它们。那么,这正是Beanstalkd提供的。

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

您需要一个可以将工作放在管道上的API /生产者,比方说该行的json表示。这对我们的用例来说是一个杀手锏。所以我们有一个获取行的API,并将它们放在管道上,这只需要几毫秒,这样您就可以实现快速的响应时间。

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

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

一位消费者可以发布一份工作,Beanstalkd将把这项工作推回管道,并将其提供给另一位客户。

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

+0

尽管我们并没有真正使用Beanstalkd,但这是一个很好的答案。我们决定使用Redis队列并让Python作业获取关键字(一行的JSON表示)并对其进行异步处理。像魅力一样工作。 –

+0

@polleyg嗨,我们遇到同样的问题,只是我们的应用程序是用C#构建的。我可以问一下你每秒要传送多少条记录到BQ,每秒还有多少条请求? – foxwendy

+0

我们正在做大约10K p/s –

相关问题