В чем основные различия между Apache Thrift, Google Protocol Buffers, MessagePack, ASN.1 и Apache Avro?


124

Все они обеспечивают двоичную сериализацию, структуры RPC и IDL. Меня интересуют ключевые различия между ними и характеристики (производительность, простота использования, поддержка языков программирования).

Если вы знаете какие-либо другие подобные технологии, укажите это в ответе.



@Zenikoder: Эта ссылка не содержит информации о 2 из 5 запрошенных форматов.
ТОЛЬКО МОЕ ПРАВИЛЬНОЕ МНЕНИЕ

может ли это помочь: slideshare.net/IgorAnishchenko/pb-vs-thrift-vs-avro ?
Thoroc 01

2
для тех, кто не знает RPC - Remote Prodecure Call, IDL - Interface Definition language
garg10may

Ответы:


97

ASN.1 - это стандарт ISO / ISE. Он имеет очень читаемый исходный язык и множество бэкэндов, как двоичных, так и удобочитаемых. Исходный язык является международным стандартом (и к тому же старым!), Исходный язык немного неаккуратен (примерно так же, как Атлантический океан немного влажный), но он очень хорошо определен и имеет приличную поддержку. , (Вероятно, вы можете найти библиотеку ASN.1 для любого языка, который вы называете, если вы достаточно усердно копаете, а если нет, есть хорошие библиотеки языка C, которые вы можете использовать в FFI.) Это стандартизованный язык, одержимо документированный и также есть несколько хороших руководств.

Экономия - это не стандарт. Первоначально он был создан Facebook, позже был открыт с открытым исходным кодом и в настоящее время является проектом Apache верхнего уровня. Это плохо документировано - особенно уровни обучения - и, на мой (правда, краткий) взгляд, кажется, не добавляет ничего, чего не делали другие, предыдущие усилия (а в некоторых случаях и лучше). Честно говоря, он имеет довольно внушительное количество языков, которые он поддерживает из коробки, включая несколько высокопрофильных, неосновных. IDL также отдаленно похож на C.

