如何使用 Avro 生成 String 类型的字段而不是 CharSequence?

Posted

技术标签:

【中文标题】如何使用 Avro 生成 String 类型的字段而不是 CharSequence?【英文标题】:How to generate fields of type String instead of CharSequence using Avro? 【发布时间】:2014-09-26 22:18:36 【问题描述】:

我编写了一个 Avro 模式,其中一些字段 ** 需要是 ** 类型为 String 但 Avro 生成了这些类型为 CharSequence 的字段。

我无法找到任何方法告诉 Avro 将这些字段设为 String 类型。

我尝试使用

"fields": [
    
        "name":"startTime",
        "type":"string",
        "avro.java.stringImpl":"String"
    ,
    
        "name":"endTime",
        "type":"string",
        "avro.java.string":"String"
    
]

但是对于这两个字段,Avro 正在生成 CharSequence 类型的字段。

还有其他方法可以使这些字段成为String 类型的字段吗?

【问题讨论】:

String 类实现CharSequence 接口。 CharSequence 是一个接口。默认情况下,Avro 使用自己的 Utf8 类作为 CharSequence 实现。 Utf8 不超过一个字节缓冲区,可以使用toString 转换为字符串。当您不关心基准测试中的字符串时,Utf8 很方便......但大多数情况下您要使用 CharSequence 并且必须将其转换为字符串。这很麻烦,而且会占用 100% 的内存开销,因为字符串现在既存储为 Utf8 又存储为字符串。这就是为什么很多人想要 String 而不是 CharSequence。将两者混合起来也很有用。 【参考方案1】:

如果您希望所有字符串字段都是java.lang.String 的实例,那么您只需配置编译器:

java -jar /path/to/avro-tools-1.7.7.jar compile -string schema 

或者如果您使用的是 Maven 插件

<plugin>
  <groupId>org.apache.avro</groupId>
  <artifactId>avro-maven-plugin</artifactId>
  <version>1.7.7</version>
  <configuration>
    <stringType>String</stringType>
  </configuration>
  [...]
</plugin>        

如果您希望某个特定字段为 java.lang.String 类型,那么...您不能。编译器不支持它。您可以将“java-class”与反射 API 一起使用,但编译器并不关心。

如果您想了解更多信息,可以在 SpecificCompiler 第 372 行,Avro 1.7.7 中设置断点。您可以看到,在调用addStringType() 之前,架构在props 字段中有所需的信息。如果您将此模式传递给SpecificCompiler.javaType(),那么它将执行您想要的操作。但是随后addStringType 将您的架构替换为静态架构。我很可能会在邮件列表上问这个问题,因为我没有明白这一点。

【讨论】:

有这方面的文档吗?我正在寻找如何指定数组类型。我希望它被设置而不是java.util.list,但找不到任何文档:/ 它也适用于 1.8.2。干杯@Clément MATHIEU【参考方案2】:

您可以按字段级别设置它,只需将类型更改为对象,并包括 "type" : "string" 和 "avro.java.string" : "String"

请看下面的例子:


    "type": "record",
    "name": "test",
    "fields": [
        
            "name": "name",
            "type": 
                "type": "string",
                "avro.java.string": "String"
            
        
    ]

【讨论】:

那行不通。我们以这种方式定义了 avro 文件,但我们仍然得到 CharSequence 而不是 String。使用 maven 配置的 Mathieu 解决方案在我们的案例中运行良好。

以上是关于如何使用 Avro 生成 String 类型的字段而不是 CharSequence?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Java 8 日期作为逻辑类型的 Avro

Avro 字段默认值

avro时间戳字段上的配置单元外部表返回一样长

模式注册表中的递归 avro 模式类型

如何将嵌套的 Avro 字段作为单个字段复制到 Redshift?

avro序列化详细操作