介绍

MessagePack是一种高效的二进制序列化格式。它允许您像JSON一样在多个语言之间交换数据。但是,它更快并且更小。小整数被编码为一个字节,和典型的短字符串只需要除了字符串本身的一个额外字节。

JSON为什么会变小了?

我们都知道上文json总长度占27个字符,这属于JSON的标准格式,心细的你发现:引号(")、布尔型等在JSON中出现了多次,能否将多次出现的长字符用一些简易的短字符去描述,这就是Messagepack底层的理论支持。

采用Messagepack转换后的格式如下,我们将长JSON再次减短,节省网络传输带宽,提高传输效率和存储效率。

解释为:82开始代表有2两个json字段;a7代表后续紧跟7个字符是json字段名;c3代表值为true;a6代表后续有6个字符;0代表值为零。

不考虑复杂格式,解析办法为将收到到的字符按照占位分成五个,即可实现json的还原。一个很短JSON减少了9个字符,这就是messagepack的强大之处。

MessagePack的核心压缩方式:

  1. true、false 之类的:这些太简单了,直接给1个字节,(0xc2 表示true,0xc3表示false)

  2. 不用表示长度的:就是数字之类的,他们天然是定长的,是用一个字节表示后面的内容是什么东东,比如用(0xcc 表示这后面,是个uint 8,用oxcd表示后面是个uint 16,用 0xca 表示后面的是个float 32).

  3. 不定长的:比如字符串、数组,类型后面加 1~4个字节,用来存字符串的长度,如果是字符串长度是256以内的,只需要1个字节,MessagePack能存的最长的字符串,是(2^32 -1 ) 最长的4G的字符串大小。

  4. ext结构:表示特定的小单元数据。

  5. 高级结构:MAP结构,就是key=>val 结构的数据,和数组差不多,加1~4个字节表示后面有多少个项。

这个是官方的数据表示结构文档:https://gist.github.com/frsyuki/5432559

总的来说,MessagePack对数字、多字节字符、数组等都做了很多优化,减少了无用的字符,二进制格式,也保证不用字符化带来额外的存储空间的增加,所以MessagePack比JSON小是肯定的,小多少,得看你的数据。如果你用来存英文字符串,那几乎是没有区别….

MessagePack的特点如下:

  • 编解码高效,性能高;
  • 序列化之后码流小;
  • 支持跨语言。

编码原理

为什么messagepack比json序列化使用的字节流更少, 可通过图1-1、图1-2有个直观的感觉。

messagepack的具体的消息格式如图1-3所示,messagepack的数据类型主要分类两类:固定长度类型和可变长度类型。

messagepack的具体类型信息表示如图1-4所示。

用途

MessagePack主要用于结构化数据的缓存和存储:

1.存在Redis中,因为它比json小,可以省下一些内存来,速度也比json快一些,速度自然快一个档次。当然,也有一种情况,我在Redis中存json,然后直接出来就是页面可用的json,都不用解析json了(当然这个在实际开发中比较少见)。

2.存在可以持久化的Key-val存储中。

参考: Messagepack原理(更快更小的Json) 新型序列化类库MessagePack,比JSON更快、更小的格式