Самые большие различия между буфером протокола и Thrift?

286

Каковы основные плюсы и минусы Apache Thrift против буферов протокола Google ?

Jonas
источник
4
В качестве примечания, Марк Грэвелл поддерживает библиотеку для работы с protobuf Googles, которая называется protobuf.net, и находится по адресу code.google.com/p/protobuf-net
RCIX,
5
Этому вопросу и некоторым из следующих ответов около 6 лет. Вероятно, многое изменилось с тех пор.
Алик Эльзин-килака

Ответы:

159

Они оба предлагают много одинаковых функций; Тем не менее, есть некоторые различия:

  • Thrift поддерживает «исключения»
  • У буферов протокола есть намного лучшая документация / примеры
  • Thrift имеет встроенный Setтип
  • Буферы протокола допускают «расширения» - вы можете расширять внешний протокол для добавления дополнительных полей, в то же время позволяя внешнему коду работать со значениями. В Thrift нет способа сделать это
  • Я считаю, что протокол буфера гораздо проще читать

По сути, они довольно эквивалентны (с тем, что буфер протокола немного более эффективен, чем я читал).

hazzen
источник
16
Эта презентация объясняет их хорошо, как и в 2013 году. Slideshare.net/IgorAnishchenko/pb-vs-thrift-vs-avro
BAR
13
Thrift поддерживает еще как 10 языков
Илия Саункин
1
Для некоторых языков вы можете добавить расширения. Например, Thrift генерирует частичные классы для C #, которые легко расширять. Однако это не общее правило, это правда.
JensG
Поддержка grpc 1.0 (proto3) mapтакже
KindDragon
85

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

  • Буферы протокола: Java, Android Java, C ++, Python, Ruby, C #, Go, Objective-C, Node.js
  • Экономия: Java, C ++, Python, Ruby, C #, Go, Objective-C, JavaScript, Node.js, Erlang, PHP, Perl, Haskell, Smalltalk, OCaml, Delphi, D, Haxe

Оба могут быть расширены для других платформ, но это привязки языков, доступные из коробки.

Майк Грей
источник
16
Protobuf имеет отличную поддержку ruby github.com/macks/ruby-protobuf и code.google.com/p/ruby-protobuf . Я использую protobuf из C # (3.5) и Ruby, C # сериализует данные, а когда требуется, десериализует Ruby и работает над задачей.
Брайан Байлиаш
6
code.google.com/p/protobuf/wiki/ThirdPartyAddOns содержит списки PHP, Ruby, Erlang, Perl, Haskell, C #, OCaml плюс Actiona Script, Common Lisp, Go, Lua, Mathlab, Visual Basic, Scala. Думал, что это все сторонние реализации.
Игорь Гатис,
Вы можете напрямую использовать файлы protobuf C ++ в цели c (как для iOS, так и для OS X), проверьте это qn
Tushar Koul
Я вижу, что code.google.com/p/protobuf-net часто упоминается как порт protobuf для C #, но это не совсем так. Одной из важных особенностей Protobuf и Thrift является определение внешней структуры, поэтому одно и то же определение может использоваться разными языками. Protobuf-net не поддерживает эту функцию, потому что он встраивает определение структуры в код C #.
Андрей Тиличко
@AndyT: Это спорно - это dependes на будь то преимущество , что определение структуры является ВНЕШНЕЕ для всех языков , которые вы хотите поддерживать. С помощью protobuf-net вы определяете свою структуру данных в C # и генерируете из нее файл .proto, который затем можно использовать для создания поддержки на других языках. Я считаю это преимуществом, так как я очень C # -центричен и нахожусь в процессе интеграции Android / Java с большим существующим приложением .Net. Поэтому я хочу продолжить рассматривать мои классы C # как определения окончательной структуры.
RenniePet
73

RPC - еще одно ключевое отличие. Thrift генерирует код для реализации RPC-клиентов и серверов, где буферные протоколы, по-видимому, в основном предназначены только для обмена данными.

