避免Memcache“1000000字节长度”限制值

时间:2012-02-03 11:31:32

标签: google-app-engine memcached

我的模型有不同的实体,我想像公司的员工一样计算。为了避免一次又一次地进行相同的查询,计算出的列表保存在Memcache中(持续时间= 1天)。问题是应用程序有时会给我一个错误,即Memcache中存储的字节数多于允许的数量: / p>

Values may not be more than 1000000 bytes in length; received 1071339 bytes

存储一个对象列表,你应该用Memcache做什么?如果是这样,避免上述错误的最佳做法是什么?我正在拉1000个物体。你是否将值限制为< 200?在内存中检查对象的大小似乎不是一个好主意,因为它们可能在进入Memcache之前被处理(序列化或类似的东西)。

4 个答案:

答案 0 :(得分:29)

大卫,你没有说你使用哪种语言,但在Python中你可以做同样的事情,因为易卜拉欣建议使用泡菜。您需要做的就是编写两个小助手函数来读取和写入大型对象到memcache。这是一个(未经测试的)草图:

def store(key, value, chunksize=950000):
  serialized = pickle.dumps(value, 2)
  values = {}
  for i in xrange(0, len(serialized), chunksize):
    values['%s.%s' % (key, i//chunksize)] = serialized[i : i+chunksize]
  return memcache.set_multi(values)

def retrieve(key):
  result = memcache.get_multi(['%s.%s' % (key, i) for i in xrange(32)])
  serialized = ''.join([v for k, v in sorted(result.items()) if v is not None])
  return pickle.loads(serialized)

答案 1 :(得分:9)

我经常在memcache上存储大小为几兆字节的对象。我不能评论这是否是一个好的做法,但我的意见是,有时我们只需要一种相对快速的方式在我们的应用引擎实例之间传输兆字节的数据。

由于我使用Java,我所做的是使用Java的序列化程序序列化我的原始对象,生成一个序列化的字节数组。由于序列化对象的大小现在已知,我可以切成800 KB字节数组的块。然后我将字节数组封装在容器对象中,并存储该对象而不是原始对象。

每个容器对象都可以有一个指向下一个memcache键的指针,我可以在其中获取下一个字节数组块,如果没有需要从memcache中获取的块,则返回null。 (就像链接列表一样)然后我将字节数组块重新合并为一个大字节数组,并使用Java的反序列化器对其进行反序列化。

答案 2 :(得分:5)

您是否始终需要访问您存储的所有数据?如果没有,那么您将受益于对数据集进行分区并仅访问您需要的部分数据。

如果您显示1000名员工的列表,您可能会对其进行分页。如果你分页那么你绝对可以分区。

您可以制作两个数据集列表:一个打火机只有最重要的信息,可以容纳1 MB,另一个列表分成几个部分,包含完整的信息。在灯光列表中,您将能够应用最重要的操作,例如通过员工姓名或分页进行过滤。然后当需要加载重型数据集时,您将只能加载您真正需要的部分。

但这些建议需要时间来实施。如果您可以使用当前的设计,那么只需将您的列表分成大约300个项目或任何数字是安全的并加载它们并合并。

答案 3 :(得分:3)

如果您知道对象的大小,可以使用memcached选项来允许更大的对象:

memcached -I 10m

这将允许最多10MB的对象。