Memcache在Google App Engine中限制为1 MB

时间:2011-02-22 17:20:00

标签: google-app-engine memcached

如何在memcache中存储大小超过1 MB的对象?有没有办法将其拆分,但仍然可以使用相同的密钥访问数据?

5 个答案:

答案 0 :(得分:8)

我使用以下模块(“blobcache”)在GAE的内存缓存中存储大小超过1Mb的值。

import pickle
import random
from google.appengine.api import memcache


MEMCACHE_MAX_ITEM_SIZE = 900 * 1024


def delete(key):
  chunk_keys = memcache.get(key)
  if chunk_keys is None:
    return False
  chunk_keys.append(key)
  memcache.delete_multi(chunk_keys)
  return True


def set(key, value):
  pickled_value = pickle.dumps(value)

  # delete previous entity with the given key
  # in order to conserve available memcache space.
  delete(key)

  pickled_value_size = len(pickled_value)
  chunk_keys = []
  for pos in range(0, pickled_value_size, MEMCACHE_MAX_ITEM_SIZE):
    # TODO: use memcache.set_multi() for speedup, but don't forget
    # about batch operation size limit (32Mb currently).
    chunk = pickled_value[pos:pos + chunk_size]

    # the pos is used for reliable distinction between chunk keys.
    # the random suffix is used as a counter-measure for distinction
    # between different values, which can be simultaneously written
    # under the same key.
    chunk_key = '%s%d%d' % (key, pos, random.getrandbits(31))

    is_success = memcache.set(chunk_key, chunk)
    if not is_success:
      return False
    chunk_keys.append(chunk_key)
  return memcache.set(key, chunk_keys)


def get(key):
  chunk_keys = memcache.get(key)
  if chunk_keys is None:
    return None
  chunks = []
  for chunk_key in chunk_keys:
    # TODO: use memcache.get_multi() for speedup.
    # Don't forget about the batch operation size limit (currently 32Mb).
    chunk = memcache.get(chunk_key)
    if chunk is None:
      return None
    chunks.append(chunk)
  pickled_value = ''.join(chunks)
  try:
    return pickle.loads(pickled_value)
  except Exception:
    return None

答案 1 :(得分:2)

有memcache方法set_multiget_multi,它们将字典和前缀作为参数。

如果您可以将数据拆分成块的字典,可以使用它。基本上,前缀将成为您的新密钥名称。

你必须以某种方式跟踪块的名称。此外,任何时候都可以从memcache中删除任何块,所以你还需要一些方法来重建部分数据。

答案 2 :(得分:0)

将大量数据存储到内存缓存中的最佳方法是将其拆分为块并使用set_multiget_multi来有效地存储和检索数据。

但请注意,某些部分可能会从缓存中删除而其他部分可能会保留。

您还可以通过将数据存储在全局变量中来缓存应用程序实例中的数据,但这不太理想,因为它不会跨实例共享,更有可能消失。

GAE roadmap上支持从应用程序内容上传到blobstore,您可能需要留意这一点,以及与Google存储集成。

答案 3 :(得分:0)

正如其他人提到的,你可以同时从memcache addretrieve多个值。有趣的是,虽然应用引擎blog says这些批量操作最多可以处理32mb,但official documentation still says限制为1mb。所以一定要测试一下,也许会让谷歌更新他们的文档。并且还要记住,你的一些块可能会在其他人之前从memcache中逐出。

我建议谷歌搜索python compress string并考虑在将对象发送到memcache之前对其进行序列化和压缩。

您可能还想询问this guy what he means是否允许他在memcache中存储更大的对象。

答案 4 :(得分:0)

一个很好的解决方法是使用layer_cache.py,这是一个在Khan Academy(开源)编写和使用的python类。基本上,它是内存缓存(cachepy模块)与memcache的组合,用作通过实例同步内存缓存的方式。 find the source here并阅读Ben Kamens博客文章here