Саидиму Апале
источник
9
Это не правда. Буферы протокола определяют API-интерфейс службы RPC, и есть несколько библиотек для реализации передачи сообщений.
Стивен
7
Я не говорил, что в Protobuf не определен RPC, просто кажется, что он не предназначен для этого, по крайней мере, не для внешнего выпуска, к которому у всех есть доступ. Прочитайте этот комментарий инженера Google здесь
saidimu apale
9
Что еще более важно, Thrift имеет встроенную поддержку RPC. В настоящее время Protobuf использует сторонние библиотеки, что означает меньше внимания, меньше тестирования и менее надежный код.
Алек Томас
2
Для меня это хороший момент о ProtoBuf. Если вам нужно только сериализоваться, вы не добавляете бесполезный код. И если в будущем вам нужно будет отправить его по RPC, нет проблем, он может работать. Я использую Netty для сети, а Protobuf просто отлично интегрирован, поэтому никаких проблем, никаких тестов и максимизации производительности.
Kikiwa
14
Фактически, Protobufs были разработаны с учетом RPC. Google только недавно открыл этот компонент - grpc.io
andybons,
57
  • Сериализированные объекты Protobuf примерно на 30% меньше, чем Thrift.
  • Большинство действий, которые вы можете выполнять с объектами protobuf (создание, сериализация, десериализация), выполняются намного медленнее, чем экономия, если вы не включите их.option optimize_for = SPEED .
  • Thrift имеет более богатые структуры данных (Карта, Набор)
  • API Protobuf выглядит чище, хотя сгенерированные классы упакованы как внутренние классы, что не так уж и приятно.
  • Перечисления Thrift не являются реальными перечислениями Java, то есть являются просто целыми числами. Protobuf имеет настоящие Java-перечисления.

Для более детального изучения различий ознакомьтесь с различиями исходного кода в этом проекте с открытым исходным кодом .

eishay
источник
1
Подсказка: было бы неплохо, если бы в качестве базовой линии использовался другой недвоичный формат (xml или json?). Не было хороших тестов, которые бы показывали общие тенденции - предполагается, что PB и Thrift более эффективны, но если и насколько, если это так, в основном остается открытым вопросом.
StaxMan
4
0,02 секунды ?! У меня нет такого свободного времени
Крис С
1
Теперь, когда Thrift имеет несколько протоколов (включая TCompactProtocol), я думаю, что первый пункт больше не применяется.
Янус Троелсен
13
Опция оптимизации для скорости теперь используется по умолчанию для буферов протокола ( code.google.com/apis/protocolbuffers/docs/proto.html )
Виллем
5
Получаем ли мы объекты на 30% меньше с установленным «optimize_for = speed»? Или это скомпрометировано?
Прашант Шарма
56

Как я уже сказал в теме «Базы протокола Thrift против протокола» :

Ссылаясь на сравнение Thrift против Protobuf против JSON :

Кроме того, есть множество интересных дополнительных инструментов, доступных для этих решений, которые могут решить. Вот примеры для Protobuf: Protobuf-wireshark , protobufeditor .

Гжегож Вежовецкий
источник
10
Теперь это полный круг. Вы опубликовали один и тот же ответ на три (похожих) вопроса, которые всегда ссылаются либо на, либо на. Я чувствую, что играю Зельду и пропустил знак.
ChrisR
+ ChrisR хе, я не могу вспомнить, как это случилось. Хотя было несколько схожих вопросов, возможно, мне следует создать три одинаковых структуры вместо цикла. Однажды ... Это очень старый вопрос, и теперь я отвечаю по телефону. Во всяком случае, спасибо за улов!
Гжегож Вежовецкий,
6
«Thrift идет с хорошим учебником» - как смешно. Это самый неполный урок, который я когда-либо видел. Как только вы захотите что-то сделать рядом с TSimpleServer, вы застреваете там
Marian Klühspies
У Thrift также есть плагин Wireshark: github.com/andrewcox/wireshark-with-thrift-plugin
CCoder
8

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

Мы решили не использовать крайнюю оптимизацию хранения (например, упаковывать маленькие целые числа в ASCII или использовать 7-битный формат продолжения) ради простоты и ясности в коде. Эти изменения могут быть легко сделаны, если и когда мы столкнемся с критичным к производительности вариантом использования, который требует их.

Кроме того, это может быть просто моим впечатлением, но протоколные буферы, кажется, имеют более толстые абстракции вокруг версионирования структуры. У Thrift есть поддержка версий, но чтобы это произошло, нужно приложить немало усилий.

Даниэль Спивак
источник
1
Почему тот факт, что Thrift признает, что он не настолько компактен, насколько это возможно, заставляет вас верить, что это протоколные буферы?
Майкл Миор
1
Буферы протокола используют целочисленное кодирование переменной длины как для значений, так и для идентификаторов полей. Таким образом, очень распространенным случаем отправки поля int с небольшим значением будет два байта, а не int16 и int32.
пул
«Буферы протокола используют целочисленное кодирование переменной длины» - так же, как и TCompactProtocol
JensG
8

