大数据经典论文解读
徐文浩
bothub 创始人
13843 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 59 讲
大数据经典论文解读
15
15
1.0x
00:00/00:00
登录|注册

11 | 通过Thrift序列化:我们要预知未来才能向后兼容吗?

你好,我是徐文浩。
现在,我们已经解读完了 GFS、MapReduce 以及 Bigtable 这三篇论文,这三篇论文之所以被称为 Google 的三驾马车,一方面是因为它们发表得早,分别在 2003、2004 和 2006 年就发表了。另一方面,是这三篇论文正好覆盖了大数据的存储、大数据的批处理也就是计算,以及大数据的在线服务领域。
相信你到这里,也看到了一个反复出现的关键字,那就是“数据”。在过去的三篇论文里,我们花了很多精力去分析谷歌是如何设计了分布式的系统架构,数据在硬件层面应该怎么存储。其中的很多设计面临的主要瓶颈和挑战,就是硬盘读写和网络传输性能。比如 GFS 里的数据复制,需要走流水线式的传输就是为了减少网络传输的数据量;Bigtable 里,我们会对一个个 data block 进行压缩,目的是让数据存储的空间可以小一些。
那么,我们能不能在“数据”本身上直接做点文章呢?答案当然是可以的,今天这节课,我们就来一起读一篇 Facebook 在 2007 年发表的《Thrift: Scalable Cross-Language Services Implementation》技术论文,它的背后也就是这 Apache Thrift 这个开源项目。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Thrift技术在大数据存储和处理中具有重要意义。它通过跨语言、跨协议和可扩展性的特点,解决了不同编程语言团队之间的协作问题。Thrift的设计清晰、易于扩展,支持多种序列化方式,使得数据序列化后占用的空间尽可能小。通过分析CSV、JSON、Java序列化等方式的优缺点,Thrift逐步迭代到了TCompactProtocol这样一个序列化协议。此外,Thrift通过良好的面向对象设计和分层,使系统具有“正交性”,易于迭代优化。读者通过本文可以深入理解Thrift的数据序列化最优方案、学会根据真实的业务需求进行系统迭代的思路,以及在系统设计中让各个模块具有“正交性”的重要性。文章还提到了Avro等其他数据序列化技术,为读者提供了进一步研究的方向。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《大数据经典论文解读》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(12)

  • 最新
  • 精选
  • 吴小智
    对于思考题,能想到两个问题:1. 每次需要传输到数据多了,对于 RPC 不是长链接交互的场景,每次都需要带上 Header,就跟 HTTP 一样每次都传输了重复的数据;2. 那就是需要每次都要解析 Header ,然后在对数据进行序列化,多做了运算,Thrift 生成代码的方式,就是把解析 Header 的这个计算,直接变成代码了,直接就可以对数据进行序列化,会快一点。
    2021-10-13
    20
  • 在路上
    2007年发表的Thrift论文,提到自己的优点在于提供了一套语言中立的软件栈,以很低的性能代价获得了很高的开发效率和系统可靠性。核心组件包括Types、Transport、Protocol、Versioning和Processors,Types是指跨语言的类型系统,开发者不用定义任何类型的序列化代码,Transport是指开发者可以灵活定义数据的来源和目的地,可能是网络,可能是内存的片段,也可能是文件,Protocol是指数据的序列化和反序列化过程,开发者通常不用关心,如果有需要也可以定制,Versioning是指协议支持版本,使得客户端可以向前向后兼容,Processors指的是数据的处理器,具体的逻辑由开发者实现。这种灵活的软件栈的代价是,The performance tradeoff incurred by an abstracted I/O layer (roughly one virtual method lookup / function call per operation) was immaterial compared to the cost of actual I/O operations (typically invoking system calls),也就是没什么代价。
    2021-10-14
    9
  • 在路上
    徐老师好,TCompactProtocol处理Delta Encoding的方式非常巧妙,通过判断Field第一个字节的高4位是否为0,得知到底是用了一个还是多个字节存储fieldId和fieldType。 readFieldBegin()的部分源码: ``` // mask off the 4 MSB of the type header. it could contain a field id delta. short modifier = (short)((type & 0xf0) >> 4); if (modifier == 0) { // not a delta. look ahead for the zigzag varint field id. fieldId = readI16(); } else { // has a delta. add the delta to the last read field id. fieldId = (short)(lastFieldId_ + modifier); } ``` writeFieldBeginInternal()的部分源码: ``` // check if we can use delta encoding for the field id if (field.id > lastFieldId_ && field.id - lastFieldId_ <= 15) { // write them together writeByteDirect((field.id - lastFieldId_) << 4 | typeToWrite); } else { // write them separate writeByteDirect(typeToWrite); writeI16(field.id); } ``` 直接把IDL写入协议的Header,协议的接收者可以根据Header的信息得知如何解析协议,但是如果每次传输的数据量不大,额外传输的IDL就会成为严重的网络负担。Apache Avro很好的解决了这个问题,在Apache Avro Specification的Protocol Declaration/Protocol Wire Format/Schema Resolution/Parsing Canonical Form for Schemas四个章节中详细地描述了整个过程。 谁负责写数据,就以谁的IDL为准。当客户端第一次发起一种请求时,会先发送一条消息(HandshakeRequest),告知服务端接下来的请求的IDL,服务端会响应消息(HandshakeResponse),告知服务端针对这个请求响应的IDL。之后再发起相同类型的请求时,只需要发送IDL的指纹,指纹对的上,接收方就使用缓存的IDL,如果对不上,接收方会要求发送方重发Handshake。哪些内容构成了一个IDL的指纹呢?并非整个文本,因为在文本中增加一个空格,调整字段的书写顺序,并不影响数据的序列化和反序列化,只有真正影响序列化和反序列化的内容,才会被当作计算指纹的一部分。
    2021-10-13
    9
  • Scott
    其实这题我们还真做过,主要的问题是thrift是需要预先编译的,但是也不是没有法子,我就提个当时解决问题的关键字,janino。
    2021-10-14
    4
  • 平然
    TCompactProtocol 中为什么还要记录field type,不是在IDL能查到么。
    2022-05-05
    1
    3
  • wkq2786130
    很棒的文章,看完以后自己也总结了一下 放在 http://weikeqin.com/2022/06/26/thrift-protocol/
    2022-07-27
    2
  • 哈达syn$
    老师会讲 lsm 相关的论文吗
    2021-10-13
    2
  • 可加
    模块之间的正交性是怎么理解的?尽量解耦的意思吗?
    2021-12-14
    1
  • webmin
    思考题:IDL 直接序列化,然后放到存储实际数据的 Header 里呢? 这样做对于动态语言是友好的,动态语言可以根据IDL来实时生成数据结构,但是对于静态语言通常情况下都是事先通过IDL来生成不同语言的数据结构,居于这个前题那大可不必把IDL都传输,只需要传输IDL的版本号即可。 上面只是从编解码的角度讨论了IDL是否需要通过Header来保存,试想如果从数据逻辑处理角度看,在事前不知道会有什么样的数据的情况下,自然这些数据也不知道怎么处理,那么把这些解出来貌似就是一种浪费。 如果只是把数据持久化后,让后续程序来处理,那么从保存不同版本IDL的角度考虑,是有必要把IDL单独持久化,只是在设计上,可以调整为用版本号来对应IDL(每个版本的IDL单独保存),而不需要在每块数据的Head上都保存一份IDL信息。
    2021-10-16
    1
  • Helios
    放在header里面对于强类型需要来说还是需要定义一套schema的,感觉没啥意义而且还要浪费解析的性能,自己包体变大。
    2021-12-30
收起评论
显示
设置
留言
12
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部