Выбор платформ сериализации - PullRequest
0 голосов
/ 03 марта 2020

Я читал о недостатках использования java сериализации и необходимости go для платформ сериализации. Существует так много фреймворков, как avro, parquet, thrift, protobuff.

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

Я хотел бы получить практический пример использования и сравнить / выбрать платформы сериализации на основе требований.

Может кто-нибудь помочь с этим топи c?

1 Ответ

0 голосов
/ 09 марта 2020

Есть много факторов для рассмотрения. Я проведу go через некоторые из важных.

0) Сначала схема или Код первый

Если у вас есть проект, который будет включать разные языки, Первые подходы к коду, вероятно, будут проблематичными c. Это очень хорошо иметь класс JAVA, который можно сериализовать, но это может быть неприятно, если его нужно десериализовать в C.

Как правило, я предпочитаю первые подходы схемы, на всякий случай.

1) Межобъектное разграничение

Некоторые сериализации создают поток байтов, который делает его можно увидеть, где один объект останавливается, а другой начинается. Других нет.

Итак, если у вас есть хранилище сообщений / данных, которое будет выделять для вас пакеты байтов, например, ZeroMQ, или поле базы данных, то вы можете использовать сериализацию, которая не размечает сообщения. Примеры включают в себя буфер протокола Google. С помощью разметки, выполняемой транспортным / хранилищем, читатель может получить пакет байтов, точно зная, что он охватывает один объект и только один объект.

Если ваше хранилище сообщений / данных не разделяется между пакетами байтов, например, сетевой поток или файл, то вы либо изобретаете свои собственные маркеры демаркации, либо используете сериализацию, которая укажет вам. Примеры включают ASN.1 BER, XML.

2) Канонический

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

Примеры канонических сериализаций включают ASN.1 BER, ASN.1 канонический PER, XML , Те, которые не включают ASN.1 uPER, возможно, Google Protocol Buffers (я могу ошибаться).

AVRO делает что-то другое - схема данных сама является частью сериализованных данных, поэтому всегда можно восстановить объект из произвольных данных. Как вы можете себе представить, библиотеки для этого несколько неуклюжи в таких языках, как C, но лучше в динамических c языках.

3) Ограничение размера и значения.

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

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

Это чрезвычайно полезно в больших проектах с гетерогенными свойствами (используется много разных языков), поскольку все источники правды о том, что является действительным, а что нет, исходит из схема, и только схема, и обеспечивается автоматически сгенерированным кодом. Разработчики не могут игнорировать / обойти ограничения, и когда ограничения меняются, все не могут не заметить.

Примеры включают ASN.1 (как правило, довольно хорошо выполняется с помощью наборов инструментов), XML (не часто выполняется должным образом с помощью бесплатных / дешевых наборов инструментов; MS xsd.exe намеренно игнорирует любые такие ограничения) и JSON ( вплоть до валидаторов объекта). Из этих трех ASN.1 имеет наиболее сложный синтаксис ограничений; это действительно очень мощно.

Примеры, которые этого не делают - Google Protocol Buffers. В этом отношении GPB чрезвычайно раздражает, потому что у него нет никаких ограничений вообще. Единственный способ иметь ограничения по значению и размеру - это записать их как комментарии в. Прото-файл и надеюсь, что разработчики прочитают их и обратят внимание, или какой-то другой подход, не основанный на исходном коде. Поскольку GPB очень сильно нацелен на гетерогенные системы (поддерживается буквально каждый язык под солнцем), я считаю это очень серьезным упущением, поскольку код проверки значения / размера должен быть написан вручную для каждого языка, используемого в проекте. Это пустая трата времени. Google может добавить синтаксические элементы в .proto и генераторы кода для поддержки этого, вообще не меняя проводные поля (все это в автоматически сгенерированном коде).

4) Двоичные / текстовые

Двоичные сериализации будут меньше, и, вероятно, немного быстрее сериализуются / десериализуются. Текстовые сериализации более отлаживаемы. Но удивительно, что можно сделать с помощью двоичных сериализаций. Например, можно легко добавить декодеры ASN.1 в Wireshark (вы компилируете их из файла схемы .asn с помощью инструментов ASN.1) и т. Д. - при декодировании данных программы по проводам. То же самое возможно с GPB, я должен думать.

