Hadoop阅读笔记
Hadoop阅读笔记(七)——代理模式
关于Hadoop已经小记了六篇,《Hadoop实战》也已经翻完7章。仔细想想,这么好的一个框架,不能只是流于应用层面,跑跑数据排序、单表链接等,想得其精髓,还需深入内部。
按照《Hadoop阅读笔记(五)——重返Hadoop目录结构》中介绍的hadoop目录结构,前面已经介绍了MapReduce的内部运行机制,今天准备入手Hadoop RPC,它是hadoop一种通信机制。
RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。
不同于其他RPC产品,Hadoop有属于自己RPC组件,依赖于《Hadoop阅读笔记(六)——洞悉Hadoop序列化机制Writable》中介绍的Hadoop Writable类型的支持。Hadoop Writable接口要求每个实现类都得确保将本类的对象正确序列化(writeObject)与反序列化(readObject)。因此,Hadoop RPC使用Java动态代理与反射实现对象调用方式,客户端到服务器数据的序列化与反序列化由Hadoop框架或用户自己来实现,也就是数据组装是定制的。
显然我们没法上来就直接剖析RPC,因为这里有一些绕不开的东西要先介绍:Writable序列化反序列化(已在第六篇介绍)、动态代理。所以,这里先介绍什么是动态代理。
动态代理是代理模式的一种,还有一种就是静态代理。
代理模式:为其他对象提供一种代理,并以控制对这个对象的访问。而对一个对象进行访问控制的一个原因是为了只有在我们确实需要这个对象时才对它进行创建和初始化。它是给某一个对象提供一个替代者(占位者),使之在client对象和subject对象之间编码更有效率。代理可以提供延迟实例化(lazy instantiation),控制访问, 等等,包括只在调用中传递。
静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。
动态代理:在程序运行时,运用反射机制动态创建而成。
1.静态代理
Person.java(接口)
1 package hadoop.jackie.dao; 2 3 public interface Person { 4 5 public void eat();//人具有吃饭的行为 6 7 public void sleep();//人具有睡觉的行为 8 9 }
PersonImpl.java(实现类,也就是这里的委托类)
1 package hadoop.jackie.dao.impl; 2 3 import hadoop.jackie.dao.Person; 4 5 public class PersonImpl implements Person { 6 7 @Override 8 public void eat() { 9 System.out.println("我是吃货"); 10 11 } 12 13 @Override 14 public void sleep() { 15 System.out.println("我是猪,别管我"); 16 17 } 18 19 }
PersonProxy.java(代理类)
1 package hadoop.jackie.dao.impl; 2 3 import hadoop.jackie.dao.Person; 4 5 public class PersonProxy implements Person { 6 7 private PersonImpl personImpl; 8 9 public PersonProxy(PersonImpl personImpl){ 10 this.personImpl = personImpl; 11 } 12 13 @Override 14 public void eat() { 15 System.out.println("吃饭前"); 16 personImpl.eat();//调用委托类PersonImpl的吃饭方法 17 System.out.println("吃饭后"); 18 19 } 20 21 @Override 22 public void sleep() { 23 System.out.println("睡觉前"); 24 personImpl.sleep();//调用委托类PersonImpl的睡觉方法 25 System.out.println("睡觉后"); 26 27 } 28 29 }
PersonTest.java
1 package hadoop.jackie.dao.test; 2 3 import hadoop.jackie.dao.impl.PersonImpl; 4 import hadoop.jackie.dao.impl.PersonProxy; 5 6 public class PersonTest { 7 8 /** 9 * @param args 10 */ 11 public static void main(String[] args) { 12 13 PersonImpl personImpl = new PersonImpl(); 14 PersonProxy personProxy = new PersonProxy(personImpl); 15 personProxy.eat(); 16 personProxy.sleep(); 17 18 } 19 20 }