Я имею дело с журналами сервера, которые являются JSON-форматом, и я хочу хранить свои журналы на AWS S3 в формате Паркет (а Паркет требует схему Avro). Во-первых, все журналы имеют общий набор полей, во-вторых, во всех журналах есть много необязательных полей, которые не входят в общий набор.Как смешивать запись с картой в Avro?
Например, происходит некорректно три бревна:
{ "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"}
Все из трех бревен 3 общие поля: ip
, timestamp
и message
, некоторые из бревен имеют дополнительные поля, такие как microseconds
и thread
.
Если я использую следующую схему, то я потеряю все дополнительные поля .:
{"namespace": "example.avro",
"type": "record",
"name": "Log",
"fields": [
{"name": "ip", "type": "string"},
{"name": "timestamp", "type": "String"},
{"name": "message", "type": "string"}
]
}
И следующая схема работает отлично:
{"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]}
]
}
Но единственная проблема в том, что я не знайте все имена необязательных полей, если я не сканирую все журналы, кроме того, в будущем появятся новые дополнительные поля.
Тогда я придумываю идею, которая сочетает в себе record
и 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
]
}
К сожалению, это не будет компилироваться:
java -jar avro-tools-1.7.7.jar compile schema example.avro .
Он выкинет ошибку:
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)
Есть ли способ хранить строки JSON в формате Avro, которые являются гибкими le, чтобы иметь дело с неизвестными необязательными полями?
В основном это Схема эволюции проблема, Spark может решить эту проблему на Schema Merging. Я ищу решение с Hadoop.
Ваша карта не имеет атрибута имени. Дайте ему это. :) – oakad
Думаю, вы никогда не пробовали авро. Это не сработает. '{" namespace ":" example.avro ", " type ":" record ", " name ":" Log ", " fields ": [ {" name ":" ip "," type ": "string"}, {"name": "timestamp", "type": "string"}, {"name": "message", "type": "string"}, {"name": " addtional "," type ":" map "," values ":" string "} ] }' – soulmachine