Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
分布式系统中的 RPC 与串行化
By 徐家强
xjqkilling@gmail.com
提纲
● RPC 体系结构
● Thrift
● Avro
● Protocol Buffer
●
总结对比
RPC 体系结构
● Client 端:同步与异步
● RPC 系统的层次结构
●
调用层
● 协议层( Protocol )—— 串行化机制
● 传输层( Transport )
● Server 架构
●
单线程、多线程、线程池、事件循环
...
RPC 体系结构
●
调用层
●
为上层的用户代码提供编程接口
●
对函数调用进行串行化和解串行化(策略)
●
协议层
●
提供串行化和解串行化的机制
●
传输层
●
收发已经串行化的数据
● Server
●
将上面个层组合起来
Thrift
● 最全面的 RPC 系统,但不支持本地串行化
● 采用层次结构,支持多种 Protocol , Transport
以及多种 server 架构
● Client 端只支持同步模式
● 需要通过 IDL 来定义 RPC 服务,然...
Thrift Types
● Base types: bool, byte, i16, i32, i64, double,
string
● Struct
● Containers: List, Map, Set
● Exceptions
● ...
Thrift 调用层
● Client 端
● 对每个 Service X , IDL 编译器生成一个对应的
XClient 类, RPC 函数作为该类的成员函数
● 用户代码直接调用 XClient 中的成员函数
● 调用层将参数列表封装在一...
Thrift Protocols
● 将 thrift 支持的各种类型转换为 wire format
● Struct 的每个域都和它的类型以及 id 一起编码
● 接收端可以一边接收数据一边解码( self
delimiting )
●
接收...
Thrift Transports
● 收发已经编码为 wire format 的数据
● 抽象各种通信设备: socket, memory, file, etc
● TBufferedTransport
● 使用固定大小的收发缓冲区
● 发送...
Thrift 兼容性
●
服务器端的用户代码可以忽略不能识别的域或者
参数
● Thrift 为每个域和函数参数提供了 isset 函数
● 4 种情况
● Added field, old client, new server
● Remov...
Avro
●
只提供了调用层和协议层,两者合一
●
可以把数据串行化到文件
●
主要特色是不需要自动生成代码
● 数据类型的定义( schema )与串行化的数据存
放在一起
Avro Types
● 用 JSON 格式定义,包含在程序中
● Null, boolean, int, long, float, double, bytes, string
● Record
● Enum
● Array
● Map
● U...
调用层与协议层
● 在代码中用 JSON 定义 schema ,由 schema 生
成一个 parser 结构
● 通过 parser 就能收发各种类型的数据,包括
RPC 的 message 结构
●
调用层通过库函数的形式实现
● 整数类...
Avro 兼容性
● 提供了 schema resolution 机制
● Reader and writer
● 支持类型间的“升级”,比如 long 类型的参数可以
接收 int 类型的值
● Reader 忽略不能识别的域或者参数
● 如...
Protocol Buffer
●
只是一种串行化机制
●
主要的特色是使用了高效的串行化编码——
Variant/Zig-Zag
● 支持的数据类型少,不支持 array, list, map, set
等
●
需要自动生成代码来读写数据
Variant
● Variant
● Each byte in a varint, except the last byte, has the
most significant bit (msb) set – this indicates t...
Zig-Zag
● 在 variant 基础上解决负整数编码的问题
Signed Encoded
0 0
-1 1
1 2
-2 3
2 4
总结对比
● Thrift 比较全面,但是模型固定,不够小巧,比
较适合用在对客户端的 API 上
● Avro 可以用在程序内部的数据通信上
● Protocol Buffer 在功能上说没有什么优势
● 缺少 Client 端异步的 RPC...
Upcoming SlideShare
Loading in …5
×

分布式系统中的 RPC 与串行化

2,172 views

Published on

探讨分布式系统中 RPC 的架构,并对比分析 Thrift, Protocol Buffer 和 Avro 的设计和实现。

  • Be the first to comment

