
avro是hadoop的一個子項目,提供的功能與thrift、Protocol Buffer類似,都支援二進制高效序列化,也自帶RPC機制,但是avro使用起來更簡單,無需象thrift那樣生成目智語言源代碼,目前支援的語言有java、c#、php、c++等(詳情見:https://cwiki.apache.org/confluence/display/AVRO/Supported+Languages),hadoop生态圈中的hive、pig已經在使用avro
avro-client子產品中的pom.xml參考以下内容:
1 <?xml version="1.0" encoding="UTF-8"?>
2 <project xmlns="http://maven.apache.org/POM/4.0.0"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5 <modelVersion>4.0.0</modelVersion>
6
7 <groupId>yjmyzz.avro</groupId>
8 <artifactId>avro-client</artifactId>
9 <version>1.0</version>
10
11 <properties>
12 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
13 <compiler-plugin.version>2.3.2</compiler-plugin.version>
14 <avro.version>1.7.5</avro.version>
15 </properties>
16
17 <dependencies>
18 <dependency>
19 <groupId>junit</groupId>
20 <artifactId>junit</artifactId>
21 <version>4.10</version>
22 <scope>test</scope>
23 </dependency>
24 <dependency>
25 <groupId>org.slf4j</groupId>
26 <artifactId>slf4j-simple</artifactId>
27 <version>1.6.4</version>
28 <scope>compile</scope>
29 </dependency>
30 <dependency>
31 <groupId>org.apache.avro</groupId>
32 <artifactId>avro</artifactId>
33 <version>${avro.version}</version>
34 </dependency>
35 <dependency>
36 <groupId>org.apache.avro</groupId>
37 <artifactId>avro-ipc</artifactId>
38 <version>${avro.version}</version>
39 </dependency>
40
41 <dependency>
42 <groupId>yjmyzz.avro</groupId>
43 <artifactId>avro-contract</artifactId>
44 <version>1.0</version>
45 </dependency>
46 </dependencies>
47
48 <build>
49 <plugins>
50 <plugin>
51 <groupId>org.apache.maven.plugins</groupId>
52 <artifactId>maven-compiler-plugin</artifactId>
53 <version>${compiler-plugin.version}</version>
54 </plugin>
55 <plugin>
56 <groupId>org.apache.avro</groupId>
57 <artifactId>avro-maven-plugin</artifactId>
58 <version>${avro.version}</version>
59 <executions>
60 <execution>
61 <id>schemas</id>
62 <phase>generate-sources</phase>
63
64 <goals>
65 <goal>schema</goal>
66 <goal>protocol</goal>
67 <goal>idl-protocol</goal>
68 </goals>
69 </execution>
70 </executions>
71 </plugin>
72 </plugins>
73 </build>
74
75
76 </project>
View Code
一、定義檔案示例
Person.avsc
{
"namespace": "yjmyzz.avro.study.dto",
"type": "record",
"name": "Person",
"fields": [
{
"name": "age",
"type": "int"
},
{
"name": "name",
"type": "string"
},
{
"name": "sex",
"type": "boolean"
},
{
"name": "salary",
"type": "double"
},
{
"name": "childrenCount",
"type": "int"
}
]
}
QueryParameter.avsc
{
"namespace": "yjmyzz.avro.study.dto",
"type": "record",
"name": "QueryParameter",
"fields": [
{
"name": "ageStart",
"type": "int"
},
{
"name": "ageEnd",
"type": "int"
}
]
}
DemoService.avdl
@namespace ("yjmyzz.avro.study.service")
protocol DemoService
{
import schema "Person.avsc";
import schema "QueryParameter.avsc";
string ping();
array<yjmyzz.avro.study.dto.Person> getPersonList(yjmyzz.avro.study.dto.QueryParameter queryParameter);
}
二、服務端
DemoServiceImpl.java
package yjmyzz.avro.study;
import yjmyzz.avro.study.dto.Person;
import yjmyzz.avro.study.dto.QueryParameter;
import yjmyzz.avro.study.service.DemoService;
import java.util.ArrayList;
import java.util.List;
public class DemoServiceImpl implements DemoService {
public String ping() {
System.out.println("ping()");
return "pong";
}
public List<Person> getPersonList(QueryParameter parameter) {
//System.out.println(parameter.getAgeStart() + " - " + parameter.getAgeEnd());
List<Person> list = new ArrayList<Person>(10);
for (int i = 0; i < 10; i++) {
Person p = new Person();
p.setAge(i);
p.setChildrenCount(i);
p.setName("test" + i);
p.setSalary(10000D);
p.setSex(true);
list.add(p);
}
return list;
}
}
AvroServer.java
package yjmyzz.avro.study;
import org.apache.avro.ipc.NettyServer;
import org.apache.avro.ipc.Server;
import org.apache.avro.ipc.specific.SpecificResponder;
import yjmyzz.avro.study.service.DemoService;
import java.net.InetSocketAddress;
public class AvroServer {
public static void main(String[] args) {
System.out.println("Starting avro server...");
Server server = new NettyServer(new SpecificResponder(DemoService.class,
new DemoServiceImpl()),
new InetSocketAddress(65111));
System.out.println("Avro erver started.");
}
}
三、用戶端
AvroClient.java
package yjmyzz.avro.study;
import org.apache.avro.AvroRemoteException;
import org.apache.avro.ipc.NettyTransceiver;
import org.apache.avro.ipc.specific.SpecificRequestor;
import yjmyzz.avro.study.dto.QueryParameter;
import yjmyzz.avro.study.service.DemoService;
import java.net.InetSocketAddress;
public class AvroClient {
public static void main(String[] args) throws Exception {
NettyTransceiver client = new NettyTransceiver(new InetSocketAddress(65111));
DemoService proxy = (DemoService) SpecificRequestor.getClient(DemoService.class, client);
System.out.println(proxy.ping());
int max = 100000;
Long start = System.currentTimeMillis();
for (int i = 0; i < max; i++) {
call(proxy);
}
Long end = System.currentTimeMillis();
Long elapse = end - start;
int perform = Double.valueOf(max / (elapse / 1000d)).intValue();
System.out.print("avro " + max + " 次RPC調用,耗時:" + elapse + "毫秒,平均" + perform + "次/秒");
// cleanup
client.close();
}
private static void call(DemoService proxy) throws AvroRemoteException {
//client.ping();
//System.out.println("ping()=>" + client.ping());
QueryParameter parameter = new QueryParameter();
parameter.setAgeStart(5);
parameter.setAgeEnd(50);
proxy.getPersonList(parameter);
//System.out.println(client.getPersonList(parameter));
}
}
avro 100000 次RPC調用,耗時:18617毫秒,平均5371次/秒
注:雖然很多關于thrift、avro的性能評測文章提到avro性能不輸于thrift,但就本文的示例而言,在同一台筆記本上,avro的性能隻有thrift的約1/2.
作者:菩提樹下的楊過