【Знакомство с Авро】
Apache Avro — это подпроект Hadoop и система сериализации данных. Его данные в конечном итоге хранятся в двоичном формате с использованием хранилища строк.
Авро обеспечивает:
Основываясь на вышеперечисленных преимуществах, avro широко используется в системе Hadoop. Кроме того, avro также используется в Hudi и Iceberg как формат хранения метаданных.
【schema】
Avro использует «схему» (схему) для реализации определения структуры данных. Схема описывается и выражается через объекты json, а именно следующим образом:
Типы в схеме состоят из примитивных типов (то есть базовых типов) (null, boolean, int, long, float, double, bytes и string) и сложных типов (запись, перечисление, массив, карта, объединение и т. д.). зафиксированный).
1. Оригинальный тип
К примитивным типам относятся следующие:
У примитивного типа нет указанного значения атрибута, и имя примитивного типа также является именем определенного типа. Таким образом, «строка» в схеме эквивалентна {»type»:»string»}.
2, сложный тип
Avro поддерживает 6 сложных типов: записи, перечисления, массивы, карты, объединения и фиксированные.
1)Records
reocrds использует имя типа «запись» и поддерживает следующие свойства
Простой пример:
{
"type": "record",
"name": "LongList",
"aliases": ["LinkedLongs"],
"fields", [
{"name": "value", "type": "long"},
{"name": "next", "type": ["null", "LongList"]}
]
}
2)Enums
Enum использует имя типа «enum» и поддерживает следующие свойства.
Пример:
{
"type": "enum",
"name": "Suit",
"symbols": ["SPADES", "HEARTS", "DIAMONDS", "CLUBS"]
}
3) Arrays
Пример: объявить массив, значением которого является строка.
{
"type": "array",
"items": "string",
"default": []
}
4)Maps
Пример: объявить карту, значением которой является длинный тип (тип ключа — строка).
{
"type": "map",
"values": "long",
"default": {}
}
5)Unions
Объединение представлено массивом json, например [null, «test»] объявляет шаблон, который может быть нулевым значением или строкой.
Следует отметить, что при указании значения по умолчанию для поля типа объединения тип значения по умолчанию должен соответствовать первому элементу объединения. Поэтому для объединения, содержащего «ноль», «ноль» обычно указывается первым, поскольку. этот тип Значение объединения по умолчанию обычно пусто.
Кроме того, объединение не может содержать несколько схем одного и того же типа, за исключением типов записи, фиксированной и EUM.
6)Fixed
Фиксированный использует имя типа «фиксированный» и поддерживает следующие свойства:
Например, 16-байтовое число можно объявить как:
{
"type": "fixed",
"name": "md5",
"size": 16
}
[Формат хранения файлов Avro]
1. Кодирование данных
1) Примитивный тип
длянулевой тип:Контент не написан,То есть представление контента длиной 0 байт;
длялогический тип:к1Байты0или1выражатьfalseилиtrue;
дляint、long:кzigzagспособкодировка записи
дляfloat:Фиксированная длина 4 байта,Сначала преобразуйте в 32-битное целое число через floatToIntBits.,Затем напишите в кодировке с прямым порядком байтов.
дляdouble:зафиксированный8Длина байта,Сначала преобразуйте в 64-битное целое число через doubleToLongBits.,Затем напишите в кодировке с прямым порядком байтов.
дляbytes:Сначала напишите длину(использоватьzigzagкодировка записи),Затем идут двоичные данные содержания соответствующей длины.
дляstring:такой же Сначала напишите длину(использоватьzigzagкодировка записи),Затем запишите в строку двоичные данные, соответствующие utf8.
2) Сложный тип
дляenums:Просто нужноenumгде значениеIndexПросто закодируйте результат,Например,Значения перечисления: ["A", "B", "C", "D"],Тогда 0 означает «А».,3 означает «Д».
дляmaps:кодируется как серия блоков。Каждый блок состоит из длинного целого числа, представляющего количество пар ключ-значение.(использоватьzigzagкодировка записи),за которым следует несколько пар ключ-значение,Блок со счетом 0 указывает на конец карты. Каждый элемент кодируется в соответствии с соответствующим ему типом схемы.
дляarrays:иmapпохожий,Также кодируется как серия блоков,Каждый блок содержит количество длинных целых чисел.,Подсчет, за которым следует содержимое определенного элемента массива,Он заканчивается представлением блока со счетчиком 0. Каждый элемент в элементе массива кодируется в соответствии с соответствующим типом схемы.
дляunions:напиши сначалаlongКоличество типов представляет каждыйvalueномер позиции значения(начать с нуля),Затем значение кодируется по соответствующей схеме.
дляrecords:Следуйте напрямуюschemaдля кодирования полей в。
Для фиксированного: закодируйте экземпляр, используя количество байтов, определенное в схеме.
2. Формат хранения
В стандартном файле avro информация о схеме и соответствующее содержимое данных хранятся одновременно. Конкретный формат состоит из трех частей:
Фиксированная длина 4 байта,Содержимое — символ «О».,'b','j',и идентификация номера версии,Обычно1。
Атрибуты метаданных файла, включая схему, метод сжатия данных и т. д. Весь атрибут метаданных кодируется и сохраняется в виде карты. Каждый атрибут сохраняется в форме KV. Имя атрибута соответствует ключу, а значение атрибута соответствует значению и сохраняется в форме. массив байтов. Наконец, случайная строка фиксированной длины в 16 байт идентифицирует конец метаданных.
Содержимое данных состоит из одного или нескольких блоков данных. В начале каждого блока данных находится счетчик длинного типа (сохраненный в соответствии с зигзагообразным кодированием), указывающий, сколько фрагментов данных фактически содержится в блоке данных, за которым следует счетчик длинного типа, указывающий длину закодированных (N фрагментов) данных. Затем имеются фрагменты данных, хранящиеся в соответствии с кодировкой. В конце каждого блока данных находится 16-байтовая случайная строка, идентифицирующая конец блока.
Общее содержимое хранилища показано на рисунке ниже:
3. Формат хранения
Давайте сравним и проанализируем на практическом примере.
Сначала определите содержимое схемы, а именно таблицу с четырьмя полями: имя (строка), возраст (целое число), навыки (массив) и другие (тип карты). Подробности следующие:
{
"type":"record",
"name":"person",
"fields": [
{
"name": "name",
"type": "string"
},
{
"name": "age",
"type": "int"
},
{
"name": "skill",
"type": {
"type":"array",
"items": "string"
}
},
{
"name": "other",
"type": {
"type": "map",
"values": "string"
}
}
]
}
Затем определите два фрагмента данных (person.json) согласно приведенной выше схеме:
{"name":"hncscwc","age":20,"skill":["hadoop","flink","spark","kafka"],"other":{"interests":"basketball"}}
{"name":"tom","age":18, "skill":["java","scala"],"other":{}}
Файл avro можно создать с помощью avro-tools:
java -jar avro-tools-1.7.4.jar fromjson --schema-file person.avsc person.json > person.avro
Просмотрите содержимое сгенерированного файла avro в двоичном режиме:
Кроме того, для существующего файла вы также можете просмотреть содержимое схемы и данных с помощью инструмента avro-tools.
[root@localhost avro]$ java -jar avro-tools-1.7.4.jar getschema ./person.avro
{
"type" : "record",
"name" : "person",
"fields" : [ {
"name" : "name",
"type" : "string"
}, {
"name" : "age",
"type" : "int"
}, {
"name" : "skill",
"type" : {
"type" : "array",
"items" : "string"
}
}, {
"name" : "other",
"type" : {
"type" : "map",
"values" : "string"
}
} ]
}
[root@localhost avro]$ java -jar avro-tools-1.7.4.jar tojson ./person.avro
{"name":"hncscwc","age":20,"skill":["hadoop","flink","spark","kafka"],"other":{"interests":"basketball"}}
{"name":"tom","age":18,"skill":["java","scala"],"other":{}}
【краткое содержание】
В этой статье представлено подробное объяснение определения формата avro, метода кодирования и фактического формата хранимого файла, а также, наконец, приведено сравнительное объяснение на практическом примере. Кроме того, на официальном сайте также используются RPC и Mapreduce. Подробных объяснений здесь нет. Если вам интересно, вы можете зайти на официальный сайт и проверить это.