高性能的序列化与反序列化:kryo的简单使用
前言:kryo是个高效的java序列化/反序列化库,目前Twitter、yahoo、Apache、strom等等在使用该技术,比如Apache的spark、hive等大数据领域用的较多。
为什么使用kryo而不是其他?
因为性能足够好。比kyro更高效的序列化库就只有google的protobuf了(而且两者性能很接近),protobuf有个缺点就是要传输的每一个类的结构都要生成对应的proto文件(也可以都放在同一个proto文件中,如果考虑到扩展性的话,不建议放在一个proto文件中),如果某个类发生修改,还得重新生成该类对应的proto文件;另外考虑到项目中用的全部是java技术栈,不存在不同编程语言间的兼容性问题,因此最终采用了kryo作为序列化库。
使用场景:(数据交换或数据持久化)比如使用kryo把对象序列化成字节数组发送给消息队列或者放到redis等nosql中等等应用场景。
注意:由于kryo不是线程安全的,针对多线程情况下的使用,要对kryo进行一个简单的封装设计,从而可以多线程安全的使用序列化和反序列化
序列化和反序列化接口设计
/*** 序列化工具(程序调用该接口来实现obj<->byte[]之间的序列化/反序列化)* @author eguid**/ public interface Serializer{/*** 序列化* @param t* @param bytes*/public void serialize(Object t,byte[] bytes);/*** 序列化* @param obj* @param bytes* @param offset* @param count*/public void serialize(Object obj, byte[] bytes, int offset, int count);/*** 反序列化* @param bytes -字节数组* @return T<T>*/public <T>T deserialize(byte[] bytes);/*** 反序列化* @param bytes* @param offset* @param count* @return*/public <T>T deserialize(byte[] bytes, int offset, int count);}使用kryo实现上面的接口
/*** 基于kyro的序列化/反序列化工具* * @author eguid**/ public class kryoSerializer implements Serializer {// 由于kryo不是线程安全的,所以每个线程都使用独立的kryofinal ThreadLocal<Kryo> kryoLocal = new ThreadLocal<Kryo>() {@Overrideprotected Kryo initialValue() {Kryo kryo = new Kryo();kryo.register(ct, new BeanSerializer<>(kryo, ct));return kryo;}};final ThreadLocal<Output> outputLocal = new ThreadLocal<Output>();final ThreadLocal<Input> inputLocal = new ThreadLocal<Input>();private Class<?> ct = null;public kryoSerializer(Class<?> ct) {this.ct = ct;}public Class<?> getCt() {return ct;}public void setCt(Class<?> ct) {this.ct = ct;}@Overridepublic void serialize(Object obj, byte[] bytes) {Kryo kryo = getKryo();Output output = getOutput(bytes);kryo.writeObjectOrNull(output, obj, obj.getClass());output.flush();}@Overridepublic void serialize(Object obj, byte[] bytes, int offset, int count) {Kryo kryo = getKryo();Output output = getOutput(bytes, offset, count);kryo.writeObjectOrNull(output, obj, obj.getClass());output.flush();}/*** 获取kryo* * @param t* @return*/private Kryo getKryo() {return kryoLocal.get();}/*** 获取Output并设置初始数组* * @param bytes* @return*/private Output getOutput(byte[] bytes) {Output output = null;if ((output = outputLocal.get()) == null) {output = new Output();outputLocal.set(output);}if (bytes != null) {output.setBuffer(bytes);}return output;}/*** 获取Output* * @param bytes* @return*/private Output getOutput(byte[] bytes, int offset, int count) {Output output = null;if ((output = outputLocal.get()) == null) {output = new Output();outputLocal.set(output);}if (bytes != null) {output.writeBytes(bytes, offset, count);}return output;}/*** 获取Input* * @param bytes* @param offset* @param count* @return*/private Input getInput(byte[] bytes, int offset, int count) {Input input = null;if ((input = inputLocal.get()) == null) {input = new Input();inputLocal.set(input);}if (bytes != null) {input.setBuffer(bytes, offset, count);}return input;}@SuppressWarnings("unchecked")@Overridepublic <T> T deserialize(byte[] bytes, int offset, int count) {Kryo kryo = getKryo();Input input = getInput(bytes, offset, count);return (T) kryo.readObjectOrNull(input, ct);}@Overridepublic <T> T deserialize(byte[] bytes) {return deserialize(bytes, 0, bytes.length);}测试一下kryo的序列化和反序列化
为什么使用纳秒,而不用毫秒?与java原生的序列化反序列化要耗时几毫秒不同,kryo序列化和反序列化太快了,单个对象的序列化反序列化速度都在0.0x毫秒左右(如果电脑性能更好的话,会更快)
转载于:https://www.cnblogs.com/eguid/p/10195569.html
总结
以上是生活随笔为你收集整理的高性能的序列化与反序列化:kryo的简单使用的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: 列表标签
- 下一篇: SFrame中的apple函数