java - ¿Cuál es la ventaja de almacenar el esquema en avro?
apache hadoop (2)
Necesitamos serializar algunos datos para poner en solr y hadoop.
Estoy evaluando herramientas de serialización para el mismo.
Los dos primeros en mi lista son Gson y Avro.
Por lo que yo entiendo, Avro = Gson + Schema-In-JSON
Si eso es correcto, no veo por qué Avro es tan popular para Solr / Hadoop.
He buscado mucho en Internet, pero no puedo encontrar una sola respuesta correcta para esto.
Donde quiera que diga, Avro es bueno porque almacena el esquema. Mi pregunta es ¿qué hacer con ese esquema?
Puede ser bueno para objetos muy grandes en Hadoop donde un solo objeto se almacena en múltiples bloques de archivos de manera que almacenar el esquema con cada parte ayuda a analizarlo mejor. Pero incluso en ese caso, el esquema se puede almacenar por separado y solo una referencia a eso es suficiente para describir el esquema. No veo ninguna razón por la cual el esquema deba ser parte de todas y cada una de las piezas.
Si alguien puede darme un buen caso de uso de cómo Avro los ayudó y Gson / Jackson fueron insuficientes para el propósito , sería realmente útil.
Además, la documentación oficial en el sitio de Avro dice que tenemos que darle un esquema a Avro para ayudarlo a producir Schema + Data. Mi pregunta es, si se ingresa el esquema y se envía el mismo a la salida junto con la representación de datos JSON, ¿qué extra adicional está logrando Avro? ¿No puedo hacerlo yo mismo serializando un objeto usando JSON, agregando mi esquema de entrada y llamándolo Avro?
¡Estoy realmente confundido con esto!
1: Esquemas evolutivos
Supongamos inicialmente que diseñó un esquema como este para su clase Empleado
{{"nombre": "emp_name", "tipo": "cadena"}, {"nombre": "dob", "tipo": "cadena"}, {"nombre": "edad", "tipo": "En t"} }
Más tarde, se dio cuenta de que la edad es redundante y la eliminó del esquema.
{{"nombre": "emp_name", "tipo": "cadena"}, {"nombre": "dob", "tipo": "cadena"}}
¿Qué pasa con los registros que fueron serializados y almacenados antes de que este esquema cambie? ¿Cómo leerá esos registros?
Es por eso que el lector / deserializador avro solicita el esquema de lector y escritor. Internamente lo hace resolución de esquema, es decir. intenta adaptar el esquema anterior a un nuevo esquema.
Vaya a este enlace - http://avro.apache.org/docs/1.7.2/api/java/org/apache/avro/io/parsing/doc-files/parsing.html - sección "Resolución usando símbolos de acción"
En este caso, omite la acción, es decir, deja de leer "edad". También puede manejar casos como cambios de campo de int a long, etc.
Este es un artículo muy bueno que explica la evolución del esquema - http://martin.kleppmann.com/2012/12/05/schema-evolution-in-avro-protocol-buffers-thrift.html
2: el esquema se almacena solo una vez para múltiples registros en un solo archivo.
3: Tamaño, codificado en muy pocos bytes.
Creo que uno de los problemas clave resueltos por la evolución del esquema no se menciona explícitamente en ninguna parte y es por eso que causa tanta confusión a los recién llegados.
Un ejemplo aclarará esto:
Digamos que un banco almacena un registro de auditoría de todas sus transacciones. Los registros tienen un formato particular y deben almacenarse durante al menos 10 años. También es muy conveniente que el sistema que contiene estos registros se adapte al formato que evoluciona en todos estos 10 años.
El esquema para tales entradas no cambiaría con demasiada frecuencia, digamos dos veces al año en promedio, pero cada esquema tendría una gran cantidad de entradas. Si no hacemos un seguimiento de los esquemas, luego de un tiempo, tendremos que consultar un código muy antiguo para descubrir los campos presentes en ese momento y seguir agregando sentencias if-else para procesar diferentes formatos. Con un almacén de esquemas de todos estos formatos, podemos usar la función de evolución del esquema para convertir automáticamente un tipo de formato en el otro (Avro lo hace automáticamente si le proporciona esquemas más antiguos y más nuevos). Esto ahorra a las aplicaciones agregar muchas declaraciones if-else en su código y también lo hace más manejable, ya que sabemos fácilmente cuáles son todos los formatos que tenemos al mirar el conjunto de esquemas almacenados (los esquemas generalmente se almacenan en un almacenamiento separado y los datos solo tienen una ID apuntando a su esquema).
Otra ventaja de la evolución del esquema es que los productores de nuevo formato pueden producir objetos de forma segura con un nuevo esquema sin esperar a que los consumidores intermedios cambien primero. Los consumidores intermedios pueden tener la lógica incorporada para simplemente suspender el procesamiento a menos que tengan visibilidad del nuevo esquema asociado con un nuevo formato. Esta suspensión automática es excelente para mantener el sistema en línea y adaptar la lógica de procesamiento para el nuevo esquema.
Por lo tanto, en resumen, la evolución del esquema ayuda a los clientes más nuevos a leer formatos más antiguos al usar la conversión de formato automático y también ayuda a los clientes antiguos a suspender el procesamiento de manera elegante hasta que se les haya permitido comprender formatos más nuevos.