文档章节

Thrift二进制序列化TCompactProtocol与TBinaryProtocol的原理和区别

LarrySu
 LarrySu
发布于 2016/09/26 16:45
字数 1117
阅读 1728
收藏 1

Thrift二进制序列化协议中,默认为TBinaryProtocol,关于TCompactProtocol的说明,为高效密集型的二进制序列化(varint).那么TCompactProtocol相对于TBinaryProtocol是怎样做到高效密集的呢?TCompactProtocol是否一定比TBinaryProtocol高效?

我们以比较常用的i32类型为例,来解释一下两种方式各自的原理:

TBinaryProtocol
处理i32整型数据类型时,定义的是4个字节的数组,32位的长度正好可以保存到这4个字节组当中.如果我们分别以n1~n32来表示第1位到第32位,那么这个数组的数据结构应该为以下结构:
i32out[0] {n1  ~ n8 }
i32out[1] {n9  ~ n16}
i32out[2] {n17 ~ n24}
i32out[3] {n25 ~ n32}

这样的实现很简单.
对于其它类型,比如i16,也是类似的原理,不过是以2个字节的数组保存,在此不再说明了.

TCompactProtocol
在处理i32整型数据类型时,与TBinaryProtocol完全不同,采用的是1~5个字节组来保存.依然以n1~n32来表示第1位到第32位,数据结构应该为以下结构:
i32out[0] {1 , 0 , 0 , 0 , n1 ~ n4}
i32out[1] {1 , n5 ~ n11}
i32out[2] {1 , n12 ~ n18}
i32out[3] {1 , n19  ~ n25}
i32out[4] {0 , n26  ~ n32}

这是一种极端情况,5个字节全部占满.

 

很显然,这样做比TBinaryProtocol复杂得多,而且还多了1个字节,并没有达到密集的目的.那是不是说明TBinaryProtocol更好?先不急着下结论,举个具体一点的例子来说明两种实现的区别.
假如我们需要序列化一个十进制数值'10',那么它的二进制表示方式应该为'1010',只用了4位,但i32会在前面自动补0,则是'00000000000000000000000000001010',那么如果使用TBinaryProtocol方式来保存,则应该为以下结构:
i32out[0] {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0}
i32out[1] {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0}
i32out[2] {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0}
i32out[3] {0 , 0 , 0 , 0 , 1 , 0 , 1 , 0}

这样有什么问题呢?那就是大量补足的0占用了宝贵空间.
接着我们再来看看TCompactProtocol会怎样保存'10'这个数值:
i32out[0] {0 , 0 , 0 , 0 , 1 , 0 , 1 , 0}
TCompactProtocol只用了1个字节,而TBinaryProtocol依然用了4个字节.这就是为什么说TCompactProtocol高效密集型的二进制序列化的原因.

接着我们来分析一下TCompactProtocol的保存规则.
TCompactProtocol每个字节的第1位是状态位,第2位到第8位保存具体的数据.这有别于TBinaryProtocol的1到8位全部保存具体数据.这也是为什么极端情况下TCompactProtocol比TBinaryProtocol多占1个字节的原因.
TCompactProtocol的字节中第1位状态位的意思是标记此字节后是否还有数据.1为有数据,0为没有数据.
为了更容易理解,我们再举一个例子.
用TCompactProtocol来序列化十进制数值'300',二进制应该为'100101100',用TCompactProtocol方式来保存则为如下结构:
i32out[0] {1 , 0 , 0 , 0 , 0 , 0 , 1 , 0}
i32out[1] {0 , 0 , 1 , 0 , 1 , 1 , 0 , 0}

这里将'100101100'拆分为了2部分,'10'和'0101100',在i32out[0]中保存了'10',并在第1位记为'1'来表示后面还有,第7位和第8位保存'10',不足的几位(第2位到第6位)补0,所以i32out[0]为'10000010',在i32out[1]中保存了后面的'0101100',并在第1位记为'0'来表示后面没有了,则第1位为'0',所以i32out[1]为'00101100'.
TCompactProtocol以这样的原理来达到压缩的目的.

最后引用一张图来展示TCompactProtocol的i32数据('106903'数值序列化后)的结构:

    

