编码和模式——《Designing Data-Intensive Applications》读书笔记5

进去及第四回了,本篇主要聊的点是编码(也即是序列化)与代码升级的有状况,来梳理存储其中涉及到的编解码的流水线。目前主流的编解码便是缘于Apache的Avro,来自Facebook的Thrift与Google的Protocolbuf,在本篇之中,我们为会挨个梳理各种编码的优点和痛点。

《码农周刊》由于微博微信账号 developerWorks 创建。developerWorks 一直专注让IT技术干货分享,目前粉丝曾逾7万。

1.非二进制的编码格式

程序通常因为至少少种植不同的代表法处理多少:

1、在内存中,数据是保存在对象、结构、列表、数组、哈希表、树、等等。这些数据结构在内存之中被优化为CPU可以快速访问同操作的组织(一般性就是操作系统的职责,并不需要程序员操心)。

2、而当您想将数量形容副一个文件或者经过网络发送它常,你不能不管它编码成某种形式之字节序列(例如,一个JSON文档)。

因此,我们得简单栽样式中的某种转换。(内存以及其它位置)翻译由外存中表示的多寡称编码(也称序列化),反的谓解码(反序列化)。

习以为常编码有如下几栽格式:

  • 特定的语言格式
    森编程语言都针对编码有搭的支撑,用于将内存对象编码成字节序列。例如:Java的java.io.Serializable
    , Ruby的Marshal,
    Python的pickle。但是这些编程语言内置的库存在一些好层次之题目。
  • 编码通常和特定的编程语言捆绑于一起,用任何一样种语言读取数据是老大不方便的
  • 为了当一如既往对象类型中恢复数据,解码过程需要会实例化任意类,如果攻击者可被您的应用程序解码任意字节序列,则它们得以实例化任意类。这常是高枕无忧问题之来源。
  • 频率(用于编码或解码的CPU时间,以及编码结构的大大小小),java内置编码库臭名昭著的即是那糟糕之变现与臃肿的编码

  • JSON、XML与CSV
    面立几乎种格式,也是咱以编码之中时来看的。

  • XML的叙说良精准,但是以过度冗长。
  • JSON的流行主要归功给它在Web浏览器中之坐支持(由于她是JavaScript的一个子集)和相对于XML的简单性。
  • CSV是另外一样种流行的以及语言无关之格式,尽管功能不愈。

JSON、XML和CSV都是文本格式,因此还有所一定之可读性。但她们啊产生如下一些微妙的题目:

  • 有关数字之编码有成千上万歧义。在XML和CSV中,不可知分恰好由数字组合的数字和字符串(除了引用外部模式)。JSON区分字符串和数字,但她不区分整数和浮点数,也无克认同精度。
  • JSON以及XML为Unicode字符串的支撑,但她们不支持二上制字符串(字节序列没有字符编码)。
  • 对于XML和JSON,都发可卜的模式支持。这些模式语言非常强大,因此学习和贯彻起来相当复杂。而CSV没有任何模式,因此需要应用程序定义每个行与排的意思。如果应用程序添加了新行或列,则要手动处理该更新。CSV是一个一定模糊的格式(出于是劈隔符的由来)

网页版 | 高效订阅《码农周刊》

2.二进制的编码格式

老二进制的编码格式通常是太严密的编码格式,对于一个稍之数据集,编码大小的纯收入是不值一提的,但如果进入百万兆字节的数据集,数据格式的选项就会时有发生酷死之熏陶了。接下来我们来拘禁一个通过JSON描述的数据结构:
图片 1

  • MessagPack
    咱来探视通过MessagePack进行第二上前制编码之后的JSON格式:
    图片 2
    老二上制编码长度也66个字节,这不过比81字节的文本JSON编码小了一点。通过这样的长空压缩便丧失了可读性的涵养,我们来探有木有更可以之解决智。
  • Thrift
    以Thrift中之数量进行编码,需要先在Thrift接口定义语言(IDL)中描述这样的模式:
    图片 3
    当Thrift之中存在个别栽不同之第二进制编码格式,一种植是一直利用二上制编码的Binary格式,另一样栽则是使压缩后的Compact格式,我们来挨家挨户看两者的界别。

