4

我正在看以下场景。我每天都会发送一个数据文件。我将它添加到 HBase 中,名称为 file-yyyyMMdd 格式。所以在一段时间内我有很多数据库,例如

tempdb-20121220
tempdb-20121221
tempdb-20121222
tempdb-20121223
tempdb-20121224
tempdb-20121225

现在我想做的是针对特定日期范围获取列表,如果表匹配该范围,以便我可以创建索引。我正在使用 hbase-0.90.6

就我的研究而言,TableMapReduceUtil.initTableMapperJob 只需要 1 个表名。

TableMapReduceUtil.initTableMapperJob(
tableName,        // input HBase table name
scan,             // Scan instance to control CF and attribute selection
HBaseIndexerMapper.class,   // mapper
null,             // mapper output key
null,             // mapper output value
job
);

我已经能够获取表列表并循环运行它,但我的想法是我可以遍历所有表,扫描它(或其他东西),以便最终我可以获得用于索引目的的合并/组合结果.

实现这一目标的任何方向都会非常有用。

4

2 回答 2

3

好的,请检查HBase 0.94.6来源(看起来它们最适合您)。在那里你会发现MultiTableInputFormat 类(按照链接查看包含示例的 JavaDoc),它可以满足你的需要。就在几天前,我有经验将这个类添加到HBase 0.94.2(实际上CDH 4.2.1)基于项目的项目中。成功。

这似乎以非常有效的方式完全满足您的需求。这里唯一的问题是您将有一个映射器处理所有数据。要区分表,您可能需要TableSplit从 0.94.6 中获取类,将其重命名有所不同并移植以不破坏您的环境。请检查 TableMapReduceUtil 中的差异 - 您需要手动配置扫描,以便输入格式能够理解它们的配置。

还可以考虑简单地移动到HBase 0.94.6- 更简单的方式,因为我无法遵循它。我花了大约 12 个工作小时来了解这里的问题/调查解决方案/了解我的 CDH 4.2.1 问题/移植所有内容。对我来说好消息是 Cloudera 打算在 CDH 4.3.0 中迁移到 0.94.6。

UPDATE1:CDH 4.3.0可用,它包括 HBase 0.94.6 和所有必需的基础设施。

UPDATE2:我转向其他解决方案 - 自定义输入格式,它结合了几个 HBase 表,按键混合它们的行。碰巧非常有用,尤其是在适当的按键设计下。您可以在单个映射器中获得整个聚合。我正在考虑在 github 上发布此代码。

于 2013-05-19T18:21:32.983 回答
1

List<scans>也是一种方式。我也同意 MultipleTableInputFormat :

import java.util.List; 
import org.apache.hadoop.conf.Configuration; 
import org.apache.hadoop.conf.Configured; 
import org.apache.hadoop.hbase.client.Scan; 
import org.apache.hadoop.hbase.mapreduce.TableMapReduceUtil; 
import org.apache.hadoop.hbase.util.Bytes; 
import org.apache.hadoop.io.IntWritable; 
import org.apache.hadoop.io.Text; 
import org.apache.hadoop.mapreduce.Job; 
import org.apache.hadoop.util.Tool; 

 public class TestMultiScan extends Configured implements Tool { 

    @Override 
    public int run(String[] arg0) throws Exception { 
        List<Scan> scans = new ArrayList<Scan>(); 


        Scan scan1 = new Scan(); 
        scan1.setAttribute("scan.attributes.table.name", Bytes.toBytes("table1ddmmyyyy")); 
        System.out.println(scan1.getAttribute("scan.attributes.table.name")); 
        scans.add(scan1); 


        Scan scan2 = new Scan(); 
        scan2.setAttribute("scan.attributes.table.name", Bytes.toBytes("table2ddmmyyyy")); 
        System.out.println(scan2.getAttribute("scan.attributes.table.name")); 
        scans.add(scan2); 


        Configuration conf = new Configuration(); 
        Job job = new Job(conf);     
        job.setJarByClass(TestMultiScan.class); 


        TableMapReduceUtil.initTableMapperJob( 
                scans,  
                MultiTableMappter.class,  
                Text.class,  
                IntWritable.class,  
                job); 
        TableMapReduceUtil.initTableReducerJob( 
                "xxxxx", 
                MultiTableReducer.class,  
                job); 
        job.waitForCompletion(true); 
        return 0; 
    } 

    public static void main(String[] args) throws Exception { 
        TestMultiScan runJob = new TestMultiScan(); 
        runJob.run(args); 
    } 
 } 

通过这种方式,我们通过 HBASE 命名空间表解决了多租户需求。例如:DEV1:TABLEX(DATA INGESTED BY DEV1) UAT1:TABLEX (DATA CONSUED BY UAT1) 在映射器中,我们想要比较两个命名空间表以进一步进行。

在内部它使用了多表输入格式,如 TableMapReduceUtil.java 中所示

TableMapReduceUtil 内部使用 MultiTableInputFormat

于 2015-11-07T17:10:58.840 回答