在不同版本号hdfs集群之间转移数据

    最简单的办法就是把src集群的数据导到本地,然后起还有一个进程将本地数据传到des集群上去。

只是这有几个问题:

  • 效率减少
  • 占用本地磁盘空间
  • 不能应付实时导数据需求
  • 两个进程须要协调,复杂度添加


    更好的办法是在同一个进程内一边读src数据,一边写des集群。只是这相当于在同一个进程空间内载入两个版本号的hadoop jar包。这就须要在程序中使用两个classloader来实现。 

    下面代码能够实现classloader载入自己定义的jar包,并生成须要的Configuration对象:
Java代码
  • URL[] jarUrls = new URL[1];
  • jarUrls[0]=new File(des_jar_path).toURI().toURL();
  • ClassLoader jarloader = new URLClassLoader(jarUrls, null);
  • Class Proxy = Class.forName("yourclass", true, jarloader);
  • Configuration conf = (Configuration)Proxy.newInstance();
URL[] jarUrls = new URL[1];
jarUrls[0]=newFile(des_jar_path).toURI().toURL();
ClassLoader jarloader = newURLClassLoader(jarUrls, null);
Class Proxy =Class.forName("yourclass", true, jarloader);
Configuration conf =(Configuration)Proxy.newInstance();




    可是因为在生成HTable对象时。须要使用这个conf对象,而载入这个conf对象的代码本身是由默认的classloader载入的,也就是0.19.2的jar包。

所以在以上代码最后一行所强制转换的Configuration对象仍然是0.19.2版本号的。

那怎么办呢? 

    琢磨了一会,发现假设要实现以上功能,必须将生成HTable对象,以及以后的全部hbase操作都使用这个新的classloader。因此这个新的classloader必须载入除了0.19.2的jar包外全部须要用到的jar包,然后把全部操作都封装进去。在外面用反射来调用。

这种话。通常构造函数都不为空了。因此须要用到Constructor来构造一个自己定义的构造函数 

    代码段例如以下:

Java代码
  • main.java
  • void init(){
  • ClassLoader jarloader = generateJarLoader();
  • Class Proxy = Class.forName("test.writer.hbasewriter.HBaseProxy", true, jarloader);
  • Constructor con = Proxy.getConstructor(new Class[]{String.class, String.class, boolean.class});
  • Boolean autoflush = param.getBoolValue(ParamsKey.HbaseWriter.autoFlush, true);
  • proxy = con.newInstance(new Object[]{path, tablename, autoflush});
  • }
  • void put(){
  • ...
  • while((line = getLine()) != null) {
  • proxy.getClass().getMethod("generatePut",String.class).invoke(proxy, line.getField(rowkey));
  • Method addPut = proxy.getClass().getMethod("addPut",
  • new Class[]{String.class, String.class, String.class});
  • addPut.invoke(proxy, new Object[]{field, column, encode});
  • proxy.getClass().getMethod("putLine").invoke(proxy);
  • }
  • }
  • ClassLoader generateJarLoader() throws IOException {
  • String libPath = System.getProperty("java.ext.dirs");
  • FileFilter filter = new FileFilter() {
  • @Override
  • public boolean accept(File pathname) {
  • if(pathname.getName().startsWith("hadoop-0.19.2"))
  • return false;
  • else
  • return pathname.getName().endsWith(".jar");
  • }
  • };
  • File[] jars = new File(libPath).listFiles(filter);
  • URL[] jarUrls = new URL[jars.length+1];
  • int k = 0;
  • for (int i = 0; i < jars.length; i++) {
  • jarUrls[k++] = jars.toURI().toURL();
  • }
  • jarUrls[k] = new File("hadoop-0.20.205.jar")
  • ClassLoader jarloader = new URLClassLoader(jarUrls, null);
  • return jarloader;
  • }
