这个问题有三个部分:
我有一个应用程序,用户可以在其中创建其他用户可以在5分钟内更新的对象。5分钟后,对象超时并且无效。我将对象存储为实体。为了完成超时,我有一个每分钟运行一次的cron作业来清除过期的对象。
现在大多数时候,我没有任何活动对象。在这种情况下,mapreduce处理程序会检查它获得的实体,如果它不处于活动状态,则不执行任何操作,也不执行任何写入操作。然而,我的免费数据存储写入配额在大约7小时后就会从mapreduce调用中用完。根据我的粗略估计,仅仅运行mapreduce就可能导致120次写入/调用。(粗略计算,60次呼叫/小时*7小时=420次呼叫,50k操作限制/420次呼叫~120次写入/次呼叫)
Q1:有人能验证一下,仅仅运行mapreduce就触发了120次数据存储写入吗
为了解决这个问题,我在启动mapreduce:之前检查数据存储
def cronhandler():
count = model.all(keys_only=True).count(limit=1000)
if count:
shards = (count / 100) + 1;
from mapreduce import control
control.start_map("Timeout open objects",
"expire.maphandler",
"expire.OpenOrderInputReader",
{'entity_kind' : 'model'},
shard_count=shards)
return HttpResponse()
Q2:这是避免mapreduce引发的数据存储写入的最佳方法吗?有没有更好的方法来配置mapreduce以避免无关的写入?我在想,有了更好的自定义InputReader,这是可能的
Q3:我猜更多的碎片会导致更多来自mapreduce记账的无关数据存储写入。是否通过我需要适当写入的预期对象数量来限制碎片
如果您将对象保留在memcache上而不是数据存储上,该怎么办?我唯一担心的是,运行给定应用程序的所有实例之间的内存缓存是否一致,但如果一致,问题就有了一个非常巧妙的解决方案。
这并不能完全回答您的问题,但您能减少cron作业的频率吗?
与其在模型无效后立即删除模型,只需将其从用户看到的查询中删除即可。
例如:
import datetime
now = datetime.datetime.now(created_at)
five_minutes_ago = now - datetime.timedelta(minutes=5)
q = model.all()
q.filter('create_at >=', five_minutes_ago)
或者,如果你不想使用不等式滤波器,你可以使用基于五分钟块的==
。
然后,每隔一个小时左右运行一次cron,以清除不活动的模型。
这种方法的缺点是实体将通过只提取密钥的方式返回,在这种情况下,在将实体返回给用户之前,您需要验证它们是否仍然有效。
我认为我所做的是做事的最佳方式。看起来Mapreduce API使用数据存储来跟踪启动的作业并同步工人。默认情况下,API使用8个工人。减少工作程序的数量会减少数据存储写入的数量,但这也会降低壁时间性能。