之前我们分析了Elasticsearch中网络数据读写的过程。本文我们来学习并实践一下其中针对stream的读写。
前文进行了网络数据读写的分析,我们注意到三个重要的接口和类:
Streamable:定义stream读写的接口。实现该接口的类可以向StreamOutput中写入数据,也可以从StreamInput中读取数据。StreamInput:读取stream的抽象类。定义了从stream读取各种数据类型(包括byte、int、short、long、double、list、map等等)的方法。StreamOutput:写入stream的抽象类。定义了向stream写入各种数据类型的方法。
针对stream的功能测试,我从Elasticsearch中分离出核心的代码,详见:elasticsearch-stream
使用
某个类需要添加stream的读写功能可以继承Streamable接口,实现readFrom和writeTo方法。如User.java所示,在readFrom和writeTo中自定义对User类的读写。
定义了Streamable接口的实现类,可以非常方便地将该实现类写入StreamOutput或者从StreamInput中读取该类的内容。如RWTest.java所示。
性能测试
从直觉上看,stream因为直接读写二进制流,性能上会比较好。为了验证我们的直觉,我们设计测试用例来对比stream操作与json操作的性能。代码见:PerformanceTest.java。
该测试是一个不太严格的测试,仅仅通过它对stream的性能有个直观的认识。
对于写操作(序列化),stream的性能大概是json的2.4倍,stream生成的数据大小大概是json的41%。
对于读操作(反序列化),stream的性能大概是json的2.6倍。
总结
Elasticsearch设计的这套数据流读写框架,无论从性能还是从需要传输的数据量角度来看都胜过json,缺点在于每个实现类都要自定义序列化、分序列化的过程。在性能要求高、数据交换频繁的内部服务中可以借鉴该设计。