Avro优化
上一篇blog写了一个通用的avro数据schema,接下来写点于此相关的插曲。
Array
在上文中提到的的Data存在7个数据类型的Array,avro中定义的Array就是List。
因为我们的meta是确定的,所以存储数据的数组length就是固定的,并不需要resize。
假如在写入数据时,并不按照schema的顺序来写的话,就会导致操作Arraylist报错。
所以需要实现一个List来包装数组的特性,我们就叫它FixedList吧。
private Object[] elementData;
public FixedList(int capacity) {
this.elementData = new Object[capacity];
}
@Override
public int size() {
return elementData.length;
}
@Override
public boolean isEmpty() {
return false;
}
@Override
public E get(int index) {
return elementData(index);
}
@Override
public E set(int index, E element) {
E e = elementData(index);
elementData[index] = element;
return e;
}
scheme to java
定义schema的json后,通过avro-tool来compile得到java文件。
java -jar avro-tools-1.9.1.jar compile -string schema Data.schema .
第一次使用avro的enum类型,发现还单独生成了一个enum的java文件,不要忽略了。
avro中string默认为charsequence,可以加-string参数改为java.lang.String。
encoder
在序列化avro时,需要BinaryEncoder实例,默认为BufferBinaryEncoder。
如果数据的字段比较多,数据体积比较大的话,需要适当提高Buffer的size,来提高性能,
不然会导致多次arraycopy。avro还提供了一个BlockingBinaryEncoder,
针对超大的Array和Map有优化,一般来说是用不到的。
一般来说在encode时,还需要一个ByteArrayOutputStream,也需要适当考虑一下初始size。
avro的decoder也一样,可以设置buffersize的。
最后
大致读了一下avro的源码,涉及到arraycopy的比较多,之后做性能测试的时候再看如何优化。
data.avsc
{
"namespace":"exchange",
"type":"record",
"name":"Data",
"fields":[
{
"name":"nid",
"type":"long"
},
{
"name":"sid",
"type":[
"null",
"string"
]
},
{
"name":"opt",
"type":{
"name":"Opt",
"type":"enum",
"symbols":[
"INSERT",
"UPDATE",
"DELETE"
]
}
},
{
"name":"timestamp",
"type":"long"
},
{
"name":"tags",
"type":[
{
"type":"map",
"values":[
"null",
"string"
]
},
"null"
]
},
{
"name":"metaId",
"type":"long"
},
{
"name":"strings",
"type":[
{
"type":"array",
"items":[
"null",
"string"
]
},
"null"
]
},
{
"name":"bytes",
"type":[
{
"type":"array",
"items":[
"null",
"bytes"
]
},
"null"
]
},
{
"name":"ints",
"type":[
{
"type":"array",
"items":[
"null",
"int"
]
},
"null"
]
},
{
"name":"longs",
"type":[
{
"type":"array",
"items":[
"null",
"long"
]
},
"null"
]
},
{
"name":"floats",
"type":[
{
"type":"array",
"items":[
"null",
"float"
]
},
"null"
]
},
{
"name":"doubles",
"type":[
{
"type":"array",
"items":[
"null",
"double"
]
},
"null"
]
},
{
"name":"booleans",
"type":[
{
"type":"array",
"items":[
"null",
"boolean"
]
},
"null"
]
},
{
"name":"updatesLong",
"type":"long"
}
]
}