protobuf compress - landon30/Bulls GitHub Wiki
proto消息过长
- BullsWeakNetFilter#filterWrite
GC_SUDDENCRIME_ATTACK_RESULT = 70012 击杀结果包括战报(十几个Round) netMessage.getData().length = 52826 (short) data.length = -12710 Short.MAX_VALUE = 32767
- 即包括战报的数据长度大约50k,超出了长度字段(short)
- 之前的测试是没有加snappy压缩,可以先测试一下用snappy压缩之后战报数据大小
- 52732(压缩前) 5585(压缩后)
- snappy的压缩比还是很不错
- 保险起见,一定要将长度字段的short(16bit)要改为int(32bit)
- 之前的测试是没有加snappy压缩,可以先测试一下用snappy压缩之后战报数据大小
- 测试protobuf vs snappy
- 从测试输出结果看
- String类型, pb压缩不明显
- json重复key多,snappy压缩明显
- 总结1
- Protocol buffers are an efficient binary serialization format, not a compressor
- strings do not become any smaller as their payload remains the same
- If you need to reduce the size, you could either gzip the data or use an application-level dictionary to substitute large strings with something smaller
- 即pb和snappy解决的是不同的问题,一起用比较好
- 总结2:
- A
- 我们以前是消息是否压缩是开发人员控制,消息协议头里有个标志本消息是否进行了压缩处理。因为压缩还是要消耗不少性能
- 登录、战斗、同屏,消息比较大,进行压缩。其它就不压缩追求性能
- 还做过一种,是框架底层发现消息太大就自动压缩
- 现在的项目对性能要求不高,瓶颈不会在压缩上,还好
- B
- 我们现在是支持不压缩的,但是不建议不压缩,大多数情况下,压缩会有效果的,不管是不是PB,越压越大的情况少
- 业务里的消息大小,是控制不住的
- 这就是看主程的控制粒度了, 如果哪个新来的开发不知道这些细节,哪天写个大数据接口出来,没压缩,那就挂了。snappy 经过了验证,性能不会有太大问题的,建议统一处理,上层就不需要区分了
- 大多数情况下,不用太过于追求极致的细节性能优化,做的傻一些,灵活度低一些,稳定是第一优先级。
- 统一压缩
- 网络层自始至终是不允许自己修改的
- landon:这个确实比较底层 如果擅自修改 引起其他不必要的问题 就不好了;MinaTypicalNetIO这个部分确实是历史原因,不过无论是这个mina或者还是后续的其他网络库 网络层其实也不建议修改;除非有特别需求 但通常这个需求可能是通用的
- A
- 总结3:
- landon:之前一直觉得用protobuf就不用压缩了,但其实还是没有深入理解。在战报传输这种大量的重复字符串的情况下,protobuf结合压缩如snappy是非常好的解决方案
@Test
public void testProtobufCompresss() {
// 这里省略输入战报字符串,太长
String result = "{\"battleResult\":-1....}";
BattleResultReplayMsg.Builder builder = BattleResultReplayMsg.newBuilder();
builder.setReplayResult(result);
byte[] bytes = builder.build().toByteArray();
// protobuf.byte:43539
System.out.println("protobuf.byte:" + bytes.length);
ICompressAlgorithm algorithm = CompressAlgorithmFactory
.create(DataCompressType.SNAPPY.getType());
byte[] compressedData = algorithm.compress(bytes);
// compressedData.byte:4872
System.out.println("compressedData.byte:" + compressedData.length);
}