Avro é um formato de dados importante no mundo da computação distribuída, com ele a quantidade de bytes trafegada pela rede será bem menor, se comparadada com seu equivalente definido com JSON.
Ele também possui um poderoso mecanismo que permite a evolução dos esquemas sem maiores dores-de-cabeça.
Neste artigo você entenderá como Avro dá suporte a evolução de esquemas, que aliado ao Schema Registry torna o trabalho muito mais simples.
Avro
Avro é uma especificação para formato de dados mantida pelo grupo Apache. Ele tem muitas utilidades e a principal e mais utilizada com Apache Kafka® é a Schema Resolution.
Acesse os equemas no projeto esquemas-avro
A resolução de esquema proporciona muita flexibilidade quando se identifica a necessidade de incluir um novo campo, criando uma evolução por exemplo. Veja:
Versão 1:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{
"name":"ForwardDebitoExecutadoV1",
"namespace":"com.kafkabr.e5o",
"type":"record",
"fields":[
{
"name":"valor",
"type":"double"
},
{
"name":"conta",
"type":"string"
},
{
"name":"descricao",
"type":"string"
},
{
"name":"apagar_v2",
"type":"string",
"default":"-apagado_v2-",
"doc":"Campo que será eliminado na próxima versão"
}
]
}
Versão 2 (evolução):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
"name":"ForwardDebitoExecutadoV2",
"namespace":"com.kafkabr.e5o",
"type":"record",
"fields":[
{
"name":"valor",
"type":"double"
},
{
"name":"conta",
"type":"string"
},
{
"name":"descricao",
"type":"string"
},
{
"name":"metadados",
"type":"string",
"doc":"Novo campo requerido"
}
]
}
Nos exemplos anteriores, na Versão 2 foi incluído um campo chamado metadados
, ele é requerido porque não define um valor padrão. Já a Versão 1 definiu um valor padrão para o campo apagar_v2
, tornando-o opcional.
Isso garante que eventos escritos (serializados) usando a Versão 2 do esquema podem ser lidos (desserializados) com sua Versão 1. E este é um exemplo clássico de compatibilidade FORWARD
.
Então isso leva a outro item importante que é a compatibilidade entre versões, ou seja, uma estratégia de evolução definida no inicio do ciclo de vida do esquema.
Evolução e Compatibilidade
Agora entra em cena o Schema Registry. Ele gerencia a evolução e compatibilidade entre versões de esquemas, pois ao registrar um novo esquema é obrigatório estabelecer uma estratégia que será utilizada durante seu ciclo de vida.
As estratégias são:
As estratégias de compatibilidade são relativas a nova versão do esquema
BACKWARD
: novo esquema pode ser utilizado para ler a versão imediatamente anteriorBACKWARD_TRANSITIVE
: novo esquema pode ser utilizado para ler qualquer versão anteriorFORWARD
: uma versão imediatamente anterior é capaz de ler eventos escritos (serializados) com o novo esquemaFORWARD_TRANSITIVE
: qualquer versão anterior é capaz de ler eventos escritos (serializados) com o novo esquemaFULL
: esquema éBACKWARD
eFORWARD
ao mesmo tempoFULL_TRANSITIVE
: esquema éFORWARD_TRANSITIVE
eBACKWARD_TRANSITIVE
ao mesmo tempo
Interagir com Schema Registry
O modelo evolutivo do esquema pode ser definido ao registrá-lo no Schema Registry ou herdado do padrão global, que aqui será demonstrado através de sua API Rest.
Substituir
http://localhost:8081
pela URL do registry
Consultar estratégia evolutiva globlal no Schema Registry
1
curl -X GET http://localhost:8081/config
Saída. (Padrão é BACKWARD
)
1
{"compatibilityLevel":"BACKWARD"}
Registrar esquema Versão 1 para um novo tópico
1
2
3
4
curl -X POST \
-H "Content-Type: application/vnd.schemaregistry.v1+json" \
--data '{"schema": "{\"name\":\"ForwardDebitoExecutadoV1\",\"namespace\":\"com.kafkabr.e5o\",\"type\":\"record\",\"fields\":[{\"name\":\"valor\",\"type\":\"double\"},{\"name\":\"conta\",\"type\":\"string\"},{\"name\":\"descricao\",\"type\":\"string\"},{\"name\":\"apagar_v2\",\"type\":\"string\",\"default\":\"-apagado_v2-\",\"doc\":\"Campo que ser\u00E1 eliminado na pr\u00F3xima vers\u00E3o\"}]}"}' \
http://localhost:8081/subjects/conta-corrente-transacoes-value/versions
Configurar a estratégia de evolução
FORWARD
1
2
3
4
curl -X PUT \
-H 'Content-Type: application/json' \
--data '{"compatibility": "FORWARD"}' \
http://localhost:8081/config/conta-corrente-transacoes-value
Testar compatibilidade da evolução
Se o teste for realizado antes da estratégia, então o resultado será incompatível.
1
2
3
4
curl -X POST \
-H "Content-Type: application/vnd.schemaregistry.v1+json" \
--data '{"schema": "{\"name\":\"ForwardDebitoExecutadoV2\",\"namespace\":\"com.kafkabr.e5o\",\"type\":\"record\",\"fields\":[{\"name\":\"valor\",\"type\":\"double\"},{\"name\":\"conta\",\"type\":\"string\"},{\"name\":\"descricao\",\"type\":\"string\"},{\"name\":\"metadados\",\"type\":\"string\",\"doc\":\"Novo campo requerido\"}]}"}' \
http://localhost:8081/compatibility/subjects/conta-corrente-transacoes-value/versions/1
Saída sobre a verificação de compatibilidade:
1
{"is_compatible":true}
Registrar evolução, a Versão 2
Esquema segue a estratégia
FORWARD
1
2
3
4
curl -X POST \
-H "Content-Type: application/vnd.schemaregistry.v1+json" \
--data '{"schema": "{\"name\":\"ForwardDebitoExecutadoV2\",\"namespace\":\"com.kafkabr.e5o\",\"type\":\"record\",\"fields\":[{\"name\":\"valor\",\"type\":\"double\"},{\"name\":\"conta\",\"type\":\"string\"},{\"name\":\"descricao\",\"type\":\"string\"},{\"name\":\"metadados\",\"type\":\"string\",\"doc\":\"Novo campo requerido\"}]}"}' \
http://localhost:8081/subjects/conta-corrente-transacoes-value/versions
Registrar evolução incompatível
Quando se tenta registrar uma versão imcompatível com a estratégia evolutiva definida, um erro como este será retornado e o esquema rejeitado.
1
2
3
4
{
"error_code":409,
"message":"Schema being registered is incompatible with an earlier schema for subject \"conta-corrente-transacoes-value\""
}
Todos os esquemas estão no Github: https://github.com/kafkabr/esquemas-avro
Obrigado e até o próximo!
Photo by Cytonn Photography on Unsplash