2012-03-27 5 views
4

Ich suche AVRO auf Hadoop. Aber ich beschäftige mich mit der Serialisierung großer Datenstrukturen und dem Hinzufügen von Methoden zu den (Daten-) Klassen.Wie Apache AVRO serialisiert (große) Datenstrukturen

Das Beispiel (aus http://blog.voidsearch.com/bigdata/apache-avro-in-practice/ entnommen) zeigt ein Modell von Facebook-Benutzern.

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

Does avro serialize die komplette Social Graph eines facebookuser in diesem Modell?

[Das heißt, wenn ich einen Benutzer serialisieren möchten, hat die Serialisierung umfassen alle es Freunde und deren Freunde und so weiter?]

Wenn die Antwort ja ist, würde ich eher speichern IDs von Freunden anstelle von Referenzen, um bei Bedarf in meiner Anwendung nachzuschlagen. In diesem Fall würde ich gerne eine Methode hinzufügen können, die die tatsächlichen Freunde anstelle von IDs zurückgibt.

Wie kann ich generierte AVRO Java Klassen einbinden/erweitern, um Methoden hinzuzufügen?

(auch Methoden hinzufügen, die zum Beispiel Freund-Zählung zurück)

Antwort

3

In Bezug auf die zweite Frage: Wie kann ich generierte AVRO Java-Klassen wrap/erweitern, um Methoden hinzuzufügen?

Sie können AspectJ verwenden, um neue Methoden in eine vorhandene/generierte Klasse einzufügen. AspectJ wird nur zur Kompilierzeit benötigt. Der Ansatz ist unten dargestellt.

Definieren einer Person Aufzeichnung als Avro IDL (person.avdl):

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

obigen Konfiguration geht davon aus, dass:

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

Verwendung maven und die avro-maven-plugin Java-Quellen aus dem AVDL zu erzeugen die person.avid Datei ist in src/main/resources/avro. Quellen werden in target/generated-sources/java generiert.

Generierte Person.java hat zwei Methoden: getFirstName() und getLastName().Wenn Sie wollen, dass es mit einer anderen Methode erweitern: getCompleteName() = vorName + Nachnamen dann können Sie diese Methode mit dem folgenden Aspekte injizieren:

package net.tzolov.avro.extend; 

import net.tzolov.avro.extend.Person; 

public aspect PersonAspect { 

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

Verwenden Sie den aspectj-maven-plugin Maven Plugin diesen Aspekt zu weben mit dem generierten Code

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

und das Ergebnis:

@Test 
public void testPersonCompleteName() throws Exception { 

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

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

ich zuerst erste quesion zu beantworten versuchen:
In meinem besten Verständnis AVRO ist nicht etwas, nicht hierarchisch speichern gebaut. Es hat auch keine Notation von Objekt-IDs. Es kann Arrays, Datensätze primitiver Typen oder Kombinationen davon speichern. Die Fähigkeit, den Graphen des Objekts, auf den Sie verweisen, zu übernehmen, ist in der Lage, die Java-Serialisierung zu aktivieren. Um also ein Diagramm zu speichern, sollten Sie eigene Objekt-IDs einführen und sie einigen Feldern explizit zuweisen. Sie können einen Blick in getSchema Methode hier: http://www.java2s.com/Open-Source/Java/Database-DBMS/hadoop-0.20.1/org/apache/avro/reflect/ReflectData.java.htm es ist ziemlich einfach ... Es ist ein Weg AVRO generiert Schema von der Java-Klasse.
In Bezug auf die zweite Frage - ich denke nicht, dass es eine gute Idee ist, generierten Code zu ändern. Ich würde vorschlagen, Klasse mit allen Methoden/Daten, die Sie hinzufügen möchten, zu machen und AVRO generierte "Daten" -Klasse als Mitglied dort zu setzen.
In der gleichen Zeit denke ich, dass technisch generierte Klassen in Ordnung sein sollte.

0

über diese Fragen mit Avro zu lösen versuchen, was oder vielleicht nicht funktioniert (meine Vermutung ist, dass die Erweiterung der generierten Klasse nicht gut funktioniert, egal wie du es versuchst), du könntest einfach JSON verwenden (es sei denn, du hast spezielle Voraussetzungen für Avro). Viele Bibliotheken unterstützen beliebige POJO-Mappings; und einige (wie Jackson) unterstützen auch die auf Object Id basierende Serialisierung (mit 2.0.0).