Каков наилучший метод сериализации для объектов в memcached? - PullRequest
24 голосов
/ 01 февраля 2009

Мое приложение Python в настоящее время использует python-memcached API для установки и получения объектов в memcached. Этот API-интерфейс использует собственный модуль Python pickle для сериализации и десериализации объектов Python.

Этот API-интерфейс упрощает и ускоряет хранение вложенных списков Python, словарей и кортежей в memcached, а чтение этих объектов обратно в приложение полностью прозрачно - оно просто работает.

Но я не хочу этого делать ограничено использованием исключительно Python, и если все объекты memcached сериализованы с помощью pickle, то клиенты, написанные на других языках, работать не будут.

Вот варианты кросс-платформенной сериализации, которые я рассмотрел:

  1. XML - главное преимущество в том, что он удобочитаем, но это не важно в этом приложении. XML также занимает много места, и его анализ очень дорогой.

  2. JSON - кажется хорошим кроссплатформенным стандартом, но я не уверен, что он сохраняет характер типов объектов при чтении из memcached. Например, согласно этот пост кортежи преобразуются в списки при использовании simplejson ; Кроме того, кажется, что добавление элементов в структуру JSON может нарушить код, написанный в старой структуре

  3. Буферы протокола Google - я действительно заинтересован в этом, потому что он кажется очень быстрым и компактным - по крайней мере, в 10 раз меньше и быстрее, чем XML; это не читается человеком, но это не важно для этого приложения; и, похоже, он предназначен для поддержки роста структуры без разрушения старого кода

Учитывая приоритеты этого приложения, какой метод сериализации объектов идеально подходит для memcached?

  1. Кроссплатформенная поддержка (Python, Java, C #, C ++, Ruby, Perl)

  2. Обработка вложенных структур данных

  3. Быстрая сериализация / десериализация

  4. Минимальный объем памяти

  5. Гибкость для изменения структуры без нарушения старого кода

Ответы [ 5 ]

7 голосов
/ 19 февраля 2009

Одним из основных соображений является "Вы хотите указать каждое определение структуры" ?

Если вы согласны с этим, вы можете взглянуть на:

  1. Буферы протокола - http://code.google.com/apis/protocolbuffers/docs/overview.html
  2. Комиссионные - http://developers.facebook.com/thrift/ (больше ориентированы на услуги)

Для обоих этих решений требуются файлы поддержки для определения каждой структуры данных.


Если вы предпочитаете не брать на себя лишние затраты разработчиков на предварительное определение каждой структуры, взгляните на:

  1. JSON (через Python CJSON и нативный PHP JSON). И то, и другое действительно очень быстро, если вам не нужно передавать двоичный контент (например, изображения и т. Д.).
  2. Еще один язык разметки @ http://www.yaml.org/. Также очень быстро, если вы получите нужную библиотеку.

Однако я считаю, что у них обоих были проблемы с передачей двоичного контента, поэтому они были исключены для нашего использования. Примечание: YAML может иметь хорошую двоичную поддержку, вам придется проверить клиентские библиотеки - см. Здесь: http://yaml.org/type/binary.html


В нашей компании мы выпустили собственную библиотеку (Extruct) для межязыковой сериализации с поддержкой двоичных файлов. В настоящее время у нас есть (прилично) быстрые реализации на Python и PHP, хотя они не очень удобочитаемы из-за использования base64 во всех строках (двоичная поддержка). Со временем мы перенесем их на C и будем использовать более стандартную кодировку.

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

Если вы хотите увидеть реализацию Extruct, пожалуйста, дайте мне знать. (контактная информация на http://blog.gahooa.com/ под "О себе")

7 голосов
/ 01 марта 2009

Я попробовал несколько методов и остановился на сжатом JSON как на лучшем балансе между скоростью и объемом памяти. Собственная функция Pickle в Python немного быстрее, но полученные объекты нельзя использовать с не-Python клиентами.

Я вижу сжатие 3: 1, поэтому все данные помещаются в memcache, и приложение получает время отклика менее 10 мс, включая отрисовку страницы.

Вот сравнение JSON, Thrift, Protocol Buffers и YAML, с и без сжатия:

http://bouncybouncy.net/ramblings/posts/more_on_json_vs_thrift_and_protocol_buffers/

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

2 голосов
/ 16 сентября 2010

Вас может заинтересовать эта ссылка:

http://kbyanc.blogspot.com/2007/07/python-serializer-benchmarks.html

Альтернатива: MessagePack, похоже, самый быстрый сериализатор. Может быть, вы можете попробовать.

2 голосов
/ 01 февраля 2009

«Кроссплатформенная поддержка (Python, Java, C #, C ++, Ruby, Perl)»

Жаль, что этот критерий первый. Целью большинства языков является выражение фундаментальных структур данных и обработка по-разному. Вот что делает несколько языков «проблемой»: все они разные.

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

JSON прекрасно соответствует остальным критериям. Сообщения компактны и быстро разбираются (в отличие от XML). Вложенность обрабатывается красиво. Изменение структуры без нарушения кода всегда сомнительно - если вы удалите что-то, старый код сломается. Если вы измените что-то, что требовалось, старый код сломается. Однако если вы добавляете что-то, JSON справится и с этим.

Мне нравится читать человека. Это помогает в устранении неполадок и устранении неполадок.

Тонкость превращения кортежей Python в списки не является интересной проблемой. Принимающее приложение уже знает полученную структуру и может настроить ее (если это имеет значение.)


Редактировать по производительности.

Парсинг документов XML и JSON из http://developers.de/blogs/damir_dobric/archive/2008/12/27/performance-comparison-soap-vs-json-wcf-implementation.aspx

xmlParse 0.326 jsonParse 0,255

JSON выглядит значительно быстрее для того же контента. Я использовал модули Python SimpleJSON и ElementTree в Python 2.5.2.

1 голос
/ 17 февраля 2012

Гессиан отвечает всем вашим требованиям. Здесь есть библиотека Python:

https://github.com/bgilmore/mustaine

Официальную документацию по протоколу можно найти здесь:

http://hessian.caucho.com/

Я регулярно использую его как на Java, так и на Python. Это работает и не требует написания файлов определения протокола. Я не могу сказать вам, как работает сериализатор Python, но версия Java достаточно эффективна:

https://github.com/eishay/jvm-serializers/wiki/

...