Memcache 1 МБ ограничение в Google App Engine - PullRequest
4 голосов
/ 22 февраля 2011

Как вы сохраняете объект размером более 1 МБ в memcache? Есть ли способ разделить его, но при этом данные будут по-прежнему доступны с тем же ключом?

Ответы [ 5 ]

8 голосов
/ 20 марта 2011

Я использую следующий модуль («blobcache») для хранения значений с размерами более 1 МБ в memcache GAE.

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
2 голосов
/ 22 февраля 2011

Существуют методы memcache set_multi и get_multi , которые принимают словарь и префикс в качестве аргументов.

Если бы вы могли разбить ваши данные на словарь, вы можете использовать это.По сути, префикс станет вашим новым именем ключа.

Вам придется каким-то образом отслеживать имена фрагментов.Кроме того, ЛЮБОЙ из кусков может быть удален из memcache в любое время, так что вам также нужно каким-то образом восстановить частичные данные.

0 голосов
/ 17 мая 2014

Хороший обходной путь - использовать layer_cache.py, класс python, написанный и используемый в Khan Academy (с открытым исходным кодом). По сути, это комбинация кеша в памяти (модуля cachepy) с memcache, который используется для синхронизации кеша в памяти через экземпляры. найдите источник здесь и прочитайте сообщение в блоге Бена Каменса об этом здесь .

0 голосов
/ 23 февраля 2011

Как уже упоминали другие парни, вы можете добавить и получить несколько значений из memcache одновременно.Интересно, что хотя блог приложения сообщает, что эти массовые операции могут обрабатывать до 32 МБ, в официальной документации все еще говорится, что они ограничены 1 МБ.Так что определенно проверьте это, и, возможно, приставите к Google об обновлении их документации.Также имейте в виду, что некоторые ваши чанки могут быть исключены из memcache раньше других.

Я бы порекомендовал поискать в Google python compress string и подумать о сериализации и сжатии вашего объекта перед отправкой его в memcache.

Вы также можете спросить этого парня, что он имеет в виду о наличии расширения, которое позволяет ему хранить большие объекты в memcache.

0 голосов
/ 23 февраля 2011

Лучший способ сохранить большой блок данных в memcache - разделить его на куски и использовать set_multi и get_multi для эффективного хранения и извлечения данных.

Но имейте в виду, что некоторые части могут удаляться из кэша, а другие остаются.

Вы также можете кэшировать данные в экземпляре приложения, сохраняя его в глобальной переменной, но этоменее идеален, так как он не будет распространяться между экземплярами и с большей вероятностью исчезнет.

Поддержка загрузки в хранилище BLOB-объектов из приложения в дорожной карте GAE , вы можете захотетьследите за этим, а также за интеграцией с Google Storage.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...