图片 4
Binary格式编码之后也59个字节大小,并且每个字段都生一个种类注释(用于指示它是字符串、整数、列表等),并当得常指定长度指示(字符串的长短、列表中项的数码)。但是和MessagePack相比就是节省了字段名等信息,取而代之的凡字段标记(1,2及3),这些是起于模式定义中之数字。字段标记类似于字段别名,它们是同种植精简之计来讲述我们所讨论的字段,而不必拼写字段名称。从而减少了第二迈入制编码的高低。

图片 5
Compact格式它涵盖相同的音信才出34独字节。它经过将字段类型及标记号打包改成一个字节,并使可转换长整数来兑现就或多或少。它不是啊1337声泪俱下以八个一体化的字节,而是用简单单字节编码,每个字节的高位用来指示是否还有复多的字节要来。这象征64届63中间的数字用一个字节编码,8192交8191之间的数字用简单只字节编码,较充分的数字运用更多字节。

  • ProtocolBuf
    Protocolbuf(只来一个二进制编码格式)相同之数据编码如下图所示。它个包装略有不同,但Thrift的Compact格式大同小异。Protobuf以33字节匹配相同的记录。
    图片 6

  • Avro
    Avro是一个二进制编码格式,它是发源于开源项目Hadoop,来当Thrift的轮换方案有的,我们来看看通过Avro编码之后的记录,又是什么的吗?
    图片 7
    当Avro模式之中无标记号。将一如既往的数量进行编码,Avro二进制编码是32只字节长,是上述编码之中最严谨的。检查上述的字节序列,并没有标识字段或数据类型。编码简单地由于连接在合的值组成。在解析二进制数据经常,通过下模式来确定每个字段的数据类型。这意味要读取数据的代码和写副数据的代码用完全相同的模式,二进制数据才能够叫正确地解码。

往期最为受欢迎文章

3.模式升级和演变

乘势应用程序的出,模式不可避免地索要随着岁月一旦反。而在是进程里面,二进制编码同时保障为后和前进兼容性呢?

  • 字段标记
  • 自示例中得以视,编码的笔录就是编码字段的串联。每个字段由标签号及注释的数据类型识别(如字符串或整数)。如果无安装字段值,则只有待从曾经编码的记录被看看略该字段值。因此字段标记对编码数据的意思至关重要。我们好变更模式面临字段的名目,因为编码的数量没有引用字段名称,但非能够改字段的符号,因为当时将设拥有现有编码数据无效。
  • 可以通过抬高一个新的标记号的法子朝着模式上加新字段。如果原本代码(不懂得乃添加的初标记号)试图读取由新代码编写的多寡,包括一个初字段,该字段的标记号不识别,它可简单地忽视该字段。数据类型注释允许分析器来确定要过了多少字节。因为每个字段都发出唯一的标记号,新代码可以无缝连接老的数额,因为标记号仍然拥有同样之义。但是,如果是加加了一个新字段,则无克使它们化必备字段。如果如上加一个字段并要其变为必不可少的字段,那么要新代码读取旧代码编写的数目,则该检查将败,因为本来代码用不见面写副您添加的初字段。因此,为了保持为后兼容性,在开头部署模式之后加上的每个字段必须是可选的要有所默认值。
  • 去除字段就如上加字段一样,这表示只能去一个可选的字段(必填字段非克于删),而且你不可知重复以同一之标记号(因为你或许还有一个包含旧标记号的数,该字段必须叫新代码忽略)。

  • 数据类型
    如何改字段的数据类型?例如,将32各项整数转换为64各整数。新代码可以好容易地朗诵取旧代码编写的数,因为解析器可以据此零填充任何丢失的各。但是,如果原本代码读取由新代码编写的数码,旧代码仍然以32各类变量来保存值。如果解码的64各项值未吻合32各,会给截断。
    Protocolbuf并从未一个列表或累组的数据类型,而是发生一个再次的符字段。可以用可选取的(单值)字段转换为重新的(多值)字段。读取旧数据的初代码看到一个享有零个或一个因素的列表(取决于字段是否存在);读取新数据的旧代码只盼列表的尾声一个素。而Thrift有一个专门的列表数据类型,这是参数列表中之数据类型。这不容许像Protocolbuf那样从单值到多值的升级,但它们拥有支撑嵌套列表的长。

  • 动态变化模式
    Avro最要命之特性是支撑了动态变化模式,它的核心思想是编码者与解码者的模式可不同,事实上他们只需要配合就可以了。相比于Protocolbuf和Thrift,它并无带有其他标签数字。每当数据库模式发生变化时,管理员要手动更新从数据库列名到字段标记的照耀。而Avro是历次运行时大概地展开模式转换。任何读取新数据文件的先后都见面感知到记录的字段发生了转。

