message pack,一种非常有潜力的数据格式,市面上还有其他的格式比如json,xml,bson,甚至一些标记语言(html,markdown,yaml)和他们的字符编码utf-8。这些看似毫无关联的标记语言,文件格式和字符编码其实都属于一个大类:序列化格式。
今天来做一个全面对比,对他们的优缺点,性能,应用场景做一个全面分析。
首先的问题是:
啥TM是降维打击?
用一句话说,降维打击是将多维度的数据序列化成一维的通用格式以被不同的平台理解。
什么是多维数据?
从逻辑上不是线性排列的数据就是多维的,最常见的就是树形数据结构,比如引用数据类型:我们在对一个对象进行深拷贝的时候常常需要递归地遍历嵌套树的每一层,才能得到这个对象的全部信息。但是这种树形结构的基本生存资料是对象所在的平台比如JavaScript运行环境,同一个JS对象不能原封不动地拿到Java的环境下使用(虽然感觉底层原理都差不多),反之亦然,就是这个简单的道理:多维数据结构“不通用”,虽然JS对象和Java对象都是多维度的,但多维结构不同。
如何实现跨平台的通用数据格式呢,只能使用一个维度的数据结构,比如字符串(json)。
再举个例子解释什么是序列化,如果不感兴趣可以跳过,直接看之后的各种格式。
抛出一个场景:你要收集一组人的信息:name, last name, nickname, date of birth, 他们的乐器instruments。你可以轻而易举地制作一个电子表格:定义列,将每一行作为一个条目。你甚至还可以定义表格的schema:date of birth必须是number类型,instruments是枚举类型:
name | last name | dob | nickname | instruments |
---|---|---|---|---|
William | Bailey | 1962 | Axl Rose | vocals, piano |
Saul | Hudson | 1965 | Slash | guitar |
你上述的做法其实定义了一个数据结构,如果你只是想在当前的Excel环境下愉快地使用这个表格那没有任何问题,如果想用这个表格和其他人交流(或者和一个服务器,数据库交互),问题就出来了:无论你保存成一个.xlsx文件还是截图发给对方,你的表格都经历了序列化的过程(excel文件序列化和图片序列化)。
序列化也叫编码,与之对应的逆操作就是反序列化或者解码,一维数据抵达不同平台(这里的浏览器,服务器和数据库都是不同的平台)后就要进行反序列化,从而将数据改造成易于自己理解的多维结构。
还有一个很好的解释是,网络只能传输一维的数据流。
各大降维技术优缺点
1 简单易用开发成本低
5 可以即时编译,用括号和引号闭合数据块的语法可以监测网络是否中断(因为代码可以突然解析失败),这一点优于其他的标记语言比如yaml和markdown。
1 体积大,影响高并发
之前例子里提到的电子表格用json序列化以后是这样的:
[
{
"name": "William",
"last name": "Bailey",
"dob": 1962,
"nickname": "Axl Rose",
"instruments": [
"vocals",
"piano"
]
},
{
"name": "Saul",
"last name": "Hudson",
"dob": 1965,
"nickname": "Slash",
"instruments": [
"guitar"
]
}
]
总结:JSON流行的原因自然离不开它爸爸(JavaScript)。作为JS对象的子集,json是最简单最通用的应用协议之一,使用广泛,开发效率高,但性能相对较低,维护成本较高,所以json有望被message pack取代,参考我的这篇文章。
Protobuf是一种以有效并可扩展的格式编码结构化数据的方式。
1 跨语言,可自定义数据结构。
1 二进制格式,可读性差(抓包dump后的数据很难看懂)
总结:简单快速上手,高效兼容性强,维护成本较高。
1 跨语言,多语言支持(超多)
4 提供流接口
1.缺乏复杂模型支持。【但可定制】
总结:高性能但目前的维护成本较高。
YAML
YAML: YAML Ain’t Markup Language.
可我觉得yaml就是个“markup language”,因为yaml.org官网就是用yaml写的:
yaml的可读性可能比json还强,因为它用空白字符实现缩进,取代了括号和引号。yaml还支持特殊的“内部引用”语法,给人一种“可编程”的感觉。事实上yaml的规格超级巨大,非常复杂,和轻量级的json形成鲜明对比
之前提到的电子表格用yaml序列化以后是这样的:
- name: William
last name: Bailey
dob: 1962
nickname: Axl Rose
instruments:
- vocals
- piano
- name: Saul
last name: Hudson
dob: 1965
nickname: Slash
instruments:
- guitar
1 序列化和RPC支持一站式解决,比pb更方便
2 不支持双通道
总结:跨语言、实现简单,初次使用较麻烦,需要避免使用问题和场景限制。
BSON
bson有以下特性:
方便存储二进制信息:更适合交换图像和附件
专为快速内存操作而设计
简单的规范:像JSON一样,BSON有一个非常简短的规范
BSON是MongoDB的主要存储结构和传输协议:BSON旨在轻松遍历
额外数据类型:
double(64位IEEE 754浮点数)
date(自Unix纪元以来的整数毫秒数)
字节数组(二进制数据)
BSON对象和BSON阵列
JavaScript代码
MD5二进制数据
正则表达式
BSON的名字取得倒是好听(Binary JSON),容易让人产生一种BSON就是标准二进制json的错觉,我们不能被这个标题党忽悠。
MessagePack VS BSON
这2款产品都宣称是二进制的json,关于2者的优劣一直争论不休。事实上msgpack和bson并不是竞争关系,而是适用于不同场景:
msgpack适用于空间效率要求高的场景:网络传输;
bson适用于时间效率要求高的场景:数据库的CRUD;
所以msgpack更加紧凑,体积小,符合最优编码;而bson比较冗长,但增删改查比较快。
StackOverflow上MessagePack的原作者也给出了自己的看法,客观的说明了msgpack和bson的应用场景:msgpack为网络服务,bson为数据库服务。
但话说回来,现实因素有时候会阻碍我们去使用更新更高效的技术,就像python3之于python2一样。不过我想了一下,我们开发者或者企业家不都是创新者吗?
(完)
【日记】
是时候引入中文标点符号来扩充编程语言的语法了!
翻来覆去的那几个括号和引号明显不够用了,写一个正则表达式要加好几个转义字符,定义一个对象非要用括号来封装成表达式。以上不合理之处都可以通过在语法中加入中文的标点符号来解决:
¥ ; : “ ” ‘ ’ 【 】 、 ? ! … ( ) — 。 , · 《 》
中文有这么多天然的对称字符和不对称字符你们都不用,而且一般字体都符合方块字的正方尺寸,易区分,可读性强。当然这梦一时半会估计实现不了,但如果在未来的编程语言中真的出现了中文语法,你是高兴呢还是不高兴呢?留下你的评论。