降维打击(序列化)的流行手段

上次介绍了message pack,一种非常有潜力的数据格式,市面上还有其他的格式比如jsonxmlbson,甚至一些标记语言(htmlmarkdownyaml)和他们的字符编码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文件序列化和图片序列化)。

序列化也叫编码,与之对应的逆操作就是反序列化或者解码,一维数据抵达不同平台(这里的浏览器,服务器和数据库都是不同的平台)后就要进行反序列化,从而将数据改造成易于自己理解的多维结构。

还有一个很好的解释是,网络只能传输一维的数据流。

各大降维技术优缺点

JSON

优点

1 简单易用开发成本低 2 跨语言 3 轻量级数据交换 4 非冗长性(对比xml标签简单括号闭环)

5 可以即时编译,用括号和引号闭合数据块的语法可以监测网络是否中断(因为代码可以突然解析失败),这一点优于其他的标记语言比如yaml和markdown。

缺点

1 体积大,影响高并发 2 无版本检查,自己做兼容 3 片段的创建和验证过程比一般的XML复杂 4 缺乏命名空间导致信息混合

之前例子里提到的电子表格用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

Protobuf是一种以有效并可扩展的格式编码结构化数据的方式。

优点

1 跨语言,可自定义数据结构。 2 字段被编号,新添加的字段不影响老结构。解决了向后兼容问题。 3 自动化生成代码,简单易用。 4 二进制消息,效率高,性能高。

缺点

1 二进制格式,可读性差(抓包dump后的数据很难看懂) 2 对象冗余,字段很多,生成的类较大,占用空间。 3 默认不具备动态特性(可以通过动态定义生成消息类型或者动态编译支持)

总结:简单快速上手,高效兼容性强,维护成本较高。

MessagePack

优点

1 跨语言,多语言支持(超多) 2 It’s like JSON.but fast and small.序列化反序列化效率高(比json快一倍),文件体积小,比json小一倍。 3 兼容所有json数据格式,独有二进制类型,date类型等。

4 提供流接口

缺点

1.缺乏复杂模型支持。【但可定制】 2.流行度不高,原生支持的平台不多。

总结:高性能但目前的维护成本较高。

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

Thrift(Facebook)

优点

1 序列化和RPC支持一站式解决,比pb更方便 2 跨语言,IDL接口定义语言,自动生成多语言文件 3 省流量,体积较小 4 包含完整的客户端/服务端堆栈,可快速实现RPC 5 为服务端提供了多种工作模式,如线程池模型、非阻塞模型

缺点

2 不支持双通道 3 rpc方法非线程安全,服务器容易被挂死,需要串行化。 4 默认不具备动态特性(可以通过动态定义生成消息类型或者动态编译支持) 5 开发环境、编译较麻烦

总结:跨语言、实现简单,初次使用较麻烦,需要避免使用问题和场景限制。

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一样。不过我想了一下,我们开发者或者企业家不都是创新者吗?

(完)

【日记】



是时候引入中文标点符号来扩充编程语言的语法了!

翻来覆去的那几个括号和引号明显不够用了,写一个正则表达式要加好几个转义字符,定义一个对象非要用括号来封装成表达式。以上不合理之处都可以通过在语法中加入中文的标点符号来解决:

¥ ; : “ ” ‘ ’ 【 】 、 ? ! … ( ) — 。 , · 《 》

中文有这么多天然的对称字符和不对称字符你们都不用,而且一般字体都符合方块字的正方尺寸,易区分,可读性强。当然这梦一时半会估计实现不了,但如果在未来的编程语言中真的出现了中文语法,你是高兴呢还是不高兴呢?留下你的评论。

本文分享自微信公众号 - WebHub(myWebHub)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-08-19

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券