上一篇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"
        }
    ]
}