main.java
void init(){
  ClassLoader jarloader = generateJarLoader();
  Class Proxy =Class.forName("test.writer.hbasewriter.HBaseProxy", true, jarloader);
  Constructor con = Proxy.getConstructor(new Class[]{String.class,String.class, boolean.class});
  Boolean autoflush =param.getBoolValue(ParamsKey.HbaseWriter.autoFlush, true);
  proxy = con.newInstance(new Object[]{path, tablename, autoflush});
}
void put(){
...
  while((line = getLine()) != null) {
   proxy.getClass().getMethod("generatePut",String.class).invoke(proxy,line.getField(rowkey));
   Method addPut = proxy.getClass().getMethod("addPut",
      new Class[]{String.class, String.class, String.class});
   addPut.invoke(proxy, new Object[]{field, column, encode});
   proxy.getClass().getMethod("putLine").invoke(proxy);
  }
}
ClassLoader generateJarLoader()throws IOException {
      String libPath =System.getProperty("java.ext.dirs");
      FileFilter filter = new FileFilter() {
      @Override
      public boolean accept(File pathname) {
        if(pathname.getName().startsWith("hadoop-0.19.2"))
          return false;
        else
         returnpathname.getName().endsWith(".jar");
      }
      };
      File[] jars = newFile(libPath).listFiles(filter);
      URL[] jarUrls = new URL[jars.length+1];
   
      int k = 0;
      for (int i = 0; i < jars.length; i++){
        jarUrls[k++] = jars.toURI().toURL();
      }
      jarUrls[k] = newFile("hadoop-0.20.205.jar")
      ClassLoader jarloader = newURLClassLoader(jarUrls, null);
     return jarloader;
}
Java代码
  • HBaseProxy.java
  • public HBaseProxy(String hbase_conf, String tableName, boolean autoflush)
  • throws IOException{
  • Configuration conf = new Configuration();
  • conf.addResource(new Path(hbase_conf));
  • config = new Configuration(conf);
  • htable = new HTable(config, tableName);
  • admin = new HBaseAdmin(config);
  • htable.setAutoFlush(autoflush);
  • }
  • public void addPut(String field, String column, String encode) throws IOException {
  • try {
  • p.add(column.split(":")[0].getBytes(), column.split(":")[1].getBytes(),
  • field.getBytes(encode));
  • } catch (UnsupportedEncodingException e) {
  • p.add(column.split(":")[0].getBytes(), column.split(":")[1].getBytes(),
  • field.getBytes());
  • }
  • }
  • public void generatePut(String rowkey){
  • p = new Put(rowkey.getBytes());
  • }
  • public void putLine() throws IOException{
  • htable.put(p);
  • }
HBaseProxy.java
public HBaseProxy(Stringhbase_conf, String tableName, boolean autoflush)
     throws IOException{
   Configuration conf = new Configuration();
   conf.addResource(new Path(hbase_conf));
   config = new Configuration(conf);
   htable = new HTable(config, tableName);
   admin = new HBaseAdmin(config);
   htable.setAutoFlush(autoflush);
  }
public void addPut(Stringfield, String column, String encode) throws IOException {
    try {
     p.add(column.split(":")[0].getBytes(), column.split(":")[1].getBytes(),
        field.getBytes(encode));
   } catch (UnsupportedEncodingException e) {
     p.add(column.split(":")[0].getBytes(),column.split(":")[1].getBytes(),
        field.getBytes());
   }
   
  }
    public void generatePut(String rowkey){
   p = new Put(rowkey.getBytes());
  }
  
    public void putLine() throws IOException{
   htable.put(p);
  }

总之,在同一个进程中载入多个classloader时一定要注意,classloader A所载入的对象是不能转换成classloader B的对象的,当然也不能使用。

两个空间的相互调用仅仅能用java的基本类型或是反射。

很多其它精彩内容请关注:http://bbs.superwu.cn

关注超人学院微信二维码:

关注超人学院java免费学习交流群:

