【发布时间】:2011-06-12 08:17:32
【问题描述】:
这是我每天都会在我的应用程序日志中看到的常见异常,通常每天 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 使用预定义的 default 队列添加到 deferred 工作人员,您可能知道,该队列的吞吐率为每秒五个任务调用。
在具有六个属性(两个索引)的实体上,我认为使用受延迟任务速率限制调节的 transactions 可以让我避免数据存储超时,但是查看日志,这个错误仍然每天都出现。
我存储的这个计数器不是很重要,所以我不担心会出现这些超时;无论如何,我很好奇为什么即使以每秒 5 个任务的低速率,Google App Engine 也无法正确处理此任务,如果降低速率可能是一种可能的解决方案。
在每个问题上使用sharded counter 以避免超时对我来说太过分了。
编辑:
我已将默认队列上的速率限制设置为每秒 1 个任务;我仍然遇到同样的错误。
【问题讨论】:
-
延迟任务在任何意义上都不会比常规任务“更轻”,只是它们更容易编写。在引擎盖下,它们是通过常规处理程序实现的。无论如何,这不会影响事务本身的开销。
标签: google-app-engine timeout google-cloud-datastore deferred