总结一下:
TCompactProtocol在数据量较小的情况下比TBinaryProtocol序列化更省空间.
在i32数值或者string的长度大于'2097151'时(二进制21个'1'),与TBinaryProtocol方式占用的空间一样,都是4个字节.
在i32数值或者string的长度大于'268435455'时(二进制28个'1'),TCompactProtocol反而会比TBinaryProtocol多占用1个字节的空间.(其它数据类型依此类推,不做阐述了)

 

© 著作权归作者所有

LarrySu

LarrySu

粉丝 4
博文 6
码字总数 3481
作品 2
其它
其他
私信 提问
架构设计:系统间通信(12)——RPC实例Apache Thrift 中篇

(接上文《架构设计:系统间通信(11)——RPC实例Apache Thrift 上篇》) 3、Aapche Thrift详解 在《架构设计:系统间通信(10)——RPC的基本概念》一文中,我专门介绍了一款RPC规范的具体...

引鸩怼孑
2016/01/29
110
0
Thrift之Protocol源码分析

 之前写过两篇关于 Thrift 的相关文章。 Thrift源码剖析 Thrift异步IO服务器源码分析 也算是对Thrift比较熟悉,不过对 Thrift 里面的 Protocol 部分还是黑盒使用。 虽然大概能猜到具体实...

nothingfinal
2016/04/23
0
0
Thrift 协议栈

Thrift 协议栈 为了更好地理解Thrift的协议栈,推荐阅读Thrift的白皮书,以及Thrift Architecture阐述。 接下来的部分内容,直接来自于上述文档,下面将做简要地叙述Thrift Architecture Run...

zyqJustin
2016/08/04
41
0
接口协议工具thrift1快速入门

简介 Thrift是一种接口描述语言和二进制通讯协议,它被用来定义和创建跨语言的服务。它被当作远程过程调用(RPC)框架来使用,是由Facebook为“大规模跨语言服务开发”而开发的。它通过一个代...

python人工智能找电子书
2018/10/09
0
0
跨语言服务部署框架Thrift简介[转]

参考文档: http://dongxicheng.org/search-engine/thrift-framework-intro/ Thrift是一个跨语言的服务部署框架,最初由Facebook于2007年开发,2008年进入Apache开源项目。Thrift通过一个中间...

强子哥哥
2016/06/25
400
0

没有更多内容

加载失败,请刷新页面

加载更多

Spring Security 自定义登录认证(二)

一、前言 本篇文章将讲述Spring Security自定义登录认证校验用户名、密码,自定义密码加密方式,以及在前后端分离的情况下认证失败或成功处理返回json格式数据 温馨小提示:Spring Security...

郑清
21分钟前
1
0
php yield关键字以及协程的实现

php的yield是在php5.5版本就出来了,而在初级php界却很少有人提起,我就说说个人对php yield的理解 Iterator接口 在php中,除了数组,对象可以被foreach遍历之外,还有另外一种特殊对象,也就是继承...

冻结not
34分钟前
2
0
servlet请求和响应的过程

本文转载于:专业的前端网站➥servlet请求和响应的过程 1.加载 Servlet类被加载到Java虚拟机中,并且实例化。在这个过程中,web容器(例如tomcat)会调用Servlet类的公开无参构造函数,产生一...

前端老手
34分钟前
2
0
golang 1.13 errors 包来了,不用写“err 气功波”代码

引 这篇是对 errors 包 的姿势挖掘 气功波错误代码 从 http.Get()返回的错误 判断 syscall.ECONNREFUSED 错误.以前要对 go 标准库 error 结构有点熟悉,才能写出下面的代码 func CmdErr(err ...

guonaihong
38分钟前
25
0
喜玛拉雅已听书单

时间倒序排 书名 作者 状态 唐砖 孑与2 进行中 死灵之书(克苏鲁神话合集) 阿卜杜拉·阿尔哈萨德 进行中 赡养人类 刘慈欣 完结 赡养上帝 刘慈欣 完结 中国太阳 刘慈欣 完结 中国太阳 刘慈欣...

Alex_Java
39分钟前
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部