这是我每天在应用程序日志中遇到的常见异常,通常每天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.
引发上述异常的函数如下:
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)
基本上,store_printed_question
功能检查先前是否打印过一个给定的问题,在这种情况下递增一个事务中的相关计数器。
WebHandler
工作人员使用预定义的 deferred 队列将此函数添加到{{1}},正如您所知,该队列的吞吐率为五个任务调用每秒。
在具有六个属性(两个索引)的实体上,我认为使用由延迟任务速率限制调节的default将允许我避免数据存储区超时,但是,查看日志,此错误仍然每天出现。
我存储的这个计数器并不是那么重要,所以我并不担心得到这些超时;无论如何,我很好奇为什么Google App Engine无法正常处理这项任务,即使是每秒5个任务的低速率,如果降低速率可能是一个可能的解决方案。
每个问题transactions以避免超时对我来说都是一种矫枉过正的行为。
修改
我在默认队列上将速率限制设置为每秒1个任务;我仍然遇到同样的错误。
答案 0 :(得分:8)
查询只能存活30秒。有关使用游标破解查询的示例代码,请参阅我对this question的回答。
答案 1 :(得分:7)
一般来说,像这样的超时通常是因为write contention。如果你有一个事务正在进行并且你正在同时向同一个实体组写一堆东西,你会遇到写争用问题(optimistic concurrency的副作用)。在大多数情况下,如果您将entity group缩小,通常会将此问题降至最低。
在您的特定情况下,基于上面的代码,很可能是因为您应该使用sharded counter来避免堆叠序列化写入。
另一个不太可能的可能性(这里仅提到完整性)是您的数据所在的平板电脑是being moved。