之前我们分析了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
,缺点在于每个实现类都要自定义序列化、分序列化的过程。在性能要求高、数据交换频繁的内部服务中可以借鉴该设计。