Google App Engine超时:数据存储区操作超时,或者数据暂时不可用

sys*_*out 11 google-app-engine timeout deferred google-cloud-datastore

这是我每天在我的应用程序日志中获得的常见异常,通常每天5/6次,每天访问量为1K:

db error trying to store stats
Traceback (most recent call last):
  File "/base/data/home/apps/stackprinter/1b.347728306076327132/app/utility/worker.py", line 36, in deferred_store_print_statistics
    dbcounter.increment()
  File "/base/data/home/apps/stackprinter/1b.347728306076327132/app/db/counter.py", line 28, in increment
    db.run_in_transaction(txn)
  File "/base/python_runtime/python_lib/versions/1/google/appengine/api/datastore.py", line 1981, in RunInTransaction
    DEFAULT_TRANSACTION_RETRIES, function, *args, **kwargs)
  File "/base/python_runtime/python_lib/versions/1/google/appengine/api/datastore.py", line 2067, in RunInTransactionCustomRetries
    ok, result = _DoOneTry(new_connection, function, args, kwargs)
  File "/base/python_runtime/python_lib/versions/1/google/appengine/api/datastore.py", line 2105, in _DoOneTry
    if new_connection.commit():
  File "/base/python_runtime/python_lib/versions/1/google/appengine/datastore/datastore_rpc.py", line 1585, in commit
    return rpc.get_result()
  File "/base/python_runtime/python_lib/versions/1/google/appengine/api/apiproxy_stub_map.py", line 530, in get_result
    return self.__get_result_hook(self)
  File "/base/python_runtime/python_lib/versions/1/google/appengine/datastore/datastore_rpc.py", line 1613, in __commit_hook
    raise _ToDatastoreError(err)
Timeout: The datastore operation timed out, or the data was temporarily unavailable.
Run Code Online (Sandbox Code Playgroud)

引发上述异常的函数如下:

def store_printed_question(question_id, service, title):
    def _store_TX():
        entity = Question.get_by_key_name(key_names = '%s_%s' % \
                                         (question_id, service ) )
        if entity:
            entity.counter = entity.counter + 1                
            entity.put()
        else:
            Question(key_name = '%s_%s' % (question_id, service ),\ 
                          question_id ,\
                          service,\ 
                          title,\ 
                          counter = 1).put()
    db.run_in_transaction(_store_TX)
Run Code Online (Sandbox Code Playgroud)

基本上,store_printed_question函数检查先前是否打印了给定问题,在这种情况下递增单个事务中的相关计数器.使用预定义的默认队列,
a将此函数添加WebHandler延迟的工作队列,正如您所知,该队列的吞吐率为每秒五次任务调用.

在具有六个属性(两个索引)的实体上,我认为使用 由延迟任务速率限制调节的事务将允许我避免数据存储区超时,但是,查看日志,此错误仍然每天出现.

我存储的这个计数器并不是那么重要,所以我并不担心得到这些超时; 无论如何,我很好奇为什么谷歌应用引擎即使以每秒5个任务的低速率也无法正确处理这项任务,如果降低速率可能是一个可能的解决方案.
一个分片计数器上的每个问题,以避免超时将是一个矫枉过正我.

编辑:
我已在默认队列上将速率限制设置为每秒1个任务; 我仍然得到同样的错误.

pha*_*ann 9

查询只能存活30秒.有关使用游标破解查询的示例代码,请参阅我对此问题的回答.


Bob*_*man 7

一般来说,这样的超时通常是因为写入争用.如果你有一个事务正在进行并且你正在同时向同一个实体组写一堆东西,你会遇到写争用问题(乐观并发的副作用).在大多数情况下,如果您将实体组缩小,通常会最大限度地减少此问题.

在您的特定情况下,基于上面的代码,很可能是因为您应该使用分片计数器来避免堆叠序列化写入.

另一个不太可能的可能性(这里仅提到完整性)是您的数据正在移动的平板电脑.