今天早上,我的GAE应用程序生成了几个错误日志:“对这些数据存储区实体的争用太多了。请再试一次。”在我看来,只有当多个请求尝试修改相同实体或相同实体组中的实体时,才会发生此类错误。
当我收到此错误时,我的代码正在插入新实体。我糊涂了。这是否意味着我们创建新实体的速度有限制?
我的模型定义和调用序列代码如下所示:
# model defnition
class ExternalAPIStats(ndb.Model):
uid = ndb.StringProperty()
api = ndb.StringProperty()
start_at = ndb.DateTimeProperty(auto_now_add=True)
end_at = ndb.DateTimeProperty()
# calling sequence
stats = ExternalAPIStats(userid=current_uid, api="eapi:hr:get_by_id", start_at=start_at, end_at=end_at)
stats.put() # **too much contention** happen here
这对我来说很神秘。我想知道如何处理这个问题。如果有任何建议,请告诉我。
答案 0 :(得分:12)
没有看到调用是如何进行的(你显示调用代码但调用的次数,通过循环或许多页面同时调用相同的put)但我相信问题可以更好地解释here 。特别是
如果您使用单调递增的索引属性(如时间戳)以高速创建新实体,也会看到此问题,因为这些属性是Bigtable中索引表中行的键。
以'start_at'为罪魁祸首。这个article更详细地解释了。
可能(虽然未经测试)尝试分批进行投注。你在'start_at'字段上运行查询吗?如果不删除其索引也将解决问题。
如何调用看跌期权(即上面我在循环中询问的内容,多页调用)?有了它,可能更容易缩小问题范围。
答案 1 :(得分:6)
以下是您需要了解的有关数据存储区争用以及如何避免它的所有信息:
https://developers.google.com/appengine/articles/scaling/contention?hl=en
希望有所帮助