hbase服务端源码分析
2016-07-15 17:26
316 查看
—client –>hmaster 和 client —> regionserver的流程
(源码基于hbase-1.1.5版本)服务端主要有两个进程,hmaster 和 HRegionServer(其实 hmaster继承于 HRegionServer,这两个进程中既提供了web界面,同时也提供了rpc服务的调用,
如web服务在hmaster中是 http://127.0.0.1:16010/master-status
在regionserver中的web界面是 http://127.0.0.1:16030/rs-status
是通过HRegionServer.putUpWebUI 进行拉起jetty的不同业务的web界面
同时这两个进程也提供rpc服务,
hmaster 和 regionserver 绑定到不同的端口进行rpc ,就是通过 RpcServer 类进行的,在RSRpcServices(MasterRpcServices 是hamster调用的,其实MasterRpcServices也继承于 RSRpcServices) 中进行调用
通过 RpcServer.Listener 的方法,拉起一个nio server线程,来监听客户端的连接。
如
bind(acceptChannel.socket(), bindAddress, backlogLength);
然后在 Listener 线程当中,接收数据请求。
每一个链接都拿一下线程Reader 对象进行处理,创建的线程reader数量是通过(hbase.ipc.server.read.threadpool.size)
参数进行定义的,所以如果想提高线程的处理并发数,可以调整这个参数。
然后每个链接都创建 org.apache.hadoop.hbase.ipc.RpcServer.Connection.Connection
对象到 readKey.attach(c); 中调用 readAndProcess()方法读取连接中的数据
第一次连接上来时,调用readPreamble()方法,读取头部的数据如 AuthMethod.SIMPLE 、version 等头部信息
校验通过后,读取数据到data对象中,调用process()方法进行数据的处理
在数据处理中,会根据刚才的头部中上传的auth信息,进行判断是否进行权限校验。通过 变量 useSasl 保存。
在head部分,就可以拿到上传的用户名称.
接着通过authorizeConnection()方法进行权限的校验,如果校验失败,就返回出错
在
authorize(UserGroupInformation user, ConnectionHeader connection, InetAddress addr)
方法当中,会根据是否配置了HADOOP_SECURITY_AUTHORIZATION 参数进行权限的验证
通过
Class c = getServiceInterface(services, connection.getServiceName());
拿到来源模块的接口方法
this.authManager.authorize(user != null ? user : null, c, getConf(), addr);
在这里进行KerberosInfo 的验证
所以其实Kerberos 的校验,就是通过来源的ip+username进行判断的。
当校验完成后,就调用processRequest()方法进行业务数据的处理了,在RpcServer的创建时,
有传入一个services参数,其实就是下面的方法
protected List<BlockingServiceAndInterface> getServices() { List<BlockingServiceAndInterface> bssi = new ArrayList<BlockingServiceAndInterface>(2); bssi.add(new BlockingServiceAndInterface( ClientService.newReflectiveBlockingService(this), ClientService.BlockingInterface.class)); bssi.add(new BlockingServiceAndInterface( AdminService.newReflectiveBlockingService(this), AdminService.BlockingInterface.class)); return bssi; }
这个方法,已经包含所有的业务调用了,通过客户端上传的serviceName,拿到对应的模块,然后反射调用对应的方法
再次调用 md = this.service.getDescriptorForType().findMethodByName(header.getMethodName());
就可以找到对应的具体method的调用。
创建call调用对象
Call call = new Call(id, this.service, md, header, param, cellScanner, this, responder, totalRequestSize, traceInfo, RpcServer.getRemoteIp());
然后放在 用CallRunner包装一下提交在 scheduler 线程池当中,
在CallRunner里面的run方法会调用到 RpcServer.call
resultPair = this.rpcServer.call(call.service, call.md, call.param, call.cellScanner, call.timestamp, this.status)
在里面隐含着一个比较重要的的对象
RpcServer.CurCall.set(call);
把外面的所有参数放在call的当前线程当中,但是由于这个CurCall是protected的,在具体的方法当中,拿不到。
在业务方法中,为了拿到ip和user的信息,就需要从这个对象中拿出新的信息,
放在PayloadCarryingRpcController 对象,传到下个方法中了
在方法里面
Message result = service.callBlockingMethod(md, controller, param);
调用到service的接口方法,其实就是调用到 RSRpcServices 这个类当中,可以看到这个类的继承关系
RSRpcServices implements HBaseRPCErrorHandler, AdminService.BlockingInterface, ClientService.BlockingInterface, PriorityFunction;
无论是调用hmaster还是调用hregionserver的rpc服务,都是最后回调到这个类当中。
如调用到 RSRpcServices.scan 方法当中,通过如下代码
String requestUserName = ((PayloadCarryingRpcController)controller).getRequestUserName();
就可以进行 拿到客户端的帐号了
相关文章推荐
- Facebook's New Real-time Messaging System: HBase to Store 135+ Billion Messages a Month
- Hadoop生态上几个技术的关系与区别:hive、pig、hbase 关系与区别
- 基于HBase Thrift接口的一些使用问题及相关注意事项的详解
- 如何解决struts2日期类型转换
- java 保留两位小数的几种方法
- Java IO流 文件传输基础
- Eclipse中查看android工程代码出现"android.jar has no source attachment"的解决方案
- 基于Java实现杨辉三角 LeetCode Pascal's Triangle
- hbase shell基础和常用命令详解
- 手把手教你配置Hbase完全分布式环境
- 实战:在Java Web 项目中使用HBase
- HBase RowKey设计的那些事
- Spark中将对象序列化存储到hdfs
- HBase基本原理
- HBase中的基本概念
- 【原创】基于分布式存储的开源系统在实时数据库海量历史数据存储项目上的预研
- HBase0.96.x开发使用(一)--安装
- 基于外部ZooKeeper的GlusterFS作为分布式文件系统的完全分布式HBase集群安装指南
- 基于solr实现hbase的二级索引