HDFS-Proxy 技术梳理
问题背景
来自某个需求,希望数据平台可以支持多个不同版本不同认证方式的Hadoop集群。
由于Kerberos的认证是进程级别有效的,因此无法在多线程环境下支持对多Hadoop集群的访问支持。
为了解决多个模块对HDFS的访问需求,因此设计HDFS Proxy模块,透明无侵入地解决这个问题。
设计目标(按重要性排序)
- 兼容FileSystem接口,尽量减少接入方的改动成本
- 保证性能,减少Proxy环节的性能损耗
- 可扩展性,对于集群数量与流量负载都能保持线性可扩展
- 完整的Log/Tracing/Metrics信息,减少服务运行状态的不透明
- 保持异常信息,在客户端还原服务端捕获到的异常
- 不保证线程安全,虽然有一定的锁保护,但不支持多线程同时访问一个FS实例
实现功能
1. SDK
作为一个Jar包集成在模块中,实现HDFS FileSystem接口,使得模块可以透明对接多个HDFS集群
从请求上下文中获取HDFS集群ID,实现基于HDFS 集群ID的Proxy服务发现
反序列化异常栈,正确抛出异常
2. Proxy
- 代理对单个HDFS集群的接口访问
- 实现基于HDFS集群ID的服务注册
- 基于Session的资源回收,避免由于客户端崩溃/网络故障等原因导致服务端资源泄露
- 捕捉并序列化异常,回传到SDK
设计思路与折衷
- 接口兼容与代码入侵
FileSystem接口支持通过配置文件的方式指定底层的实现类,保护了底层具体实现与上层代码的分离解耦。
因此,只需要在配置文件中指定用SDK中的类作为FileSystem的实现,就可以启用Proxy,入侵比较小。
- RPC协议的性能
- REST接口,简单方便,文本便于阅读,也便于开发与测试
- gRPC协议,基于HTTP2+Protobuf3,性能良好
选择gPRC协议
- 可扩展性
利用K8S提供的负载均衡机制,可以保证对请求负载的良好扩展性。
利用K8S提供的服务发现机制,可以保证对接多个Hadoop集群的扩展性。
- Log/Tracing/Metrics支持
gRPC协议支持OpenTracing,而Log与Metrics可以在SDK中添加
- 异常信息还原
为了能在客户端还原出服务端捕获的异常信息,我们需要将堆栈信息序列化传输到客户端,并在客户端反序列化
- 超时资源回收
Proxy服务端可以在后台运行一个GC线程定期进行资源回收,避免泄露
- 优化
Buffer可以提高读性能,流式接口可以适应大数据块,gRPC连接可以保持复用
其他
与此相似,后来还补充实现了HiveProxy,在原有的框架基础上添加几个方法就可以了
这里只记录大致思路,具体协议与代码细节就不细说了