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

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

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

Ответ 1

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

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

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

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

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

Ответ 2

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

Thrift = сериализация + стек RPC

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

ASN.1 = Grand daddy

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

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

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

Общие

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

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

Некоторые результаты и живой проект для воспроизведения с

Этот проект (https://github.com/sidshetye/SerializersCompare) сравнивает важные сериализаторы в мире С#. У людей 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 заключается в том, что ist предназначен для спецификации не для реализации. Поэтому очень хорошо скрывать/игнорировать детали реализации на любом "реальном" языке программирования.

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

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

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

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

Ответ 4

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

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

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

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

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

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

Результаты измерений

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

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

Ответ 5

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

Немногие ресурсы по облигациям выглядят следующим образом (https://news.ycombinator.com/item?id=8866694, https://news.ycombinator.com/item?id=8866848, https://microsoft.github.io/bond/why_bond.html)

Ответ 6

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

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

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

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