Подтвердить что ты не робот

Избегание ограничения по меткам "1000000 байт в длину" по значениям

В моей модели есть разные сущности, которые я бы хотел рассчитать как сотрудники компании. Чтобы избежать повторения одного и того же запроса, вычисленный список сохраняется в Memcache (duration = 1day). Проблема в том, что приложение иногда дает мне ошибку, что в Memcache хранится больше байтов, чем это допустимо:

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

Сохраняет ли список объектов что-то, что вы должны делать с Memcache? Если да, то какие рекомендации лучше избегать ошибки выше? В настоящее время я набираю 1000 объектов. Ограничиваете ли вы значения < 200? Проверка размера объекта в памяти не кажется слишком хорошей идеей, потому что они, вероятно, обрабатываются (сериализованы или что-то в этом роде) перед тем, как войти в Memcache.

4b9b3361

Ответ 1

Дэвид, вы не говорите, какой язык вы используете, но в 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)

Ответ 2

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

Поскольку я использую Java, то я сделал сериализацию своих необработанных объектов с помощью сериализатора Java, создавая сериализованный массив байтов. Поскольку размер сериализованного объекта теперь известен, я мог бы разрезать куски массивов байтов размером 800 Кбайт. Затем я инкапсулирую массив байтов в объект-контейнер и сохраняю этот объект вместо необработанных объектов.

Каждый объект-контейнер может иметь указатель на следующий ключ memcache, где я мог бы получить следующий массив байтов массива, или null, если больше нет кусков, которые необходимо извлечь из memcache. (т.е. точно так же, как связанный список), я затем повторно объединяю куски массивов байтов в большой массив байтов и десериализую его с помощью десериализатора Java.

Ответ 3

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

Если вы показываете список из 1000 сотрудников, вы, вероятно, собираетесь его разбивать на страницы. Если вы разбиты на страницы, то вы определенно можете разделить.

Вы можете создать два списка своего набора данных: один ярче с самой важной информацией, которая может вписаться в 1 МБ и другой список, который разделен на несколько частей с полной информацией. В светом списке вы сможете применить наиболее важные операции, например, фильтрацию через имя сотрудника или разбивку на страницы. И тогда при необходимости загрузите тяжелый набор данных, вы сможете загружать только те части, которые вам действительно нужны.

Но эти рекомендации требуют времени для реализации. Если вы можете жить с вашим текущим дизайном, тогда просто разделите свой список на куски ~ 300 единиц или любой номер в безопасности и загрузите их все и слейте.

Ответ 4

Если вы знаете, насколько велики будут объекты, вы можете использовать опцию memcached, чтобы разрешить большие объекты:

memcached -I 10m

Это позволит создавать объекты размером до 10 МБ.