2015-10-19 1421 views
5

设置:

我有一个HBase表,有100M +行和1百万列。每行只有2到5列的数据。只有1列家庭。我们可以从HBase表中获取所有列名吗?

问题:

我想找出所有不同qualifiers(列)在此column family。有没有快速的方法来做到这一点?

我可以想到扫描整个表格,然后得到familyMap为每一行,得到qualifier并将其添加到Set<>。但那会非常缓慢,因为有100M +行。

我们可以做得更好吗?

回答

1

HBase的可以看作分布式NavigableMap<byte[], NavigableMap<byte[], NavigableMap<byte[], NavigableMap<Long, byte[]>>>>

有关,在所有地区服务器的所有可用预选赛的名单没有“元数据”(说点什么集中存储在主节点)。

因此,如果您有一次性使用情况,唯一的方法是扫描整个表并在Set<>中添加限定符名称,就像您提到的那样。

如果这是一个重复使用的情况(如果您有自由裁量权将组件添加到您的技术栈),您可能需要考虑添加Redis。使用Redis Set可以以分布式方式维护一组限定符。

0

HBase Coprocessors可用于此场景。您可以编写定制的EndPoint实现,它像RDBMS中的存储过程一样工作。它在服务器端执行你的代码并为每个区域获取不同的列。在客户端,您可以获得所有地区的不同列。

性能优点:所有列都不会传输到客户端,从而减少网络呼叫。

2

您可以使用mapreduce来做到这一点。在这种情况下,您不需要为协处理器安装hbase的自定义库。 下面是创建mapreduce任务的代码。

任务设置

Job job = Job.getInstance(config); 
    job.setJobName("Distinct columns"); 

    Scan scan = new Scan(); 
    scan.setBatch(500); 
    scan.addFamily(YOU_COLUMN_FAMILY_NAME); 
    scan.setFilter(new KeyOnlyFilter()); //scan only key part of KeyValue (raw, column family, column) 
    scan.setCacheBlocks(false); // don't set to true for MR jobs 


    TableMapReduceUtil.initTableMapperJob(
      YOU_TABLE_NAME, 
      scan,   
      OnlyColumnNameMapper.class, // mapper 
      Text.class,    // mapper output key 
      Text.class,    // mapper output value 
      job); 

    job.setNumReduceTasks(1); 
    job.setReducerClass(OnlyColumnNameReducer.class); 
    job.setReducerClass(OnlyColumnNameReducer.class); 

映射

public class OnlyColumnNameMapper extends TableMapper<Text, Text> { 
    @Override 
    protected void map(ImmutableBytesWritable key, Result value, final Context context) throws IOException, InterruptedException { 
     CellScanner cellScanner = value.cellScanner(); 
     while (cellScanner.advance()) { 

      Cell cell = cellScanner.current(); 
      byte[] q = Bytes.copy(cell.getQualifierArray(), 
           cell.getQualifierOffset(), 
           cell.getQualifierLength()); 

      context.write(new Text(q),new Text()); 

     } 
} 

}

减速

public class OnlyColumnNameReducer extends Reducer<Text, Text, Text, Text> { 

    @Override 
    protected void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {  
      context.write(new Text(key), new Text());  
    } 
} 
相关问题