Java 如何并行更新400000个GAE数据存储实体?
我有400000个特定类型的实体,我想对每个实体执行一个简单的操作(添加一个属性)。我无法连续处理它们,因为这将花费很长时间。我不想使用MapReduce库,因为它既复杂又令人难以理解 基本上,我想在taskqueue上创建100个任务,每个任务占用约4000个实体的一段,并对每个实体执行此操作。希望在所有任务并行执行时,处理所有400k实体所需的时间不会超过几分钟 但是,我不知道如何使用GAE查询来实现这一点。我的实体具有由我的应用程序生成的格式为“230498234 com.example”的字符串ID。我希望每个任务基本上都要求数据存储类似“请给我实体200000到204000”,然后逐个操作它们Java 如何并行更新400000个GAE数据存储实体?,java,google-app-engine,parallel-processing,google-cloud-datastore,Java,Google App Engine,Parallel Processing,Google Cloud Datastore,我有400000个特定类型的实体,我想对每个实体执行一个简单的操作(添加一个属性)。我无法连续处理它们,因为这将花费很长时间。我不想使用MapReduce库,因为它既复杂又令人难以理解 基本上,我想在taskqueue上创建100个任务,每个任务占用约4000个实体的一段,并对每个实体执行此操作。希望在所有任务并行执行时,处理所有400k实体所需的时间不会超过几分钟 但是,我不知道如何使用GAE查询来实现这一点。我的实体具有由我的应用程序生成的格式为“230498234 com.example”
这可能吗?如何以这种方式划分数据存储?读取速度快,写入速度慢。除非您可以执行有效的查询来分割数据(提示:不要使用偏移分页,因为appengine将为每个页面遍历索引到您的页面,请改用查询游标),否则请使用单个后端执行单个查询,并将要处理的数据发送到任务队列。例如,每个可以处理100。 这里的优点是,您不需要对数据进行分段,也不需要任何复杂的设置,只需要启动一个后端,该后端在读取单个查询时创建任务队列。新的appengine模块可能比标准后端实例更容易(因为它们不会随机停止)
如果您想使其真正健壮,请使用pagesize=elements的查询游标来处理每个任务队列,并记住创建任务队列的最后一个游标。如果后端在完成之前停止,请重新启动它,它将在停止的位置重新启动。这是MapReduce()的完美工作。刚开始学习可能很难,但一旦掌握了,你就会爱上它
您还可以考虑在下一次保存条目时懒惰地添加属性,前提是该属性与查询中的缺省值相同。
< P>任务主机可以对任务队列执行查询和后游标(使用‘结束游标’),每个队列对应于1K结果,而不是获取结果。请注意,不能保证在游标上执行时工作人员将看到完全相同的查询结果,但这可能已经足够好了。有更多保证的另一种方法是在任务主机上执行仅键搜索,并实际获取结果(键),然后将1000个组发布到任务队列。工作人员可以使用multiget来检索具有更强一致性保证的项目。我第一次使用mapreduce几乎就是这样。我必须在我的图像模型中添加一个属性,我是这样做的: 在mapreduce.yaml中mapreduce:
- name: cleanimages
mapper:
input_reader: mapreduce.input_readers.DatastoreInputReader
handler: main.process
params:
- name: entity_kind
default: main.Image
然后,您将希望发生的事情放入过程中
code:
def process(entity):
entity.small = None
yield op.db.Put(entity)
在本例中,我只是将其中一个变量设置为None,因为它不再被使用,但是您可以将任意代码放在那里,创建一个新属性并像abose一样保存实体。你可以在网站上找到更多信息。他说:“我不想使用MapReduce库,因为它很复杂,而且非常复杂。”如果他只是想这样做,这可能是真的。此外,mapreduce仍然要求您能够高效地并行处理您的数据。他可能对mapreduce的看法是错误的,我认为这正是他所寻找的。您可以控制映射器的数量以及每个并行任务中的用户数量。当我必须向已经创建了数百万个实体的模型添加新属性时,使用
default
value可以节省我的时间。谢谢你的朋友。比固定的光标大小更好的是使用开始和结束光标。这样,如果在范围内添加了某些内容,那么工作人员就不会错过应该处理的最后一项。然而,普通查询在数据上的一致性很弱,如果这还不够,最好通过队列传递密钥,并让工作人员使用multiget,正如我在下面所说的。