AVRO—跨语言数据序列化框架

这种跨语言的数据序列化框架有很多,AVRO并不是最知名,最好用的,为什么会选择他呢?因为他是Hadoop的一个子项目,就犹如Spring mvc和Spring一样。
特点:
1.数据结构丰富。
2.快速可压缩的二进制形式。 常见的压缩算法:HUFFMAN编码(哈夫曼编码)。
3.可以实现RPC
4.依赖于模式(schema),是用json格式来表示的。如果是想利用avro实现序列化或rpc通 信,需要遵守schema的格式要求

1.数据结构

具有丰富的数据结构类型。8种基本数据类型以及6种复杂类型
基本数据类型
1. null ->表示没有值
2. boolean ->表示一个二级制布尔值
3. int ->表示32位有符号整数
4. long ->64位有符号整数
5. float ->32位单精度浮点数
6. double ->64位双精度浮点数
7. bytes ->8位无符号字节
8. string ->注意是小写 表示字符序列

复杂数据
目前只记住一个常用的就可以了
record:
{“namespace”:”avro.domain”,
“type”:”record”,
“name”:”Student”,
“fields”:[
{“name”:”username”,”type”:”string”}, {“name”:”age”,”type”:[“int”,”null”]}
]
}
namespace:指定包名
type:record 序列化类型
name:指定类名
fields:指定类的字段名

下面实现一下序列化:

maven 坐标如下:
这里还有一个插件,要右键pom.xml-run as->Maven generate-sources
会将写的模板文件生成对应的类。

<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <compiler-plugin.version>2.3.2</compiler-plugin.version>
        <avro.version>1.7.5</avro.version>
    </properties>
  <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.6.4</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.avro</groupId>
            <artifactId>avro</artifactId>
            <version>1.7.5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.avro</groupId>
            <artifactId>avro-ipc</artifactId>
            <version>1.7.5</version>
        </dependency>
    </dependencies>
   <build>
  <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${compiler-plugin.version}</version>
            </plugin>
            <plugin>
                <groupId>org.apache.avro</groupId>
                <artifactId>avro-maven-plugin</artifactId>
                <version>1.7.5</version>
                <executions>
                <execution>
                        <id>schemas</id>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>schema</goal>
                            <goal>protocol</goal>
                            <goal>idl-protocol</goal>
                        </goals>
                 <configuration>
                        <sourceDirectory>${project.basedir}/src/main/avro/</sourceDirectory>
                        <outputDirectory>${project.basedir}/src/main/java/</outputDirectory>
                    </configuration>       
                 </execution>   

                </executions>
            </plugin>
        </plugins>
   </build>

pom文件会报错,不用管,将错误提醒关掉即可。

实例如下:
1.根据avro的插件要求,更改maven工程结构,需要创建一个source源目录src\main\avro
2.根据avro的模式要求,创建模式文件(放在src\main\avro下)

1.在src\main\avro下创建模式文件student.avsc(该文件格式就是avro的存放数据的格式文件)
模式文件如下:

{"namespace":"avro.pojo",
"type":"record",
"name":"Student",
"fields":[
    {"name":"username","type":"string"},
    {"name":"age","type":["int","null"]}
]
}

序列化

public void testWrite() throws Exception{
        //创建序列化类
        DatumWriter<Student> dw = new SpecificDatumWriter<Student>();
        DataFileWriter<Student> dfw = new DataFileWriter<Student>(dw);
        //创建2个需要序列化的对象
        Student stu1 = new Student("帅比", 25);
        Student stu2 = new Student("美女", 18);
        //创建序列化目标文件1.txt
        dfw.create(stu1.getSchema(), new File ("1.txt"));
        //写入stu1
        dfw.append(stu1);
        //写入stu2
        dfw.append(stu2);
        //写入完毕
        dfw.close();
    }

反序列化

public void testRead() throws Exception{
        //创建反序列化类
        DatumReader<Student> dr = new SpecificDatumReader<Student>();
        DataFileReader<Student> dfr = new DataFileReader<Student>(new File ("1.txt"), dr);
        //反序列化并输出
        while(dfr.hasNext()){
            Student stu = dfr.next();
            System.out.println(stu);
        }

    }

这里输出的是json格式:
{“username”: “帅比”, “age”: 25}
{“username”: “美女”, “age”: 18}

Avro实现RPC(Remote Procedure Call)

场景:一个客户端,一个服务端(创建两个avro工程)。客户端向服务端发送数据,服务端根 据算法算出结果,返回给客户端。

假定客户端传值后,服务器做加法后传回。
实现步骤
1.创建两个maven工程
2.引入pom文件
3.更改maven工程结构(src/main/avro)
4.创建模式文件(协议文件) src/main/avro/AddService.avdl(注意这里的格式是协议文件的格式后缀,上面的是模式文件)

@namespace("avro.service")
protocol AddService{
    int add(int x,int y);
}

右键pom.xml-run as->Maven generate-sources,生成接口类。
两个项目都要有

客户端:
首先创建实现类:
addserverImpl

public class AddServerImpl implements AddService{

    @Override
    public int add(int x, int y) throws AvroRemoteException {

        return x+y;
    }

}

主类:

public class server {

    public static void main(String[] args) {
        /*指定监听端口号,和处理的实现类对象
         * 第一个参数 SpecificResponder 中第一个参数是接口类,第二个是实现对象
         */

        NettyServer server = new NettyServer(
                new SpecificResponder(AddService.class, 
                        new AddServerImpl()),
                new InetSocketAddress(6666));
    }
}

客户端:

public class client {

    public static void main(String[] args) throws Exception {
        //指定服务器ip及端口
        NettyTransceiver nt = new NettyTransceiver(new InetSocketAddress("127.0.0.1", 6666));
        //从服务器获取实现类
        AddService proxy = SpecificRequestor.getClient(AddService.class, nt);
        int result = proxy.add(1, 5);
        System.out.println(result);
    }

}

先启动服务端,后启动客户端,输出6;

传输对象案例:
客户端将Student对象传给服务器。
1.将student.avsc拷贝到client下的src/main/avro
2.修改AddService.avdl

@namespace("avro.service")
protocol AddService{
 import schema "student.avsc";
 int add(int a,int b);
 void sendStudent(avro.pojo.Student stu);
}

重新Pom run as一下。

服务器端实现类增加方法

//注意,返回值是Void,这个是格式,返回Null就可以了。
public Void sendStudent(Student stu) throws AvroRemoteException {
        System.out.println("服务器端接收:"+stu);
        return null;
    }

修改客户端类添加

Student stu = new Student("jack",23);
proxy.sendStudent(stu);

再次运行即可。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值