在datastore中使用最终一致性读取
2010 4 1 01:21 PM 2227次查看
分类:Google App Engine 标签:Google App Engine, Python
在SDK 1.3.2发布时曾提到了强一致性和最终一致性读取,但是没有讲述细节,而这篇文章则阐述了其区别。
默认情况下,datastore是在一个主存储区域进行更新和查询的,这个区域代表最新的数据,访问这个区域则表示使用强一致性。而主存储区域有可能变得暂时不可用(估计是并发数过多或硬件故障),这就会导致查询超时或失败。
而实际上datastore是分布式的,它还有很多副存储区域。这些副存储区域的数据比主存储区域晚几百毫秒至数秒,因而不是最新的。如果你的应用不需要这种强一致性,就可以在主存储区域不可用时,让datastore读取其他存储区域的副本,而这就称为最终一致性读取。
Datastore为了保证向下兼容性,仍然默认使用强一致性,并且在事务中是完全一致性的(即保证事务中所有读取在事务结束时都是最新的版本);但现在你可以使用最终一致性读取,对Python而言,方法就是在fetch或get时传递一个rpc对象:
rpc = db.create_rpc(deadline=5, read_policy=db.EVENTUAL_CONSISTENCY)
results = Employee.all().fetch(10, rpc=rpc)
值得注意的有3点:- rpc对象是不可重用的,每一次fetch都要传递一个新的rpc对象。
- deadline参数是超时设置,可以接受一个0~30秒之间的浮点数,这个参数可以让查询不至于影响整个handler超时。
- 还有一个callback参数,在rpc结束后就会被调用。
此外我发现put操作也可以带rpc参数,不过read_policy应该是无效的,主要是使用deadline和callback。
顺带一提,我还使用了asynctools,要支持新读取策略的话需要修改一下(import我就省略了,自己加吧;代码我是看Google的源码自己研究的,也不保证以后一直有效)。
先是datastore.py,create_rpc需要加个参数:
def create_rpc(deadline=None, callback=None, read_policy=STRONG_CONSISTENCY):
return DatastoreRPC('datastore_v3', deadline, callback, read_policy)
接着是__init__.py,DatastoreTask的__init__方法也加上read_policy参数:from google.appengine.api.datastore import DatastoreRPC
class DatastoreTask(RpcTask):
def __init__(self, deadline=None, callback=None, read_policy=STRONG_CONSISTENCY, **kw):
self._results = []
self._exception = []
rpc = datastore.create_rpc(deadline=deadline, callback=callback, read_policy=read_policy)
rpc.callback = self.rpc_callback(rpc, self._results, self.exception, callback=callback)
super(DatastoreTask, self).__init__(rpc, **kw)
最后在你自己的代码里,用这样的方法创建即可:QueryTask(query, limit=10, read_policy=EVENTUAL_CONSISTENCY)
2011年1月7日更新:
Google已经建议用db.create_config()函数取代db.create_rpc()了(实际上在访问数据库时,SDK会自动将rpc对象转换成config对象),接口基本是一致的,但是config对象可以重用,而rpc对象不可重用。
0条评论 你不来一发么↓