2015-09-18 11 views
5

JSON biçimindeki sunucu günlükleri ile uğraşıyorum ve günlüklerimı AWS S3'te Parke formatında saklamak istiyorum (ve Parke bir Avro şeması gerektirir). İlk olarak, tüm günlükler ortak bir alan kümesine sahiptir, ikinci olarak, tüm günlükler ortak kümede olmayan birçok isteğe bağlı alana sahiptir. 3 paylaşılan alanlarAvro'da harita ile kayıt nasıl karıştırılır?

{ "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"} 

üç günlüklerinin tüm adres: ip, timestamp ve message, günlükleri bazı tür microseconds ve thread gibi ek alanlar bulunur Örneğin

, follwoing üç kayıtları.

{"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]} 
] 
} 

Ama tek sorun bende olmayan geçerli:

aşağıdaki şemayı kullanın o zaman ben tüm ek alanlar .:

{"namespace": "example.avro", 
"type": "record", 
"name": "Log", 
"fields": [ 
    {"name": "ip", "type": "string"}, 
    {"name": "timestamp", "type": "String"}, 
    {"name": "message", "type": "string"} 
] 
} 

Ve aşağıdaki şema kaybedecek çalışıyor Tüm günlükleri taramazsam, isteğe bağlı alanların tüm isimlerini bildiğiniz gibi, gelecekte yeni ek alanlar da olacaktır. Ne yazık ki bu derleme olmaz

{"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 
] 
} 

:

Sonra record ve map birleştiren bir fikir dışarı düşünüyorum

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) 
:

java -jar avro-tools-1.7.7.jar compile schema example.avro . 

Bir hata dışarı ederim

JSON dizelerini Avro biçiminde saklamak için bir yol var mı le bilinmeyen alanlarla ilgilenmek için le?

Temel olarak bu, bir şema evrimi sorunudur, Spark, bu sorunu Schema Merging tarafından halledebilir. Hadoop ile bir çözüm arıyorum.

+0

Haritanızın hiçbir niteliği vardır. Bir ver. :) – oakad

+0

Sanırım asla Avro'yu denemezsin. Çalışmayacak. '{" ad alanı ":" example.avro ", " type ":" kayıt ", " name ":" Log ", " fields ": [ {" name ":" ip "," type ": "string"}, {"name": "timestamp", "type": "string"}, {"name": "message", "type": "string"}, {"name": " addtional "," type ":" map "," values ​​":" string "} ] }' – soulmachine

cevap

5

Harita türü avro terminolojisinde "karmaşık" bir türüdür. Aşağıdaki kod parçacığı çalışır:

{"namespace": "example.avro", 
"type": "record", 
"name": "Log", 
"fields": [ 
    {"name": "ip", "type": "string"}, 
    {"name": "timestamp", "type": "string"}, 
    {"name": "message", "type": "string"}, 
    {"name": "additional", "type": {"type": "map", "values": "string"}} 
    ] 
} 
+0

Teşekkürler! Bu şema derlemeyi geçecek. Bu şema, "addtional" alanındaki tüm isteğe bağlı alanları koyar; örneğin, "{" ip ":" 172.18.80.109 "," zaman damgası ":" 2015-09-17T23: 00: 18.313Z "," message ":" blah blash "," addtional ": {" microseconds ":" 123 "," thread ":" http-apr-8080-exec-1147 "}}', ancak tüm isteğe bağlı alanları ortak alanların aynı seviyesinde istiyorum. Benim sorumun üç örnek kütüğü gibi. – soulmachine

+0

Avro'daki kayıt, belirli sayıda önceden tanımlı alanlara sahip bir nesne olarak tanımlanır. Alternatif olarak haritanızı en üst düzey nesne olarak yerleştirin ve tüm alanlarınızı bu haritaya anahtar olarak yazın. – oakad

+0

"map" öğesini en üst düzey türü olarak kullanırsam, ör., "{" type ":" map "," values ​​":" string "}', daha sonra tüm alanların "string" tipi olması gerekir, eğer farklı tipte alanlar varsa, 'map' çaresizdir. – soulmachine

İlgili konular