我尝试使用AppEngine对一个大的(ish)数据集实现一个summary视图。在
我的模型看起来像:
def TxRecord(db.Model):
expense_type = db.StringProperty()
amount = db.IntegerProperty()
def ExpenseType(db.Model):
name = db.StringProperty()
total = db.IntegerProperty()
我的数据存储包含TxRecord
的100K个实例,我想用expense_type
来总结这些实例。在
在sql中,它类似于:
^{pr2}$我当前所做的是使用Python MapReduce framework来迭代所有的{
def generate_expense_type(rec):
expense_type = type.get_or_insert(name, name = rec.expense_type)
expense_type.total += rec.amount
yield op.db.Put(expense_type)
这似乎是可行的,但我觉得我必须使用1的shard_count
来运行它,以确保总数不会被并发写入覆盖。在
有没有一个策略可以让我用AppEngine来解决这个问题呢?在
使用mapreduce是正确的方法。正如David建议的那样,计数器是一种选择,但它们并不可靠(它们使用memcache),而且它们也不是为大量并行的计数器而设计的。在
当前的mapreduce有两个问题:首先,
get_or_insert
每次调用它时都会执行一个数据存储事务。其次,更新事务外部的金额,并第二次异步存储它,从而产生您所关心的并发问题。在至少在完全支持reduce之前,最好的选择是在事务中在映射器中执行整个更新,如下所示:
使用MapReduce框架是个好主意。如果使用MapReduce框架提供的计数器,则可以使用多个shard。因此,不必每次修改数据存储,您可以执行以下操作:
在MapReduce完成后(希望比只使用一个shard时快得多),然后可以将完成的计数器复制到数据存储实体中。在
MapReduce非常适合离线处理数据,我喜欢David处理计数器的解决方案(+1 upvote)。在
我只想提一下另一个选择:在数据进来时对其进行处理。看看Brett Slatkin在IO 2010中的High Throughput Data Pipelines on App Engine演讲。在
我已经在一个简单的框架(slagg)中实现了该技术,您可能会发现我的grouping with date rollup useful示例。在
相关问题 更多 >
编程相关推荐