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

Какой лучший метод сериализации для объектов в memcached?

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

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

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

Ниже перечислены варианты межплатформенной сериализации:

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

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

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

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

  • Поддержка кросс-платформенных (Python, Java, С#, С++, Ruby, Perl)

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

  • Быстрая сериализация/де-сериализация

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

  • Гибкость для изменения структуры без разбивки старого кода
4b9b3361

Ответ 1

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

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

Здесь сравнение JSON, Thrift, протокольных буферов и YAML с сжатием и без него:

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

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

Ответ 2

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

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

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


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

  • JSON (через python cjson и собственный PHP json). Оба действительно очень быстры, если вам не нужно передавать двоичный контент (например, изображения и т.д.).
  • Еще один язык разметки @http://www.yaml.org/. Также очень быстро, если вы получите нужную библиотеку.

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


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

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

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

Ответ 3

"Поддержка кросс-платформенных (Python, Java, С#, С++, Ruby, Perl)"

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

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

JSON удовлетворяет всем остальным критериям. Сообщения компактны и быстро анализируются (в отличие от XML). Вложение прекрасно обрабатывается. Изменение структуры без разрыва кода всегда iffy - если вы удалите что-то, старый код сломается. Если вы измените что-то, что требуется, старый код сломается. Однако, если вы добавляете вещи, 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.

Ответ 5

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

https://github.com/bgilmore/mustaine

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

http://hessian.caucho.com/

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

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