hdfs-proxy

HDFS-Proxy 技术梳理

问题背景

来自某个需求,希望数据平台可以支持多个不同版本不同认证方式的Hadoop集群。

由于Kerberos的认证是进程级别有效的,因此无法在多线程环境下支持对多Hadoop集群的访问支持。

为了解决多个模块对HDFS的访问需求,因此设计HDFS Proxy模块,透明无侵入地解决这个问题。

设计目标(按重要性排序)

  1. 兼容FileSystem接口,尽量减少接入方的改动成本
  2. 保证性能,减少Proxy环节的性能损耗
  3. 可扩展性,对于集群数量与流量负载都能保持线性可扩展
  4. 完整的Log/Tracing/Metrics信息,减少服务运行状态的不透明
  5. 保持异常信息,在客户端还原服务端捕获到的异常
  6. 不保证线程安全,虽然有一定的锁保护,但不支持多线程同时访问一个FS实例

实现功能

1. SDK

  • 作为一个Jar包集成在模块中,实现HDFS FileSystem接口,使得模块可以透明对接多个HDFS集群

  • 从请求上下文中获取HDFS集群ID,实现基于HDFS 集群ID的Proxy服务发现

  • 反序列化异常栈,正确抛出异常

2. Proxy

  • 代理对单个HDFS集群的接口访问
  • 实现基于HDFS集群ID的服务注册
  • 基于Session的资源回收,避免由于客户端崩溃/网络故障等原因导致服务端资源泄露
  • 捕捉并序列化异常,回传到SDK

设计思路与折衷

  • 接口兼容与代码入侵

FileSystem接口支持通过配置文件的方式指定底层的实现类,保护了底层具体实现与上层代码的分离解耦。

因此,只需要在配置文件中指定用SDK中的类作为FileSystem的实现,就可以启用Proxy,入侵比较小。

  • RPC协议的性能
  1. REST接口,简单方便,文本便于阅读,也便于开发与测试
  2. gRPC协议,基于HTTP2+Protobuf3,性能良好

选择gPRC协议

  • 可扩展性

利用K8S提供的负载均衡机制,可以保证对请求负载的良好扩展性。

利用K8S提供的服务发现机制,可以保证对接多个Hadoop集群的扩展性。

  • Log/Tracing/Metrics支持

gRPC协议支持OpenTracing,而Log与Metrics可以在SDK中添加

  • 异常信息还原

为了能在客户端还原出服务端捕获的异常信息,我们需要将堆栈信息序列化传输到客户端,并在客户端反序列化

  • 超时资源回收

Proxy服务端可以在后台运行一个GC线程定期进行资源回收,避免泄露

  • 优化

Buffer可以提高读性能,流式接口可以适应大数据块,gRPC连接可以保持复用

其他

与此相似,后来还补充实现了HiveProxy,在原有的框架基础上添加几个方法就可以了

这里只记录大致思路,具体协议与代码细节就不细说了