Protocol Buffers
Protocol Buffers — протокол сериализации (передачи) структурированных данных, предложенный Google как эффективная бинарная альтернатива текстовому формату XML. Разработчики сообщают, что Protocol Buffers проще, компактнее и быстрее, чем XML, поскольку осуществляется передача бинарных данных, оптимизированных под минимальный размер сообщения[2]. Общие сведенияПо замыслу разработчиков, сначала должна быть описана структура данных, которая затем компилируется в классы. Вместе с классами идёт код их сериализации в компактном формате представления. Чтение и запись данных доступна в высокоуровневых языках программирования — таких как Java, C++ или Python. В 2010 году бэкенд Twitter перешёл на Protocol Buffers. По заявлению разработчиков Twitter, база в триллион твитов на XML занимала бы десять петабайт вместо одного.[3] По заявлениям Google, Protocol Buffers по сравнению с XML:[2]
Protocol Buffers не предназначен для чтения пользователем и представляет собой двоичный формат. Для десериализации данных необходим отдельный .proto-файл, в котором определяется формат сообщения. Формат протоколаВ общем виде формат представляет собой закодированную последовательность полей, состоящих из ключа и значения. В качестве ключа выступает номер, определённый для каждого поля сообщения в proto-файле. Перед каждым полем указываются совместно закодированные номер поля в формате varint и тип поля. Если в качестве типа указана строка ( Число в формате varint ( Проблема кодирования отрицательных чисел была решена использованием алгоритма ZigZag ( Пусть encoded_value = (value << 1) ^ (value >> (N - 1));
Следует учесть, что вторая операция сдвига является арифметическим сдвигом, то есть при сдвиге вправо отрицательного числа старшие биты заполняются единицами, а не нулями (сдвиг знакового бита). Декодирование выполняется более сложным способом: выполняется исключающее ИЛИ над закодированным значением, сдвинутым на 1 вправо для удаления знакового бита, и знаковым битом, полученным из закодированного числа, спроецированным на все биты через умножение на максимальное значение для uvalue = ((encoded_value & 1) * MAX_VALUE(N)) ^ (encoded_value >> 1);
Значение Все числовые значения, кроме Примеры использованияДля того чтобы определить структуру сериализуемых данных, необходимо создать .proto-файл с исходным кодом этой структуры. Ниже приведён пример .proto-файла для 2-й версии Protocol Buffers, где описывается информация о машине: марка, тип кузова, цвет, год выпуска и информация о предыдущих владельцах. message Car {
required string model = 1;
enum BodyType {
sedan = 0;
hatchback = 1;
SUV = 2;
}
required BodyType type = 2 [default = sedan];
optional string color = 3;
required int32 year = 4;
message Owner {
required string name = 1;
required string lastName = 2;
required int64 driverLicense = 3;
}
repeated Owner previousOwner = 5;
}
После того как файл с нужной структурой данных создан, необходимо скомпилировать его компилятором для вашего языка программирования, чтобы сгенерировать класс доступа к этим данным. Этот класс будет содержать простейшие методы доступа ко всем полям типа get/set, а также методы для сериализации и десериализации вашей структуры данных в/из массива байтов. Примечательно, что можно добавлять к уже созданной структуре данных новые поля без потери совместимости с предыдущей версией: при парсинге старых записей новые поля просто будут игнорироваться. РеализацияНа данный момент компанией Google созданы компиляторы для языков программирования: C++, Java, Python, Go, C#, Objective C, JavaScript[5]. Но существует ряд проектов сторонних разработчиков, которые создали компиляторы для следующих языков программирования: Action Script, C, C#, Clojure, Common Lisp, D, Erlang, Go, Haskell, Haxe, JavaScript, Lua, Matlab, Mercury, Objective C, Swift, OCaml, Perl, PHP, Python, Ruby, Rust, Scala, Visual Basic, Delphi[6]. Реализация для языка СиЧтобы использовать протокол в языке Си без сторонних библиотек необходимо либо использовать вставки на языке C++, если таковые поддерживаются используемым компилятором, либо делать обёртки над сгенерированным для C++ кодом в виде библиотек. Если подобные варианты не подходят, то известны следующие генераторы кода:
Альтернативные протоколыНаиболее высокопроизводительной альтернативой может служить библиотека FlatBuffers[англ.], которая позволяет обращаться к сериализованным данным без их копирования по частям в отдельные области памяти. Соответственно, данные передаются в том же виде, в каком и используются, в связи с чем увеличивается объём передаваемых данных. Проект Apache Avro[англ.] отличается тем, что не требует генерации кода при изменении схемы данных при использовании в динамически-типизируемых языках, а сама схема описывается в формате JSON. Сравнение с Apache ThriftКлючевыми особенностями Apache Thrift могут служить возможность передачи ассоциативных массивов, списков и множеств, а также встроенная поддержка удалённого вызова процедур[7].
Примечания
Ссылки
|