ASN.1 uPER чрезвычайно полезен в ситуациях с ограниченной пропускной способностью; он автоматически использует ограничения размера / значения для экономии в битах на проводе. Например, поле с допустимым значением от 0 до 15 требует только 4 бита, и это то, что будет использовать uPER. Не случайно, что я думаю, что функции uPER также широко используются в таких протоколах, как 3G, 4G и 5G. Такой подход с минимальными битами намного более элегантен, чем сжатие текстового проводника (это то, что много сделано с JSON и XML, чтобы сделать их менее распухшими). ​​

5) Значения

Это немного странно. В ASN.1 файл схемы может определять как структуру объектов, так и значения объектов. С помощью лучших инструментов вы получаете классы (в вашем исходном коде C ++, JAVA, et c) и заранее определяете объекты этого класса, уже заполненные значениями.

Почему это полезно? Ну, я часто использую его для определения констант проекта и для предоставления доступа к ограничениям на ограничения. Например, предположим, что в сообщении вы получили поле массива с допустимой длиной 15. Вы можете иметь литерал 15 в ограничении поля или можете ссылаться на значение объекта целочисленного значения в ограничении, причем целое число также будет доступно для разработчиков. Это действительно удобно в обстоятельствах, когда вы хотите l oop сверх этого ограничения, потому что l oop может быть

for (int i = 0; i < ArraySize; i++) {do things with field[i];} // ArraySize is an integer in the auto generated code built from the .asn schema file

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

Насколько я знаю, это делает только ASN.1, и только более дорогие инструменты на самом деле выбирают эти элементы из файла схемы, что делает его чрезвычайно полезным в большом проекте. потому что буквально все, что связано с данными и их ограничениями, а также с тем, как их обрабатывать, определено только в схеме .asn, и нигде больше.

Как я уже говорил, я часто использую это для правильного типа проекта. Как только он проникает во весь проект, количество сэкономленного времени и риска составляет fantasti c. Это также меняет динамику проекта, можно вносить поздние изменения в схему, зная, что весь проект их забирает ни с чем. больше, чем перекомпиляция. Таким образом, протокол изменяется в конце проекта go высокий риск для чего-то, что вы могли бы делать каждый день.

6) Тип объекта Wireformat

Некоторые проводные форматы сериализации идентифицируют тип объекта в wireformat bytestrean. Это помогает читателю в ситуациях, когда объекты разных типов могут поступать из одного или нескольких источников. Другие сериализации не будут.

ASN.1 варьируется от проводного к проводному формату (у него есть несколько, включая несколько двоичных, а также XML и JSON). ASN.1 BER использует поля типа, значения и длины в своем проводном формате, так что читатель может просмотреть тег объекта перед декодированием потока байтов соответственно. Это очень полезно.

Буферы протокола Google не совсем то же самое, но если все типы сообщений в .proto объединены в один финальный oneof, и это только для каждого сериализованного, тогда вы можете добиться того же самого

7) Стоимость инструментов.

Инструменты ASN.1 варьируются от очень, очень дорогих (и действительно хороших), до бесплатных (и менее хорошо). Многие другие бесплатны, хотя я обнаружил, что лучшие XML инструменты (уделяющие должное внимание ограничениям по размеру / размеру) тоже довольно дороги.

8) Покрытие языка

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

Хорошие коммерческие инструменты ASN.1 охватывают C / C ++ / Java / C#. Есть несколько бесплатных C / C ++ с различной полнотой.

9) Качество

Нет смысла использовать технологию сериализации, если качество инструментов низкое.

По моему опыту, GPB - это хорошо (обычно он делает то, что говорит). Коммерческие инструменты ASN1 очень хороши, полностью исчерпав набор инструментов GPB. АВРО работает. Я слышал о некоторых случайных проблемах с Capt'n Proto, но, не используя его самому, вам придется это проверить. XML работает с хорошими инструментами.

10) Резюме

Если вы не можете сказать, я большой поклонник ASN.1.

GPB также невероятно полезен для его широкой поддержки и знакомства, но я сделаю это sh Google добавит ограничения значения / размера к полям и массивам, а также включит нотацию значений. Если бы они сделали это, можно было бы иметь тот же рабочий процесс проекта, который может быть достигнут с ASN.1. Если бы Google добавил только эти две функции, я бы посчитал, что GPB довольно хорошо подходит к «завершенной», и для тех людей, у которых мало места для хранения или пропускной способности, нужен всего лишь эквивалент UPER ASN.1, чтобы завершить его.

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

...