我可以跨多个文件拆分Apache Avro架构吗?

Owe*_*wen 22 avro

我可以,

{
    "type": "record",
    "name": "Foo",
    "fields": [
        {"name": "bar", "type": {
            "type": "record",
            "name": "Bar",
            "fields": [ ]
        }}
    ]
}
Run Code Online (Sandbox Code Playgroud)

并且工作正常,但假设我想将模式拆分为两个文件,例如:

{
    "type": "record",
    "name": "Foo",
    "fields": [
        {"name": "bar", "type": "Bar"}
    ]
}

{
    "type": "record",
    "name": "Bar",
    "fields": [ ]
}
Run Code Online (Sandbox Code Playgroud)

Avro有能力这样做吗?

小智 31

是的,这是可能的.

我通过在avro-maven-plugin中定义公共模式文件在我的java项目中完成了这个例子:

search_result.avro:

{"namespace": "com.myorg.other",
 "type": "record",
 "name": "SearchResult",
 "fields": [
     {"name": "type", "type": "SearchResultType"},
     {"name": "keyWord",  "type": "string"},
     {"name": "searchEngine", "type": "string"},
     {"name": "position", "type": "int"},
     {"name": "userAction", "type": "UserAction"}
 ]
}
Run Code Online (Sandbox Code Playgroud)

search_suggest.avro:

{"namespace": "com.myorg.other",
 "type": "record",
 "name": "SearchSuggest",
 "fields": [
     {"name": "suggest", "type": "string"},
     {"name": "request",  "type": "string"},
     {"name": "searchEngine", "type": "string"},
     {"name": "position", "type": "int"},
     {"name": "userAction", "type": "UserAction"},
     {"name": "timestamp", "type": "long"}
 ]
}
Run Code Online (Sandbox Code Playgroud)

user_action.avro:

{"namespace": "com.myorg.other",
 "type": "enum",
 "name": "UserAction",
 "symbols": ["S", "V", "C"]
}
Run Code Online (Sandbox Code Playgroud)

search_result_type.avro

{"namespace": "com.myorg.other",
 "type": "enum",
 "name": "SearchResultType",
 "symbols": ["O", "S", "A"]
}
Run Code Online (Sandbox Code Playgroud)

avro-maven-plugin配置:

<plugin>
    <groupId>org.apache.avro</groupId>
<artifactId>avro-maven-plugin</artifactId>
<version>1.7.4</version>
    <executions>
    <execution>
        <phase>generate-sources</phase>
        <goals>
        <goal>schema</goal>
        </goals>
    <configuration>
     <sourceDirectory>${project.basedir}/src/main/resources/avro</sourceDirectory>
         <outputDirectory>${project.basedir}/src/main/java/</outputDirectory>
     <includes>
         <include>**/*.avro</include>
     </includes>
     <imports>
              <import>${project.basedir}/src/main/resources/avro/user_action.avro</import>
              <import>${project.basedir}/src/main/resources/avro/search_result_type.avro</import>
     </imports>
       </configuration>
     </execution>
</executions>
</plugin>
Run Code Online (Sandbox Code Playgroud)


Mic*_*ael 22

您还可以在一个文件中定义多个模式:

schemas.avsc:

[
{
    "type": "record",
    "name": "Bar",
    "fields": [ ]
},
{
    "type": "record",
    "name": "Foo",
    "fields": [
        {"name": "bar", "type": "Bar"}
    ]
}
]
Run Code Online (Sandbox Code Playgroud)

如果你想在多个地方重用模式,这不是很好,但在我看来它提高了可读性和可维护性.

  • 在您的示例中,您实际上定义了一个具有两种不同成员类型的“联合”类型。这可能会产生影响,具体取决于哪种系统正在处理模式。 (8认同)

fab*_*ica 5

我假设,你的动机是(作为我自己的)构建你的模式定义并避免复制和粘贴错误.

为此,您还可以使用Avro IDL.它允许在更高级别定义avro架构.可以在同一文件中以及跨多个文件重用类型.

生成.avsc文件运行

$ java -jar avro-tools-1.7.7.jar idl2schemata my-protocol.avdl
Run Code Online (Sandbox Code Playgroud)

生成的.avsc文件看起来与您的初始示例几乎相同,但是因为它们是从.avdl生成的,所以您不会以详细的json格式丢失.


小智 0

据我目前所知,没有。

有一篇关于某人编写自己的方法来执行此操作的很好的文章:

http://www.infoq.com/articles/ApacheAvro