我需要大容量加载表中的所有实体。(对于高速按需图遍历算法,它们需要在内存中,而不是根据需要加载。)
为了提高加载速度,我需要将其并行化。因此,我想在并行线程中运行多个查询,每个查询从数据库中提取大约800个实体。
QuerySplitter可以达到这个目的,但我们在Flexible Environment上运行,因此使用Appengine SDK而不是客户端库。
已经提到了MapReduce,但这并不是为了将简单的数据加载到内存中。Memcache在某种程度上是相关的,但对于高速访问,我需要在我自己的应用程序JVM的RAM中的密集网络中的所有这些对象。
MultiQueryBuilder可能会这样做。它在并行运行查询部分时提供了并行性。
无论使用这三种方法中的哪一种,还是其他方法,最困难的部分是定义过滤器或其他形式的溢出,将表(Kind)大致划分为800个左右实体的块?我会创建过滤器,说"对象1到800","801到1600,…",但我知道这是不切实际的。那么,一个人是如何做到的呢?
我通过将实体划分为随机组来解决类似的问题。
我为每个数据存储实体添加了一个float属性,并在每次保存实体时为其分配一个介于0和1之间的随机数。然后,当启动N
线程来处理各种数据存储实体时,我让每个线程处理实体的1/N
查询。例如,线程0将处理其随机属性设置在0
和1/N
之间的所有实体。线程2将处理其随机属性在1/N
和2/N
之间的所有实体,等等。
这样做的缺点是它不是完全确定的,您需要向数据存储实体添加一个新属性。好处是,它可以轻松地扩展到数百万个实体和线程,并且通常可以在线程之间均匀地分配工作。