在不同版本号hdfs集群之间转移数据的更多相关文章

  1. Hadoop(四)HDFS集群详解

    前言 前面几篇简单介绍了什么是大数据和Hadoop,也说了怎么搭建最简单的伪分布式和全分布式的hadoop集群.接下来这篇我详细的分享一下HDFS. HDFS前言: 设计思想:(分而治之)将大文件.大 ...

  2. adoop(四)HDFS集群详解

    阅读目录(Content) 一.HDFS概述 1.1.HDFS概述 1.2.HDFS的概念和特性 1.3.HDFS的局限性 1.4.HDFS保证可靠性的措施 二.HDFS基本概念 2.1.HDFS主从 ...

  3. HDFS集群优化篇

    HDFS集群优化篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.操作系统级别优化 1>.优化文件系统(推荐使用EXT4和XFS文件系统,相比较而言,更推荐后者,因为XF ...

  4. HDFS集群PB级数据迁移方案-DistCp生产环境实操篇

    HDFS集群PB级数据迁移方案-DistCp生产环境实操篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 用了接近2个星期的时间,终于把公司的需要的大数据组建部署完毕了,当然,在部 ...

  5. sqoop将oracle数据导入hdfs集群

    使用sqoop将oracle数据导入hdfs集群 集群环境: hadoop1.0.0 hbase0.92.1 zookeeper3.4.3 hive0.8.1 sqoop-1.4.1-incubati ...

  6. HDFS集群中DataNode的上线与下线

    在HDFS集群的运维过程中,肯定会遇到DataNode的新增和删除,即上线与下线.这篇文章就详细讲解下DataNode的上线和下线的过程. 背景 在我们的微职位视频课程中,我们已经安装了3个节点的HD ...

  7. vivo 万台规模 HDFS 集群升级 HDFS 3.x 实践

    vivo 互联网大数据团队-Lv Jia Hadoop 3.x的第一个稳定版本在2017年底就已经发布了,有很多重大的改进. 在HDFS方面,支持了Erasure Coding.More than 2 ...

  8. 【Redis】集群故障转移

    集群故障转移 节点下线 在集群定时任务clusterCron中,会遍历集群中的节点,对每个节点进行检查,判断节点是否下线.与节点下线相关的状态有两个,分别为CLUSTER_NODE_PFAIL和CLU ...

  9. HDFS集群balance(2)-- 架构概览

    转载请注明博客地址:http://blog.csdn.net/suileisl HDFS集群balance,对应版本balance design 6 如需word版本,请QQ522173163联系索要 ...

随机推荐

  1. 6个最佳的开源Python应用服务器

    6个最佳的开源Python应用服务器 首先,你知道什么是应用服务器吗?应用服务器通常被描述为是存在于服务器中心架构中间层的一个软件框架. AD: 首先,你知道什么是应用服务器吗?应用服务器通常被描述为 ...

  2. Android中Parcelable序列化总结

    在使用Parcelable对android中数据的序列化操作还是比较有用的,有人做过通过对比Serializable和Parcelable在android中序列化操作对象的速度比对,大概Parcela ...

  3. HTML+CSS+JS - 5秒钟之后跳转页面

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.c ...

  4. 在Ubuntu 12.04下编译qtiplot

    不在windows下,再加上不想用盗版,所以需要一个origin的替代品——qtiplot.虽然我非常抵抗用这种不停点来点去的软件,用R的ggplot2画图多好啊,高效.优雅.漂亮,但是终抵不过老板一 ...

  5. Windows phone 8 学习笔记

    Windows phone 8 学习笔记(1) 触控输入  http://www.apkbus.com/android-138547-1-1.html Windows phone 8 学习笔记(2) ...

  6. Android学习笔记(九)——更复杂的进度对话框

    显示操作进度的对话框 1.使用上一篇创建的同一项目.在activity_main.xml文件里加入一个Button: <Button android:id="@+id/btn_dial ...

  7. Kendo UI开发教程(26): 单页面应用(四) Layout

    Layout继承自View,可以用来包含其它的View或是Layout.下面例子使用Layout来显示一个View 1 <div id="app"></div&g ...

  8. python 默认编码( UnicodeDecodeError: 'ascii' codec can't decode)

    python在安装时,默认的编码是ascii,当程序中出现非ascii编码时,python的处理常常会报这样的错UnicodeDecodeError: 'ascii' codec can't deco ...

  9. Ppoj 1014 深搜

    这个题题意是给你价值1-6的珠宝个数输出能否平分为两份(如果平分为三分就不知道怎么做了……) 主要是用回溯DFS,但是要剪枝,对200取模……!!(很重要……) 代码…… #include <i ...

  10. TDD测试驱动的javascript开发(3) ------ javascript的继承

    说起面向对象,人们就会想到继承,常见的继承分为2种:接口继承和实现继承.接口继承只继承方法签名,实现继承则继承实际的方法. 由于函数没有签名,在ECMAScript中无法实现接口继承,只支持实现继承. ...