Мне удалось добиться лучшей производительности с текстовым протоколом по сравнению с protobuff на python. Тем не менее, нет проверки типов или других необычных преобразований utf8 и т. Д., Которые предлагает protobuff.

Итак, если вам нужна сериализация / десериализация, то вы можете использовать что-то еще.

http://dhruvbird.blogspot.com/2010/05/protocol-buffers-vs-http.html

dhruvbird
источник
7

Одна очевидная вещь, еще не упомянутая, заключается в том, что они могут быть как за, так и против (и одинаковы для обоих), - это то, что они являются двоичными протоколами. Это обеспечивает более компактное представление и, возможно, более высокую производительность (плюсы), но с пониженной читабельностью (или, скорее, отладкой), что является недостатком.

Кроме того, оба имеют немного меньшую поддержку инструментов, чем стандартные форматы, такие как xml (и, возможно, даже json).

(РЕДАКТИРОВАТЬ) Вот интересное сравнение, которое учитывает различия в размерах и производительности, а также включает числа для некоторых других форматов (xml, json).

StaxMan
источник
3
Тривиально вывести буфер протокола в текстовое представление, которое гораздо более читабельно, чем XML: my_proto.DebugString (). Например, см. Code.google.com/apis/protocolbuffers/docs/overview.html
SuperElectric,
Конечно, то же самое для всех двоичных форматов - но это не делает их читаемыми как есть (отладка по проводам). Хуже того, для protobuf вам действительно требуется определение схемы, чтобы знать имена полей.
StaxMan
Thrift поддерживает разные, даже определяемые пользователем, протоколы. Вы можете использовать бинарный, компактный, JSON или что-то, что вы изобрели только на прошлой неделе.
JensG
6

И, согласно вики, среда выполнения Thrift не работает в Windows.


источник
5
Я успешно запускаю Thrift на Windows. Используйте форк Windows на github.com/aubonbeurre/thrift
Сергей Подобрий
20
Официальная ветка mainline теперь также имеет поддержку Windows.
Янус Троелсен
5
@dalle - Alex P добавил поддержку ускорения потоков в Thrift. Теперь это поток по умолчанию для Windows. * NIX по умолчанию использует pthreads. И чтобы подтвердить Janus T, Thrift теперь полностью поддерживает Windows.
Пмонт
21
Это устаревшая информация. Thrift отлично работает на Windows в течение долгого времени.
JensG
6

ProtocolBuffers быстрее.
Здесь есть хороший тест:
http://code.google.com/p/thrift-protobuf-compare/wiki/Benchmarking

Возможно, вы также захотите заглянуть в Avro, поскольку Avro еще быстрее.
У Microsoft есть пакет здесь:
http://www.nuget.org/packages/Microsoft.Hadoop.Avro

Кстати, самый быстрый, который я когда-либо видел, это Cap'nProto ;
Реализацию AC # можно найти в Github-репозитории Marc Gravell .

Стефан Штайгер
источник
4

Я думаю, что большинство из этих моментов упущено из основного факта, что Thrift является платформой RPC, которая, как оказалось, способна сериализовать данные, используя различные методы (двоичный, XML и т. Д.).

Протоколные буферы предназначены исключительно для сериализации, это не основа, как Thrift.

Бабра Каннингем
источник
3
Что вы подразумеваете под платформой RPC и чем она отличается от gRPC от protobuf ?
marcelocra
gRPC не упаковывается вместе с protobuf. Он был разработан как 10 лет спустя. Thrift поставляется с полной платформой RPC. Это было сделано вместе.
трилогия
3

С одной стороны, protobuf не является полной реализацией RPC. Для этого требуется что-то вроде gRPC.

gPRC очень медленный по сравнению с Thrift:

http://szelei.me/rpc-benchmark-part1/

трилогия
источник
0

Здесь есть несколько отличных моментов, и я собираюсь добавить еще один, если кто-то пересечет здесь путь.

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

PS: Посмотрите этот превосходный тестовый проект, в thekvsкотором сравниваются многие сериализаторы, включая thrift-binary, thrift-compact и protobuf: https://github.com/thekvs/cpp-serializers.

PS: есть еще один названный сериализатор, YASкоторый также предоставляет эту опцию, но он не требует схем, см. Ссылку выше.

Синапс
источник
0

Также важно отметить, что не все поддерживаемые языки совместимы с Thrift или Protobuf. На данный момент речь идет о реализации модулей в дополнение к базовой сериализации. Позаботьтесь о том, чтобы проверить эталоны для любого языка, который вы планируете использовать

JSON
источник