2016-01-12 14 views
6

を尊重していない私は、このアブロスキーマここアブロスキーマが後方compatibiltyに

{ 
"namespace": "xx.xxxx.xxxxx.xxxxx", 
"type": "record", 
"name": "MyPayLoad", 
"fields": [ 
    {"name": "filed1", "type": "string"}, 
    {"name": "filed2",  "type": "long"}, 
    {"name": "filed3", "type": "boolean"}, 
    { 
      "name" : "metrics", 
      "type": 
      { 
      "type" : "array", 
      "items": 
      { 
       "name": "MyRecord", 
       "type": "record", 
       "fields" : 
        [       
         {"name": "min", "type": "long"}, 
         {"name": "max", "type": "long"}, 
         {"name": "sum", "type": "long"}, 
         {"name": "count", "type": "long"} 
        ] 
      } 
      } 
    } 
    ] 
} 

を持って、我々はデータ

public static final MyPayLoad parseBinaryPayload(byte[] payload) { 
     DatumReader<MyPayLoad> payloadReader = new SpecificDatumReader<>(MyPayLoad.class); 
     Decoder decoder = DecoderFactory.get().binaryDecoder(payload, null); 
     MyPayLoad myPayLoad = null; 
     try { 
      myPayLoad = payloadReader.read(null, decoder); 
     } catch (IOException e) { 
      logger.log(Level.SEVERE, e.getMessage(), e); 
     } 

     return myPayLoad; 
    } 

を解析するために使用するコードは、今、私は1つの以上のフィールドのintを追加したいですスキーマは以下のようになります。

{ 
"namespace": "xx.xxxx.xxxxx.xxxxx", 
"type": "record", 
"name": "MyPayLoad", 
"fields": [ 
    {"name": "filed1", "type": "string"}, 
    {"name": "filed2",  "type": "long"}, 
    {"name": "filed3", "type": "boolean"}, 
    { 
      "name" : "metrics", 
      "type": 
      { 
      "type" : "array", 
      "items": 
      { 
       "name": "MyRecord", 
       "type": "record", 
       "fields" : 
        [       
         {"name": "min", "type": "long"}, 
         {"name": "max", "type": "long"}, 
         {"name": "sum", "type": "long"}, 
         {"name": "count", "type": "long"} 
        ] 
      } 
      } 
    } 
    {"name": "agentType", "type": ["null", "string"], "default": "APP_AGENT"} 
    ] 
} 

ファイルが追加され、デフォルトも定義されていることに注意してください。問題は、私は、これは下位互換性がされている必要がありますが、何とかそれはしていないようことをthis文書から理解私たちは古いスキーマを使用して書き込まれたデータを受信した場合、私は

java.io.EOFException: null 
    at org.apache.avro.io.BinaryDecoder.ensureBounds(BinaryDecoder.java:473) ~[avro-1.7.4.jar:1.7.4] 
    at org.apache.avro.io.BinaryDecoder.readInt(BinaryDecoder.java:128) ~[avro-1.7.4.jar:1.7.4] 
    at org.apache.avro.io.BinaryDecoder.readIndex(BinaryDecoder.java:423) ~[avro-1.7.4.jar:1.7.4] 
    at org.apache.avro.io.ResolvingDecoder.doAction(ResolvingDecoder.java:229) ~[avro-1.7.4.jar:1.7.4] 
    at org.apache.avro.io.parsing.Parser.advance(Parser.java:88) ~[avro-1.7.4.jar:1.7.4] 
    at org.apache.avro.io.ResolvingDecoder.readIndex(ResolvingDecoder.java:206) ~[avro-1.7.4.jar:1.7.4] 
    at org.apache.avro.generic.GenericDatumReader.read(GenericDatumReader.java:152) ~[avro-1.7.4.jar:1.7.4] 
    at org.apache.avro.generic.GenericDatumReader.readRecord(GenericDatumReader.java:177) ~[avro-1.7.4.jar:1.7.4] 
    at org.apache.avro.generic.GenericDatumReader.read(GenericDatumReader.java:148) ~[avro-1.7.4.jar:1.7.4] 
    at org.apache.avro.generic.GenericDatumReader.read(GenericDatumReader.java:139) ~[avro-1.7.4.jar:1.7.4] 
    at com.appdynamics.blitz.shared.util.XXXXXXXXXXXXX.parseBinaryPayload(BlitzAvroSharedUtil.java:38) ~[blitz-shared.jar:na] 

このエラーが出るということです場合。どのようなアイデアを私は間違っていますか?

答えて

0

私は自分のスキーマに見ることができる2つの可能性の問題

  1. がありますが、私のデフォルト値は常にあなたが

"default": null

を設定する必要があり、これを指定するには、ヌル としての仕事を持っているようです
  1. また、スキーマでは、配列と新しいフィールドの間に、(フィールド区切り文字)を追加することを忘れてしまいました。したがって、最終的に私はこの作業を得た

    { "namespace": "xx.xxxx.xxxxx.xxxxx", "type": "record", "name": "MyPayLoad", "fields": [ {"name": "filed1", "type": "string"}, {"name": "filed2", "type": "long"}, {"name": "filed3", "type": "boolean"}, { "name" : "metrics", "type": { "type" : "array", "items": { "name": "MyRecord", "type": "record", "fields" : [ {"name": "min", "type": "long"}, {"name": "max", "type": "long"}, {"name": "sum", "type": "long"}, {"name": "count", "type": "long"} ] } } }, {"name": "agentType", "type": ["null", "string"], "default":null} ] }

2

として、あなたのスキーマを変更してみてください。私は、だから私は、私がリーダーで、新旧両方のスキーマを通過したところ、次のように構文解析を修正し、それが魅力

public static final MyPayLoad parseBinaryPayload(byte[] payload) { 
     DatumReader<MyPayLoad> payloadReader = new SpecificDatumReader<>(SCHEMA_V1, SCHEMA_V2); 
     Decoder decoder = DecoderFactory.get().binaryDecoder(payload, null); 
     MyPayLoad myPayLoad = null; 
     try { 
      myPayLoad = payloadReader.read(null, decoder); 
     } catch (IOException e) { 
      logger.log(Level.SEVERE, e.getMessage(), e); 
     } 

     return myPayLoad; 
    } 
0

私はこの正確な状況に直面していますように働いたSpecificDatumReader でのスキーマの両方を与える必要があります。新しいスキーマで読み込もうとすると、古いスキーマによって書き込まれたデータが失敗します。新しいスキーマには、共用体とデフォルトのセットを持つフィールドが1つだけ追加されています。 "type":["null"、 "string"]、 "doc": ""、 "default":null

既定の設定にもかかわらず、読み取り中にnullが自動的に入力されません。読者スキーマと読者スキーマの両方を読書中に提供する必要があります。 avroは後方互換性があり、古いスキーマを必要とせずに新しいカラムをサポートできるはずです。

関連する問題