пятница, 26 апреля 2013 г.

[prog] Презентация Thrift vs Protobuf vs Avro

Нашел вот такую презентацию. Считаю ее весьма интересной для того, чтобы утащить к себе и показать интересующимся:

Речь идет о системах сериализации Apache Thrift, Google Protocol Buffers, Apache Avro.

Данная тема волнует меня из-за того, что в свое время я писал что-то подобное. Это был мой проект ObjESSty, который до сих пор активно используется в наших C++ных разработках. И недавно Николай Шмаков даже очень серьезно модернизировал эту разработку, так что она стала еще лучше ;)

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

Во-первых, двоичная сериализация крутится всего лишь вокруг двух принципиально разных подходов. Содержимое двоичного представления может либо помечаться тегами (т.е. каждому значению предшествует тег, который определяет смысл значения), либо же поля имеют жестко зафиксированный порядок следования. Поэтому о том, какой смысл имеет значение, нужно судить по порядковому номеру значения. Так вот Thrift/Protobuf, а так же их прадедушка ASN.1 BER (он же, в простонародье, TLV -- Tag, Length, Value), используют теговую идентификацию полей. Причем значения тегов у них нужно задавать явно. Тогда как ObjESSty и его прадедушка ASN.1 PER базируются на строгом порядке следования полей объекта. Соответственно, каждый подход имеет разные взгляды на то, как должна поддерживаться эволюция схемы сериализуемых данных. Но это уже совсем другая история... (если кому-то интересно, то можно оставить свой голос в комментариях и, если таковые будут, я постараюсь раскрыть эту тему подробнее)

Во-вторых, ObjESSty изначально затачивался на поддержку объектно-ориентированного подхода. Поэтому, например, в ObjESSty есть поддержка наследования сериализуемых типов. Это может казаться не очень полезным, но на практике бывает необходимо объявить, например, базовые классы Request или Response, или Failure, от которых будут произведены десятки/сотни конкретных или промежуточных классов.

В-третьих, в ObjESSty используется совсем другой подход к работе с языком описания данных, нежели в Thrift, Protobuf или ASN.1. В ObjESSty программист сначала сам описывает C++ класс, объекты которого он хочет сериализовать, а затем уже делает отображение полей этого класса в DDL-описание (Data Definition Language). Тогда как в Thrift/Protobuf/ASN.1 код C++ класса полностью генерируется из .thrift/.proto/.asn1-файла. Подход ObjESSty позволяет легко добавлять в сериализуемые классы любые несериализуемые поля и любые методы. Может это и звучит странно, но на практике такое бывает удобно и полезно.

В-четвертых, в ObjESSty "из коробки" делалась поддержка контейнеров из стандартной библиотеки C++98/03: string, vector, set, multiset, map, multimap, deque, list. А так же объектов, на которые идет ссылка через указатель (и здесь таки очень полезным оказывается поддержка наследования, т.к. можно иметь атрибут типа "указатель на базовый тип", но хранить в нем указатель на объект производного типа; именно этот объект и будет сериализован/десериализован). Ну и еще в качестве приятного бонуса в ObjESSty можно указывать для атрибутов условия, при которых атрибут имеет смысл сериализовать. А так же значение по умолчанию для атрибута, если он не был сериализован. Но это совсем уже мелочи... ;)

Ну, а если вернуться к упомянутой выше презентации, то очень жаль, что в ней не упомянуты ASN.1 BER и PER. Хоть это и вымирающие нонче динозавры, но это классика, которую очень полезно было бы знать, если уж берешься говорить о системах сериализации данных :( Хотя это, вероятно, уже старческое брюзжание...

Комментариев нет: