2012-03-27 5 views
4

私はhadoopでAVROを使用しています。しかし、私は大規模なデータ構造の直列化と(データクラス)へのメソッドの追加方法に懸念しています。Apache AVROはどのようにデータ構造をシリアル化(大)するのですか

例(http://blog.voidsearch.com/bigdata/apache-avro-in-practice/から取得)は、Facebookのユーザーのモデルを示しています。

{ 
    "namespace": "test.avro", 
    "name": "FacebookUser", 
    "type": "record", 
    "fields": [ 
     {"name": "name", "type": "string"}, 
     ..., 
     {"name": "friends", "type": "array", "items": "FacebookUser"} 
    ] 
} 

アブロは、このモデルでfacebookuserの完全なソーシャルグラフをシリアル化していますか?答えがイエスであれば

[それは私が一人のユーザーをシリアル化したい場合は、シリアライズはとても上のすべてのそれの友人とその友人を含め、ん、ありますか?]

することは、私はむしろ友人のIDを格納したいです参照の代わりに、必要に応じていつでもアプリケーションで参照することができます。その場合、IDの代わりに実際の友達を返すメソッドを追加できるようにしたいと考えています。

生成されたAVRO Javaクラスをラップしてメソッドを追加するにはどうすればよいですか?私の理解AVROの最高に
は階層的ではない何かを格納するために構築されていません。

は、私が最初に最初quesionにお答えしようとしています

答えて

3

2番目の質問について:生成されたAVRO Javaクラスをラップして拡張する方法はありますか?

既存の/生成されたクラスに新しいメソッドを挿入するためにAspectJを使用することができます。 AspectJはコンパイル時にのみ必要です。アプローチを以下に示します。

アブロIDL( person.avdl )としてのPersonレコードを定義します。

@namespace("net.tzolov.avro.extend") 
protocol PersonProtocol { 
    record Person { 
     string firstName; 
     string lastName; 
    }  
} 

使用Mavenとavro-maven-plugin AVDLからJavaソースを生成する:

<dependency> 
    <groupId>org.apache.avro</groupId> 
    <artifactId>avro</artifactId> 
    <version>1.6.3</version> 
</dependency> 
    ...... 
    <plugin> 
     <groupId>org.apache.avro</groupId> 
     <artifactId>avro-maven-plugin</artifactId> 
     <version>1.6.3</version> 
     <executions> 
      <execution> 
       <id>generate-avro-sources</id> 
       <phase>generate-sources</phase> 
       <goals> 
        <goal>idl-protocol</goal> 
       </goals> 
       <configuration> 
        <sourceDirectory>src/main/resources/avro</sourceDirectory> 
        <outputDirectory>${project.build.directory}/generated-sources/java</outputDirectory> 
       </configuration> 
      </execution> 
     </executions> 
    </plugin> 

の構成上のことを前提としperson.avidファイルはsrc/main/resources/avroにあります。ソースはのtarget/generated-sources/javaに生成されます。

生成されたPerson.javaには、getFirstName()とgetLastName()という2つのメソッドがあります。あなたが別の方法でそれを拡張したい場合:getCompleteName() =のfirstName + lastNameのあなたは、次の側面でこのメソッドを注入することができます

package net.tzolov.avro.extend; 

import net.tzolov.avro.extend.Person; 

public aspect PersonAspect { 

    public String Person.getCompleteName() {   
     return this.getFirstName() + " " + this.getLastName(); 
    } 
} 

は、生成されたコードと、この側面を織るためにプラグインaspectj-maven-plugin Mavenを使用してください

<dependency> 
    <groupId>org.aspectj</groupId> 
    <artifactId>aspectjrt</artifactId> 
    <version>1.6.12</version> 
</dependency> 
<dependency> 
    <groupId>org.aspectj</groupId> 
    <artifactId>aspectjweaver</artifactId> 
    <version>1.6.12</version> 
</dependency> 
    .... 
<plugin> 
    <groupId>org.codehaus.mojo</groupId> 
    <artifactId>aspectj-maven-plugin</artifactId> 
    <version>1.2</version> 
    <dependencies> 
     <dependency> 
      <groupId>org.aspectj</groupId> 
      <artifactId>aspectjrt</artifactId> 
      <version>1.6.12</version> 
     </dependency> 
     <dependency> 
      <groupId>org.aspectj</groupId> 
      <artifactId>aspectjtools</artifactId> 
      <version>1.6.12</version> 
     </dependency> 
    </dependencies> 
    <executions> 
     <execution> 
      <goals> 
       <goal>compile</goal> 
       <goal>test-compile</goal> 
      </goals> 
     </execution> 
    </executions> 
    <configuration> 
     <source>6</source> 
     <target>6</target> 
    </configuration> 
</plugin> 

と結果:アブロでこれらの問題を解決しようと

@Test 
public void testPersonCompleteName() throws Exception { 

    Person person = Person.newBuilder() 
      .setFirstName("John").setLastName("Atanasoff").build(); 

    Assert.assertEquals("John Atanasoff", person.getCompleteName()); 
} 
1

(また、例えば友人のカウントのために返すメソッドを追加します)。オブジェクトIDの表記もありません。配列、プリミティブ型のレコード、またはそれらの任意の組み合わせを格納できます。あなたが参照しているトラバースオブジェクトのグラフへの機能は、AVROレーシングのJavaシリアライゼーションの能力です。
グラフを保存するには、オブジェクトIDを所有し、いくつかのフィールドに明示的に割り当てる必要があります。 ここでgetSchemaメソッドを調べることができます:http://www.java2s.com/Open-Source/Java/Database-DBMS/hadoop-0.20.1/org/apache/avro/reflect/ReflectData.java.htm これはかなり単純です... AVROがJavaクラスによってスキーマを生成する方法です。
2番目の質問について - 私は生成されたコードを変更することをお勧めしません。私はあなたが追加するすべてのメソッド/データを持つクラスを作成し、そこにメンバーとしてAVROが生成した "データ"クラスを入れることを提案します。
同時に、私は、生成されたクラスを技術的に拡張することは大丈夫だと思います。

0

を越えて、それは動作しないかもしれません(私の推測では、生成されたクラスを拡張することはどのように試してもうまく動作しません)、プレーンなJSONの使用を検討できます(Avroの特定の要件がない限り)。 多くのライブラリは任意のPOJOマッピングをサポートしています。一部のユーザー(Jacksonなど)もオブジェクトIDベースのシリアライズ(2.0.0)をサポートしています。

関連する問題