在不同版本hdfs集群之间转移数据
本文仅供记录一下程序心得:
很多人会有这样一个需求:将一个hdfs集群上的数据写入另一个hdfs集群所在的hbase数据库。通常情况下两个hdfs集群的版本差距并不大,这样的程序会很容易写。但有时会跨大版本。比如作者所在的厂子,数据都在基于hadoop0.19.2版本修改的hdfs集群上,要将这样的数据导入版本为0.20.2+的hdfs集群,就不能使用同一个hadoop jar包来完成了。如何实现呢?
最简单的办法就是把src集群的数据导到本地,然后起另一个进程将本地数据传到des集群上去。
不过这有几个问题:
效率降低 占用本地磁盘空间 不能应付实时导数据需求 两个进程需要协调,复杂度增加
更好的办法是在同一个进程内一边读src数据,一边写des集群。不过这相当于在同一个进程空间内加载两个版本的hadoop jar包,这就需要在程序中使用两个classloader来实现。
以下代码可以实现classloader加载自定义的jar包,并生成需要的Configuration对象:
HBaseProxy.javapublic 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);}