5

我正在通过pydrive使用 Google Drive API在两个 Google Drive 帐户之间移动文件。我一直在测试一个包含 16 个文件的文件夹。我的代码总是在第六个文件中引发错误

"超出用户速率限制">

我知道请求的数量是有限制的(10/s 或 1000/100s),但我已经尝试了 Google Drive API 建议的指数退避来处理这个错误。即使在 248 秒之后,它仍然会引发相同的错误。

这是我在做什么的例子

def MoveToFolder(self,files,folder_id,drive):
    total_files = len(files)
    for cont in range(total_files):
        success = False
        n=0
        while not success:
            try:
                drive.auth.service.files().copy(fileId=files[cont]['id'],
                                                body={"parents": [{"kind": "drive#fileLink", "id": folder_id}]}).execute()
                time.sleep(random.randint(0,1000)/1000)
                success = True
            except:
                wait = (2**n) + (random.randint(0,1000)/1000)
                time.sleep(wait)
                success = False
                n += 1

我尝试使用“批处理请求”来复制文件,但它会为 10 个文件引发相同的错误。

def MoveToFolderBatch(self,files,folder_id,drive):
    cont=0
    batch = drive.auth.service.new_batch_http_request()
    for file in files:
        cont+=1
        batch.add(drive.auth.service.files().copy(fileId=file['id'],
                                                 body={"parents": [
                                                     {"kind": "drive#fileLink", "id": folder_id}]}))
    batch.execute()

有没有人有任何提示?

编辑:根据谷歌支持:

关于您的用户速率限制超出错误,与控制台中设置的每用户速率限制完全无关。相反,它来自 Drive API 所依赖的内部 Google 系统,并且最有可能在单个帐户拥有域中的所有文件时发生。我们不建议单个帐户拥有所有文件,而是让域中的个人用户拥有文件。对于传输文件,您可以查看此链接。另外,请检查此链接的建议以避免错误。

4

2 回答 2

2

403: User Rate Limit Exceeded基本上是防洪。

{
 "error": {
  "errors": [
   {
    "domain": "usageLimits",
    "reason": "userRateLimitExceeded",
    "message": "User Rate Limit Exceeded"
   }
  ],
  "code": 403,
  "message": "User Rate Limit Exceeded"
 }
}

你需要放慢速度。像您所做的那样实施指数退避是正确的做法。

谷歌在计算请求方面并不完美,所以你自己计算它们并没有真正的帮助。有时您可以一秒钟获得 15 个请求而侥幸逃脱,而有时您只能获得 7 个请求。

您还应该记住,如果服务器上的负载很大,您正在与使用服务器的其他人一起完成您的请求,其中一个请求可能需要更长的时间,而另一个请求可能不会。不要在大多数人设置 cron 作业以进行提取的时间运行。

注意:如果您转到已启用驱动器 API 的 google 开发人员控制台,请点击配额选项卡旁边的铅笔图标

每个用户每 100 秒的查询次数

每 100 秒的查询次数

你可以同时增加它们。一种是基于用户的,另一种是基于项目的。每个用户可以在 100 秒内发出 X 个请求,您的项目每 100 秒可以发出 Y 个请求。

在此处输入图像描述

注意:不知道你可以设置多高。这是我的开发帐户,所以它可能有一些我不记得的 beta 访问权限。

于 2017-03-02T14:25:18.800 回答
2

每秒仅插入 1 次后查看 403 速率限制,有时插入的 403 速率限制会成功

关键点是:-

  • 退避但不实施指数退避!. 这只会扼杀您的应用程序吞吐量

  • 相反,您需要主动限制您的请求以避免 304 的发生。在我的测试中,我发现最大可持续吞吐量约为每 1.5 秒 1 个事务。

  • 批处理使问题变得更糟,因为批处理是在 304 出现之前解包的。IE。一批 10 被解释为 10 笔快速交易,而不是 1 笔。

试试这个算法

delay=0                              // start with no backoff
while (haveFilesInUploadQueue) {
   sleep(delay)                      // backoff 
   upload(file)                      // try the upload
   if (403 Rate Limit) {             // if rejected with a rate limit
      delay += 2s                    // add 2s to delay to guarantee the next attempt will be OK
   } else {
      removeFileFromQueue(file)      // if not rejected, mark file as done
      if (delay > 0) {               // if we are currently backing off
         delay -= 0.2s               // reduce the backoff delay
      }
   }
}
// You can play with the 2s and 0.2s to optimise throughput. The key is to do all you can to avoid the 403's 

需要注意的一件事是,Drive 存在(是?)一个错误,有时上传会被 403 拒绝,但是,尽管发送了 403,Drive 会继续创建文件。症状将是重复的文件。因此,为了更加安全,在 403 之后,您应该以某种方式检查文件是否确实存在。最简单的方法是使用预先分配的 ID,或者将您自己的不透明 ID 添加到属性中。

于 2017-03-02T17:47:56.247 回答