开源组件系列(5):数据的序列化(Thrift、Protobuf、Avro)

(一)数据序列化的意义

当我们需要将采集的日志存入文件或者是传输到下一个系统时,需要将数据对象转化为字节流格式,也就是数据的序列化过程。通常情况下,搭建一套数据仓库系统,会经历如下四个阶段:

1.没有序列化方案:该方案将数据定义为字符串格式,并以文本的形式保存,如果存在多条数据,则采用分隔符来分隔,例如“{|[”等。当增加字段时,通过在文本的最后增加新行的方式来进行,修改及解析比较繁琐,修改需要改动的依赖多。

2.采用编程语言内置的序列化方案,例如Java的Serialization等,这种方式会将日志系统与开发语言绑定起来。

3.格式化数据表达方式,如XML、JSON等,该方式能够约束每个字段的类型,为后续的优化和共享带来了便利。

4.采用序列化框架,例如Thrift、Avro、Protobuf等,通过引入schema的概念,使得序列化和维护变得非常高效,并且有了代码的特征。序列化框架的优点有:提供IDL用以描述数据的schema信息;支持跨语言的读写;数据的编码存储能够节约存储空间;支持schema的演化,也就是可以根据一定的规则修改schema。

目前比较常用的开源组建包括Facebook的Thrift、Google的Protobuf、Apache的Avro等,这些方案大同小异,并不存在绝对的优点,需要根据其特点灵活使用。

(二)Thrift方案

Thrift是Facebook开源的RPC框架,具备了序列化和RPC两个功能,几乎支持所有的编程语言,并提供了一套完整的IDL语言用来定义Schema信息,在实际应用中非常广泛。

以下是一个简单的Thrift例子:

// 命名空间定义

include "shared.thrift"

namespace cpp tutorial



// 定义别名

typedef i32 MyInteger

const i32 INT32CONSTANT = 9853



// 定义枚举类型

enum Operation {

  ADD = 1,

  SUBTRACT = 2,

  MULTIPLY = 3,

  DIVIDE = 4

}



// 定义结构体

struct Work {

  1: i32 num1 = 0,

  2: i32 num2,

  3: Operation op,

  4: optional string comment,

5: required int id

}

Thrift通过struct关键字来描述对象,由四种属性构成:

1.域编号:每个域必须是唯一的整数,可以不连续,通过该编号Thrift能够实现向前及向后的兼容性;

2.域修饰:包括required和optional两个关键字,用来对域的值进行限制;

3.域类型:包括int、long等基本类型,也支持set、list、map等复杂容器;

4.域名称:同一个struct下的域名必须唯一。

 

一旦给出了数据的Thrift IDL定以后,可以通过Thrift提供的编译器直接生成目标语言代码,例如Java:

thrift  --gen  java  tutorial.thrift

 

下面是Java使用例子:

public class HelloServerDemo {

    public  static  final int  SERVER_PORT = 8090;

    public void startServer() {

        try {

            System.out.println("HelloWorld TSimpleServer start ....");

            //在这里调用了 HelloWorldIm
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值