怎么成为全栈工程师?(@知乎)  

4.小结

编码的底细不仅影响到工作效率,更关键的是会潜移默化至应用程序和软件之架。Prorotocol
Buf,Thrift 与
Avro,都使一个模式来叙述一个二进制编码格式。它们的模式语言比XML模式或JSON模式一旦简明得几近,它支持更详细的印证规则,并且能再次好之进展模式之嬗变升级,在性及吧闹矣再次好之晋升。

顶尖日志实践(王健)
 

分布式系统的事务处理(@左耳朵耗子)
 

[PDF]
蔡学镛架构设计方法(@蔡学镛)
 

WhatsApp
架构设计(最新版本)
 

[PDF] Thinking Clearly about Performance (Cary
Millsap)
 

[PPT] 深入浅出 Spark
(@CrazyJvm)
 

RESTful API 设计指南
(@ruanyf)
 

洋洋洒洒文章:深入解析
Redis(@郑思愿daoluan)
 

MySQL
在巨型网站的应用架构演变(@殷伟雄)
 

Google Java
编码规范
 

90只高质量之 Java
问答
 

C 语言高级编程指南 (Peter
Facka)
 

全栈 Python (Matt
Makai)
 

七上学会
NodeJS
 

Python
入门教程(@廖雪峰)
 

C 程序中的内存管理 (Alex
Smith)
 

C/Go/Python 学习笔记
(qyuhen)
 

[PDF] C/C++
代码优化小贴士
 

Node.js 新手指南 (Manuel
Weiss)
 

前端开发框架对比(王芳侠)
 

Swift 简介
(@peng_gong)
 

Apple 官方教程《The Swift Programming
Language》
 

机器上入门 (Adam
Geitgey)
 

一个免费编程电子书网站
 

[译] 55
分钟学会正则表达式(@Hi_DosLin)
 

[PDF] Linux 命令快速参考
(LinOxide)
 

怎么参与一个 GitHub
开源项目?
 

免费之编程中文图书索引
(JustJavaC)
 

Git
入门教程
 

Sublime Text 快速入门指南 (Jennifer
Mann)
 

编程精华资源大汇总
(ITeye)
 

100
本免费的安书籍
 

[PDF]
高级数据结构大全
 

[PDF]
存储系统的那些从(@许式伟)
 

每周一写

《文明的才》  吴军

继创作《浪潮的巅峰》、《数学的美》事后,吴军博士将眼光拉回到人类文明史,以他享有的意见与纵横捭阖的亲笔由对人类文明产生了重点影响却在过去被忽略的史故事里,选择了有趣的几十单部分特写,有机地恢复出人类文明发展之全貌。

Geek 周边

LAMY Safari –
书写工具市场之大个儿  

乃有多久没写字了?

办事机遇

[杭州]
阿里巴巴  

Java 高级开发工程师(15-30k)

[杭州]
大搜车  

Android 工程师(10-15k) iOS 工程师(10-15k) Java
工程师(8-16k) 测试工程师(7-14k) 前端工程师(可实习)(8-16k)

[北京]
大鱼  

Rails 工程师(8-20k) iOS 工程师(12-20k) Android
工程师(12-20k) 前端工程师(8-20k)

[北京]
深思洛克软件技术股份有限公司  

Windows C/C++ 程序员(8-15k) Java 程序员(8-15k)

[广州]
向日葵保险网  

网架构师(12-20k) 高级 Java 工程师(8-16k) 高级 Rails
开发工程师(8-16k) 运维经理 高级运维工程师(5-10k) 高级前端开发工程师 Web
前端开发主管

[南京]
孢子社区  

全端工程师

还多干活机会  

在招人?欢迎将招聘启事发送至 job@manong.io

《码农周刊》鉴于微博微信账号 developerWorks 创建。developerWorks 一直专注让IT技术干货分享,目前粉丝都过7万。

网页版 | 飞订阅《码农周刊》

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图