我正在Google App Engine中编写推特应用。它接受命令作为直接消息,因此我设置了第三方cronjob服务来调用定期处理DM的处理程序。我有一个只有一个条目的模型'信息',它存储了一些常用数据,这些数据在应用程序的许多地方使用(在这种情况下,是最近处理消息的时间)。我的处理程序的一般模式是这样的:
class Info(db.Model):
msg_polled = db.DateTimeProperty(auto_now_add = True)
.... More Properties ....
@classmethod
def get_info(cls):
info = cls.all().get()
if not info:
info = cls()
info.put()
return info
---------------------------------------------------------
info = Info.get_info()
msgs = api.GetDirectMessages(since = info.msg_polled)
if not msgs:
return
logging.info('Processing Messages since %s ' % str(info.msg_polled))
for msg in msgs:
...process commands...
logging.info('Processed Message :- @%s : %s' % (msg.sender_screen_name, msg.text))
info.msg_polled = datetime.datetime.now()
info.put()
但有时候我会得到这样的日志:
I 03-30 07:50AM 10.973
Processing Messages since Sun, 29 Mar 2009 11:41:59 GMT
I 03-30 07:50AM 11.122
Processed Message :- @foo : Foo_Bar
-------------------------------------------------------
I 03-30 07:46AM 08.014
Processing Messages since Sun, 29 Mar 2009 11:41:59 GMT
I 03-30 07:46AM 08.130
Processed Message :- @foo : Foo_Bar
在这里,似乎信息没有被提交到数据库。消息被多次处理,有时在msg_polled值更改之前最多10次。但我没有得到任何数据存储区例外。这种情况偶尔会发生一次。
感谢任何帮助。
答案 0 :(得分:0)
Google AppEngine数据存储区使用BigTable,这是一个分布式数据库系统。因此,更新可能不会立即可见,因为新数据尚未到达每个分布式表(Amazon在其SimpleDB中称之为“最终一致性”)。几分钟后你应该没事。
答案 1 :(得分:0)
以下是有关GAE数据存储一致性的良好文档:
结论:
最终一致性是非关系数据库的基本要素,允许开发人员在可伸缩性,性能和一致性之间找到最佳平衡。了解如何在最终和强一致性之间取得平衡,为您的应用程序设计最佳数据模型非常重要。在Google Cloud Datastore中,使用实体组和祖先查询是保证实体范围内的强一致性的最佳方式。如果由于前面描述的限制,您的应用程序无法合并实体组,您可以考虑其他选项,例如使用仅键查询或Memcache。对于大型应用程序,应用最佳实践,例如使用分散ID和减少索引以减少一致性所需的时间。将Google Cloud Datastore与BigQuery结合使用以满足复杂查询的业务需求并尽可能减少Google Cloud Datastore索引的使用情况也很重要。