分布式系统中的 RPC 与串行化

  1. 1. 分布式系统中的 RPC 与串行化 By 徐家强 xjqkilling@gmail.com
  2. 2. 提纲 ● RPC 体系结构 ● Thrift ● Avro ● Protocol Buffer ● 总结对比
  3. 3. RPC 体系结构 ● Client 端:同步与异步 ● RPC 系统的层次结构 ● 调用层 ● 协议层( Protocol )—— 串行化机制 ● 传输层( Transport ) ● Server 架构 ● 单线程、多线程、线程池、事件循环 ● 支持跨语言调用 ● 服务升级和兼容性问题
  4. 4. RPC 体系结构 ● 调用层 ● 为上层的用户代码提供编程接口 ● 对函数调用进行串行化和解串行化(策略) ● 协议层 ● 提供串行化和解串行化的机制 ● 传输层 ● 收发已经串行化的数据 ● Server ● 将上面个层组合起来
  5. 5. Thrift ● 最全面的 RPC 系统,但不支持本地串行化 ● 采用层次结构,支持多种 Protocol , Transport 以及多种 server 架构 ● Client 端只支持同步模式 ● 需要通过 IDL 来定义 RPC 服务,然后自动生成 调用层代码 ● 跨语言调用 ● 每种语言都在 IDL 编译器中有自己的代码生成逻辑 ● 需要为每种语言实现 Protocol, Transport 和 Server
  6. 6. Thrift Types ● Base types: bool, byte, i16, i32, i64, double, string ● Struct ● Containers: List, Map, Set ● Exceptions ● Services: A set of function declarations ● Struct 的域和函数的每个参数都关联一个 id
  7. 7. Thrift 调用层 ● Client 端 ● 对每个 Service X , IDL 编译器生成一个对应的 XClient 类, RPC 函数作为该类的成员函数 ● 用户代码直接调用 XClient 中的成员函数 ● 调用层将参数列表封装在一个 Struct 中发送 ● Server 端 ● 对每个 Service X , IDL 编译器生成一个对应的 XIf 接口类, RPC 函数作为成员函数 ● 服务器端的用户代码实现这个接口
  8. 8. Thrift Protocols ● 将 thrift 支持的各种类型转换为 wire format ● Struct 的每个域都和它的类型以及 id 一起编码 ● 接收端可以一边接收数据一边解码( self delimiting ) ● 接收端可以检查函数调用是否新增或者缺少参数,便 于系统升级 ● 提供多种 wire format 支持 ● Binary, Zig-Zag, JSON, etc
  9. 9. Thrift Transports ● 收发已经编码为 wire format 的数据 ● 抽象各种通信设备: socket, memory, file, etc ● TBufferedTransport ● 使用固定大小的收发缓冲区 ● 发送缓冲区满时发送数据,接收缓冲区数据不足时读数据 ● TFramedTransport ● 发送缓冲区中的数据只在 flush 的时候才发送 ● 发送缓冲区大小随着缓冲数据的增加而增长 ● 接收端一次读取一个 frame 的数据
  10. 10. Thrift 兼容性 ● 服务器端的用户代码可以忽略不能识别的域或者 参数 ● Thrift 为每个域和函数参数提供了 isset 函数 ● 4 种情况 ● Added field, old client, new server ● Removed field, old client, new server ● Added field, new client, old server ● Removed field, new client, old server
  11. 11. Avro ● 只提供了调用层和协议层,两者合一 ● 可以把数据串行化到文件 ● 主要特色是不需要自动生成代码 ● 数据类型的定义( schema )与串行化的数据存 放在一起
  12. 12. Avro Types ● 用 JSON 格式定义,包含在程序中 ● Null, boolean, int, long, float, double, bytes, string ● Record ● Enum ● Array ● Map ● Union ● Fixed ● Protocol, Message
  13. 13. 调用层与协议层 ● 在代码中用 JSON 定义 schema ,由 schema 生 成一个 parser 结构 ● 通过 parser 就能收发各种类型的数据,包括 RPC 的 message 结构 ● 调用层通过库函数的形式实现 ● 整数类型使用 ProtocolBuffer 的 Variant/Zig-Zag 编码 ● 支持同类型数据的排序(无需先转换为结构体) ● schema 跟数据在一起
  14. 14. Avro 兼容性 ● 提供了 schema resolution 机制 ● Reader and writer ● 支持类型间的“升级”,比如 long 类型的参数可以 接收 int 类型的值 ● Reader 忽略不能识别的域或者参数 ● 如果缺少域或者参数, reader 会报错
  15. 15. Protocol Buffer ● 只是一种串行化机制 ● 主要的特色是使用了高效的串行化编码—— Variant/Zig-Zag ● 支持的数据类型少,不支持 array, list, map, set 等 ● 需要自动生成代码来读写数据
  16. 16. Variant ● Variant ● Each byte in a varint, except the last byte, has the most significant bit (msb) set – this indicates that there are further bytes to come. The lower 7 bits of each byte are used to store the two's complement representation of the number in groups of 7 bits, least significant group first. ● 300 → 1010 1100 0000 0010
  17. 17. Zig-Zag ● 在 variant 基础上解决负整数编码的问题 Signed Encoded 0 0 -1 1 1 2 -2 3 2 4
  18. 18. 总结对比 ● Thrift 比较全面,但是模型固定,不够小巧,比 较适合用在对客户端的 API 上 ● Avro 可以用在程序内部的数据通信上 ● Protocol Buffer 在功能上说没有什么优势 ● 缺少 Client 端异步的 RPC 机制

×