Ho a che fare con registri server che sono in formato JSON e voglio memorizzare i miei registri su AWS S3 in formato Parquet (e Parquet richiede uno schema Avro). Innanzitutto, tutti i log hanno un set di campi comune, in secondo luogo, tutti i log hanno molti campi facoltativi che non sono nel set comune.Come mixare record con la mappa in Avro?
Ad esempio, il follwoing sono tre tronchi:
{ "ip": "172.18.80.109", "timestamp": "2015-09-17T23:00:18.313Z", "message":"blahblahblah"}
{ "ip": "172.18.80.112", "timestamp": "2015-09-17T23:00:08.297Z", "message":"blahblahblah", "microseconds": 223}
{ "ip": "172.18.80.113", "timestamp": "2015-09-17T23:00:08.299Z", "message":"blahblahblah", "thread":"http-apr-8080-exec-1147"}
tutti e tre i ceppi sono 3 campi condivisi: ip
, timestamp
e message
, alcuni dei ceppi hanno campi aggiuntivi, come ad esempio microseconds
e thread
.
Se uso il seguente schema allora mi perderò tutti i campi aggiuntivi .:
{"namespace": "example.avro",
"type": "record",
"name": "Log",
"fields": [
{"name": "ip", "type": "string"},
{"name": "timestamp", "type": "String"},
{"name": "message", "type": "string"}
]
}
E il seguente schema funziona bene:
{"namespace": "example.avro",
"type": "record",
"name": "Log",
"fields": [
{"name": "ip", "type": "string"},
{"name": "timestamp", "type": "String"},
{"name": "message", "type": "string"},
{"name": "microseconds", "type": [null,long]},
{"name": "thread", "type": [null,string]}
]
}
Ma l'unico problema è che non lo faccio conoscere tutti i nomi dei campi opzionali a meno che non scruto tutti i log, inoltre, ci saranno nuovi campi aggiuntivi in futuro.
allora penso fuori un'idea che coniuga record
e map
:
{"namespace": "example.avro",
"type": "record",
"name": "Log",
"fields": [
{"name": "ip", "type": "string"},
{"name": "timestamp", "type": "String"},
{"name": "message", "type": "string"},
{"type": "map", "values": "string"} // error
]
}
Purtroppo questo non compilerà:
java -jar avro-tools-1.7.7.jar compile schema example.avro .
sarà buttare via un errore:
Exception in thread "main" org.apache.avro.SchemaParseException: No field name: {"type":"map","values":"long"}
at org.apache.avro.Schema.getRequiredText(Schema.java:1305)
at org.apache.avro.Schema.parse(Schema.java:1192)
at org.apache.avro.Schema$Parser.parse(Schema.java:965)
at org.apache.avro.Schema$Parser.parse(Schema.java:932)
at org.apache.avro.tool.SpecificCompilerTool.run(SpecificCompilerTool.java:73)
at org.apache.avro.tool.Main.run(Main.java:84)
at org.apache.avro.tool.Main.main(Main.java:73)
C'è un modo per archiviare stringhe JSON in formato Avro che sono flexib le per gestire i campi opzionali sconosciuti?
Fondamentalmente si tratta di un problema di sviluppo dello schema , Spark può risolvere questo problema con Schema Merging. Sto cercando una soluzione con Hadoop.
La mappa non ha attributo nome. Daglielo. :) – oakad
Immagino non proverai mai avro. Non funzionerà. '{" namespace ":" example.avro ", " type ":" record ", " nome ":" Log ", " campi ": [ {" nome ":" ip "," tipo ": "string"}, {"nome": "timestamp", "tipo": "stringa"}, {"nome": "messaggio", "tipo": "stringa"}, {"nome": " addizionale "," tipo ":" mappa "," valori ":" stringa "} ] }' – soulmachine