`
guiyu0856
  • 浏览: 38521 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

自开发跨HDFS版本的拷贝工具

    博客分类:
  • hdfs
阅读更多

        虽然HDFS提供了distcp的远程拷贝工具,在同版本之间拷贝很方便,功能也很强大。但是,在跨版本、跨 运维机制时,它就不可用了。另外,HDFS也专门为跨版本提供了hftp协议,提供只读功能,但是该功能也有个致命缺陷,即需要配置被拷贝集群的所有节点的hosts,因为这个协议走的是HDFS的web管理接口,里面每个数据节点都是以hostname对外提供服务,所以,不配置hosts是不行的。但是在一些大公司,运维制度很苛刻,root的密码是不对非运维人员提供的,甚至普通用户的密码也不对外,更别人让他们去配置那么多的hosts,这是要走申请和授权的,太麻烦。再者,在大公司,hadoop的集群比较多,版本也不一样,总不能每次都去配置成千上万的hosts,不易维护。

        至此,跨版本拷贝HDFS的需求应运而生,但实现该目标有以下四点:

        1、同一进程内实现跨版本数据的读和写;

        2、全内存交换数据,不写磁盘;(一是因为效率低,二是没有这么大的磁盘[数据文件很大,上T的都有])

        3、拷贝目录时的递归拷贝;

        4、拷贝数据的完整性和一致性。

        这就也对应了四点需要解决的问题:

        1、在同一进程内,如何在面对不同集群版本时加载对应的jar,这需要实现自定制的类加载机制;

        2、多线程并发控制,缓存利用,带宽利用,保证高效拷贝;

        3、分清拷贝目录和文件的区别,同时保证在目标集群保存该目录下结构的一致性;

        4、对目录拷贝时,对个别出错文件的处理方案;源端和目的端的压缩机制、文件格式等

 

        为了方便应用和扩展,我个人设计开发了一套跨版本拷贝的JAVA拷贝工具,处于对公司技术保密制度的尊重和落实,这里我就不发布实现的源码了,但是具体思路可以分享一下。

        1、首要解决自定制的类加载器,普通实现是继承URLClassLoader,但是有个问题,单纯通过它去加载指定jar包,然后显示反射需要的类时,是完全没问题的,但是当显示调用的类内部调用别的类时(及内部隐士调用),依然会导致版本错乱(因为不同HDFS版本依赖有些不同版本的第三方jar,默认类加载器在类路径下按照先后顺序加载,当出现重名类时,取第一个jar的),因此,首要解决累加器;

       2、定义上层接口,定义create、open、delete等文件操作方法,以及一些辅助功能如递归目录等;

       3、为工具稳定和维护增加日志、监控和自运维功能设计,如重试等

       4、子类中用到Hadoop的中类时,全反射机制实现,重点关注是子类自己申明的还是继承至父类、处理数组、流关闭等;

       5、双缓冲队列,谨记,该“双缓冲”与常规双缓冲是有区别的,因此这是流式读取,顺序不能乱。

       6、命令行易用参数设计,可配置化设计等

 

       做到上述这些,那么一个结构简单却功能强大、稳定的工具就诞生了。

      

       另外,部署时,记得工具中的hadoop配置文件应该从线上拷贝过来或者从源集群的客户端中拷贝,还有就是要记得在跨用户、用户组时,部署主机的安全配置机制和源集群的安全验证机制要保持一致。

 

       设计、研发和测试该工具,我用了1.5天,现在在线上运行一切正常,符合预期。表扬一下自己和感谢一下现实环境下的“变态”需求催生了自我创新。

 

 

0
4
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics