关于Avro的使用
14年开始尝试Flume的时候了解到Avro相关的东西,但一直都没有很深入的使用。
最近在做Binlog采集时,写入Kafka的数据格式要求是Avro,在使用中了解碰到了一些小问题
在这里分享一下。
复用
序列化和反序列化时需要BinaryEncoder和BinaryDecoder,这个对象是可以反复使用的。
反序列化接口是支持对象复用的,但是经过测试复用对象性能反而下降了。
并发
序列化和反序列化都需要一个Json格式的Schema信息,或者叫Avsc。
最开始多线程反序列化Avro数据时,是使用同一个Schema对象的,但是随着线程的增加,
并发的效率提升并不明显,通过对线程状态的搜索,发现Schema对象上有Sync修饰,
详见JsonProperties类。解决办法也很简单,每个线程使用一个独立的Schema对象就可以了。
Avro中的String
Avro中的String可以是Java的String类型,还可以是使实现了CharSequence的UTF8。
当然UTF8的Charsequence直接tostring就会转为Java的String了,但是Map的key就非常难处理。
假如你的数据对象中有一个Map的field,并且Map的Key是String,通过get(“abc”)来获取
value是不可行的,因为”abc”和UTF8(“abc”)的hashcode完全不同。只能遍历老的map,然后
key.tostring(),再放入一个新的map中去,非常浪费性能。
Avro是可以声明schema的string是java的string的来解决,还可以复写SpecificDatumReader
这个类,特殊处理一下readMapKey方法,当是UTF8时调用一下tostring方法,转成java的string。