2013-03-20 1 views
8

Требование: Объекты Python с 2-3 уровнями вложенности, содержащими базовые типы данных, такие как целые числа, строки, списки и диктофоны. (нет дат и т. Д.), Необходимо сохранить как json в redis против ключа. Каковы наилучшие методы сжатия json в качестве строки для небольшого объема памяти. Объекты-мишени не очень большие, в среднем 1000 маленьких элементов, или около 15000 символов при преобразовании в JSON.Каков наилучший способ сжать json для хранения в хранилище на основе памяти, например redis или memcache?

например.

>>> my_dict 
{'details': {'1': {'age': 13, 'name': 'dhruv'}, '2': {'age': 15, 'name': 'Matt'}}, 'members': ['1', '2']} 
>>> json.dumps(my_dict) 
'{"details": {"1": {"age": 13, "name": "dhruv"}, "2": {"age": 15, "name": "Matt"}}, "members": ["1", "2"]}' 
### SOME BASIC COMPACTION ### 
>>> json.dumps(my_dict, separators=(',',':')) 
'{"details":{"1":{"age":13,"name":"dhruv"},"2":{"age":15,"name":"Matt"}},"members":["1","2"]}' 

1/Существуют ли какие-либо другие лучшие способы сжатия JSON, чтобы сохранить память в Redis (также обеспечивая легкий вес декодирования впоследствии).

2/Насколько хорошим кандидатом будет msgpack [http://msgpack.org/]?

3/Должен ли я рассматривать такие варианты, как рассол?

+1

Каковы требования вашего приложения? вам нужна производительность? надежность, согласованность и т. д.? Вы могли бы рассмотреть альтернативы redis? – drekyn

ответ

8

В качестве компрессора мы используем только gzip.

import gzip 
import cStringIO 

def decompressStringToFile(value, outputFile): 
    """ 
    decompress the given string value (which must be valid compressed gzip 
    data) and write the result in the given open file. 
    """ 
    stream = cStringIO.StringIO(value) 
    decompressor = gzip.GzipFile(fileobj=stream, mode='r') 
    while True: # until EOF 
    chunk = decompressor.read(8192) 
    if not chunk: 
     decompressor.close() 
     outputFile.close() 
     return 
    outputFile.write(chunk) 

def compressFileToString(inputFile): 
    """ 
    read the given open file, compress the data and return it as string. 
    """ 
    stream = cStringIO.StringIO() 
    compressor = gzip.GzipFile(fileobj=stream, mode='w') 
    while True: # until EOF 
    chunk = inputFile.read(8192) 
    if not chunk: # EOF? 
     compressor.close() 
     return stream.getvalue() 
    compressor.write(chunk) 

В нашей публикации мы сохраняем результат как файлы, как вы можете себе представить. Чтобы использовать только строки в памяти, вы можете использовать объект cStringIO.StringIO() в качестве замены для файла.

0

Другой возможностью было бы использовать формат хранения MongoDB, BSON.

Вы можете найти две реализации python на странице реализации на этом сайте.

Редактировать: почему бы не просто сохранить словарь и преобразовать в json при поиске?

+0

Я не думаю, что BSON можно добавить как значение для ключа в redis. – DhruvPathak

+0

@DhruvPathak см. Мое редактирование – Ivo

+2

@DhruvPathak уверен, что может, почему бы и нет? У Redis нет мнения о том, что вы храните в ключе. –

2

Одним из простых способов «почтового процесса» является создание карты «короткого ключа» и запуск сгенерированного json через это до хранения, а затем (обратное) перед де-сериализацией объекта. Например:

Before: {"details":{"1":{"age":13,"name":"dhruv"},"2":{"age":15,"name":"Matt"}},"members":["1","2"]} 
Map: details:d, age:a, name:n, members:m 
Result: {"d":{"1":{"a":13,"n":"dhruv"},"2":{"a":15,"n":"Matt"}},"m":["1","2"]} 

Просто пройти через JSON и заменить кнопочная> значение на пути к базе данных, и ценностно> на пути к применению.

Вы также можете использовать gzip для дополнительной добра (после этого не будет ни одной строки).

1

Если вы хотите, чтобы это было быстро, try lz4. Если вы хотите, чтобы он лучше сжался, go for lzma.

Есть ли еще какие-либо другие способы сжатия json для сохранения памяти в redis (также обеспечивающий легкий декодирование после этого)?

Насколько хорошим кандидатом будет msgpack [http://msgpack.org/]?

Msgpack относительно быстр и имеет меньшую площадь памяти. Но ujson, как правило, быстрее для меня. Вы должны сравнить их по своим данным, измерить скорость сжатия и декомпрессии и коэффициент сжатия.

Должен ли я рассматривать такие варианты, как рассол?

Рассмотрите как маринованные (cPickle in partucular), так и маршал. Они быстры. Но помните, что они не защищены или масштабируемы, и вы платите за скорость с дополнительной ответственностью.

 Смежные вопросы

  • Нет связанных вопросов^_^