Буферы протокола не являются стандартом. Это продукт Google, доступный широкому сообществу. Он немного ограничен с точки зрения языков, поддерживаемых из коробки (он поддерживает только C ++, Python и Java), но у него есть много сторонней поддержки для других языков (с очень переменным качеством). Google выполняет практически всю свою работу, используя буферы протоколов, так что это проверенный в боевых условиях протокол (хотя и не такой боевой, как ASN.1. Документация у него гораздо лучше, чем у Thrift, но, будучи Продукт Google, скорее всего, будет нестабильным (в смысле постоянно меняющегося, а не в смысле ненадежного). IDL также похож на C.

Все вышеперечисленные системы используют схему, определенную в некотором виде IDL, для генерации кода для целевого языка, который затем используется при кодировании и декодировании. Авро нет. Типизация Avro является динамической, и ее данные схемы используются непосредственно во время выполнения как для кодирования, так и для декодирования (что имеет некоторые очевидные затраты на обработку, но также имеет некоторые очевидные преимущества по сравнению с динамическими языками и отсутствие необходимости в типах тегов и т. Д.) , В его схеме используется JSON, что упрощает управление поддержкой Avro на новом языке, если уже существует библиотека JSON. Опять же, как и большинство систем описания протоколов, заново изобретающих колесо, Avro также не стандартизирован.

Лично, несмотря на мои отношения любви / ненависти к нему, я бы, вероятно, использовал ASN.1 для большинства целей RPC и передачи сообщений, хотя на самом деле у него нет стека RPC (вам нужно было бы его создать, но IOC делают это достаточно просто).


3
Спасибо за подробное объяснение. Но как насчет управления версиями, я слышал, что protobuf может с этим справиться, как насчет других библиотек и как их можно использовать в целом? Кроме того, похоже, что у Avro теперь есть IDL с синтаксисом, подобным C, в дополнение к JSON.
andreypopp 08

2
ASN.1 поддерживает управление версиями вручную с помощью ...маркеров расширения или автоматически с помощью EXTENSIBILITY IMPLIEDзаголовка модуля. Буферы протокола, IIRC, поддерживают ручное управление версиями. Я не знаю, поддерживает ли он что-нибудь вроде подразумеваемой расширяемости (и мне лень искать это). Thrift также поддерживает некоторое управление версиями, но опять же мне кажется, что это ручной процесс без подразумеваемой расширяемости.
ТОЛЬКО МОЕ ПРАВИЛЬНОЕ МНЕНИЕ

7
Для записи Protocol Buffers всегда явно кодирует поля числами, и на уровне библиотеки никогда не возникает ошибки, если есть дополнительные поля, а отсутствующие поля не являются ошибкой, если они помечены как необязательные или явные. Таким образом, все сообщения буферов протокола имеют EXTENSIBILITY IMPLIED.
Кевин Кэткарт

под МОК - вы имеете в виду инверсию управления? что бы использовать для стека RPC в PHP, что-то вроде расширения XML-RPC? или нужно было бы что-то написать самостоятельно?
Stann

4
Avro более гибкий, потому что он позволяет либо динамически работать с определенной схемой, либо генерировать стандартные классы. По моему опыту, он очень мощный: его сила заключается в богатом наборе функций, включая генератор RPC (это обычная функция для Thrift).
Паоло Мареска

38

Мы только что провели внутреннее исследование сериализаторов, вот некоторые результаты (для моей справки в будущем!)

Бережливость = сериализация + стек RPC

Самая большая разница в том, что Thrift - это не просто протокол сериализации, это полноценный стек RPC, похожий на современный стек SOAP. Таким образом, после сериализации объекты можно (но не обязательно) пересылать между машинами через TCP / IP. В SOAP вы начали с документа WSDL, который полностью описывает доступные службы (удаленные методы) и ожидаемые аргументы / объекты. Эти объекты были отправлены через XML. В Thrift файл .thrift полностью описывает доступные методы, ожидаемые объекты параметров, и объекты сериализуются с помощью одного из доступных сериализаторов ( Compact Protocolнаиболее популярным в производстве является эффективный двоичный протокол).

ASN.1 = дедушка

ASN.1 был разработан специалистами в области телекоммуникаций в 80-х годах и неудобен в использовании из-за ограниченной поддержки библиотек по сравнению с недавними сериализаторами, созданными людьми из CompSci. Существует два варианта: кодирование DER (двоичное) и кодирование PEM (ascii). Оба они быстры, но DER быстрее и эффективнее по размеру. Фактически, ASN.1 DER может легко поддерживать (а иногда и превосходить) сериализаторы, которые были разработаны 30 лет назад.после себя, свидетельство его хорошо спроектированного дизайна. Он очень компактен, меньше, чем Protocol Buffers и Thrift, уступает только Avro. Проблема в том, что нужно поддерживать отличные библиотеки, и сейчас Bouncy Castle кажется лучшим для C # / Java. ASN.1 является королем в системах безопасности и криптографии и никуда не денется, поэтому не беспокойтесь о «будущей проверке». Просто купи хорошую библиотеку ...

MessagePack = середина пакета

Это неплохо, но не самое быстрое, не самое маленькое и не самое поддерживаемое. Нет причин для выбора.

общий

Кроме того, они довольно похожи. Большинство из них - варианты основного TLV: Type-Length-Valueпринципа.

Буферы протоколов (из Google), Avro (из Apache, используются в Hadoop), Thrift (из Facebook, теперь проект Apache) и ASN.1 (из Telecom) - все они включают определенный уровень генерации кода, на котором вы сначала выражаете свои данные в сериализаторе. -специфический формат, то "компилятор" сериализатора сгенерирует исходный код для вашего языка через code-genэтап. Источник вашего приложения затем использует этиcode-gen классы для ввода-вывода. Обратите внимание, что некоторые реализации (например, библиотека Avro от Microsoft или ProtoBuf.NET от Marc Gavel) позволяют напрямую украшать объекты POCO / POJO на уровне приложения, а затем библиотека напрямую использует эти декорированные классы вместо классов любого генератора кода. Мы видели, что это предложение повышает производительность, поскольку устраняет этап копирования объекта (от полей POCO / POJO уровня приложения до полей генерации кода).

Некоторые результаты и живой проект, с которым можно поиграть

В этом проекте ( https://github.com/sidshetye/SerializersCompare ) сравниваются важные сериализаторы в мире C #. У разработчиков Java уже есть нечто подобное .

1000 iterations per serializer, average times listed
Sorting result by size
Name                Bytes  Time (ms)
------------------------------------
Avro (cheating)       133     0.0142
Avro                  133     0.0568
Avro MSFT             141     0.0051
Thrift (cheating)     148     0.0069
Thrift                148     0.1470
ProtoBuf              155     0.0077
MessagePack           230     0.0296
ServiceStackJSV       258     0.0159
Json.NET BSON         286     0.0381
ServiceStackJson      290     0.0164
Json.NET              290     0.0333
XmlSerializer         571     0.1025
Binary Formatter      748     0.0344

Options: (T)est, (R)esults, s(O)rt order, (S)erializer output, (D)eserializer output (in JSON form), (E)xit

Serialized via ASN.1 DER encoding to 148 bytes in 0.0674ms (hacked experiment!)

3
ASN.1 также имеет BER (базовые правила кодирования), PER (упакованные правила кодирования) и XER (правила кодирования XML). DER - это вариант BER, который используется в основном для криптографии, поскольку он гарантирует уникальное кодирование для каждого элемента данных. И BER, и PER могут быть более эффективными, чем DER. Большинство библиотек обрабатывают DER. Некоторые не обрабатывают все конструкции BER правильно. Для тех, кто хочет узнать больше: luca.ntop.org/Teaching/Appunti/asn1.html
Джо Стил,

Он также имеет JER - правила кодирования объектной нотации JavaScript. Вы также можете определить свои собственные правила кодирования с помощью ECN (Encoding Control Notation). Хороший список спецификаций со ссылками для скачивания: oss.com/asn1/resources/standards-define-asn1.html
Дмитрий

There are two variants, DER (binary) encoding and PEM (ascii) encoding, Имейте в виду, что PEM - это просто двоичные данные в кодировке base-64 внутри комментариев BEGIN END. Эти двоичные данные могли быть сгенерированы с использованием кодировки DER, поэтому странно сравнивать PEM и DER.
RafalS

14

В дополнение к перспективе производительности, Uber недавно оценил несколько из этих библиотек в своем инженерном блоге:

https://eng.uber.com/trip-data-squeeze/

Победитель для них? MessagePack + zlib для сжатия

Нашей целью было найти комбинацию протокола кодирования и алгоритма сжатия с наиболее компактным результатом при максимальной скорости. Мы протестировали комбинации протокола кодирования и алгоритма сжатия на 2219 псевдослучайных анонимных поездках из Uber Нью-Йорка (помещенных в текстовый файл как JSON).

Урок здесь в том, что от ваших требований зависит, какая библиотека вам подойдет. Для Uber они не могли использовать протокол на основе IDL из-за бессхемной природы передачи сообщений. Это устранило кучу вариантов. Также для них важно не только время необработанного кодирования / декодирования, но и размер данных в состоянии покоя.

Размер Результаты

Размер Результаты

Скорость Результаты

введите описание изображения здесь


13

Одна большая особенность ASN.1 заключается в том, что он предназначен для спецификации, а не для реализации. Поэтому он очень хорошо скрывает / игнорирует детали реализации на любом «реальном» языке программирования.

Его задача ASN.1-Compiler - применить правила кодирования к asn1-файлу и сгенерировать из них обоих исполняемый код. Правила кодирования могут быть указаны в нотации кодирования (ECN) или могут быть одними из стандартизованных, таких как BER / DER, PER, XER / EXER. То есть ASN.1 - это типы и структуры, правила кодирования определяют кодировку по проводам, и, наконец, что не менее важно, компилятор передает ее на ваш язык программирования.

Насколько мне известно, бесплатные компиляторы поддерживают C, C ++, C #, Java и Erlang. Коммерческие компиляторы (очень дорогие и имеющие патенты / лицензии) очень универсальны, обычно абсолютно актуальны и поддерживают иногда даже больше языков, но посмотрите их сайты (OSS Nokalva, Marben и т. Д.).

На удивление легко указать интерфейс между сторонами совершенно разных культур программирования (например, «встроенные» люди и «фермеры-серверы»), используя следующие методы: файл asn.1, правило кодирования, например BER, и, например, диаграмма взаимодействия UML. , Не парься, как это реализовано, пусть каждый пользуется «своим делом»! Для меня это сработало очень хорошо. Между прочим: На сайте OSS Nokalva вы можете найти как минимум две бесплатные для скачивания книги об ASN.1 (одну Лармута, другую Дюбюиссона).

ИМХО, большинство других продуктов пытаются только быть еще одними-генераторами-заглушками RPC, накачивая много воздуха в проблему сериализации. Что ж, если кому-то это нужно, с ним все будет в порядке. Но для меня они выглядят как переизобретения Sun-RPC (из конца 80-х), но, эй, это тоже отлично работало.


7

Microsoft Bond ( https://github.com/Microsoft/bond ) очень впечатляет производительностью, функциями и документацией. Однако на данный момент (13 февраля 2015 г.) он не поддерживает многие целевые платформы. Я могу только предположить, что это потому, что он очень новый. в настоящее время он поддерживает Python, C # и C ++. Он используется MS везде. Я пробовал это, для меня как разработчика C # использование bond лучше, чем использование protobuf, однако я также использовал бережливость, единственная проблема, с которой я столкнулся, была с документацией, мне пришлось попробовать много вещей, чтобы понять, как все делается.

Некоторые ресурсы по Bond следующие ( https://news.ycombinator.com/item?id=8866694 , https://news.ycombinator.com/item?id=8866848 , https://microsoft.github.io/ bond / why_bond.html )


5

Для производительности одна точка данных - это jvm-сериализаторы - это тест - это довольно специфические небольшие сообщения, но они могут помочь, если вы работаете на платформе Java. Я думаю, что производительность в целом часто не является самым важным отличием. Также: НИКОГДА не принимайте слова авторов как евангелие; многие рекламируемые утверждения являются поддельными (например, на сайте msgpack есть несколько сомнительных заявлений; это может быть быстро, но информация очень отрывочная, вариант использования не очень реалистичен).

Одно большое различие заключается в том, должна ли использоваться схема (PB, по крайней мере, Thrift; Avro может быть необязательным; ASN.1, я также думаю; MsgPack, не обязательно).

Также: на мой взгляд, хорошо иметь возможность использовать многоуровневую модульную конструкцию; то есть уровень RPC не должен диктовать формат данных, сериализацию. К сожалению, у большинства кандидатов все это тесно связано.

Наконец, при выборе формата данных в настоящее время производительность не исключает использования текстовых форматов. Существуют невероятно быстрые парсеры JSON (и довольно быстрые потоковые парсеры xml); а при рассмотрении возможности взаимодействия языков сценариев и простоты использования двоичные форматы и протоколы могут быть не лучшим выбором.


Спасибо за то, что поделились опытом, но я думаю, что мне все еще нужен двоичный формат (у меня действительно огромный объем данных) и, вероятно, буду придерживаться Avro.
andreypopp

Тогда да, может иметь смысл. Вы можете использовать сжатие с любой скоростью, независимо от используемого формата (LZF хорош, так как он очень быстро сжимает / распаковывает по сравнению с gzip / deflate).
StaxMan
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.