HBase MapReduce数据操作

46 篇文章 6 订阅
13 篇文章 0 订阅

一、Hbase数据库

HBase是一种“NoSQL”数据库。HBase具有很多支持线性和模块化缩放的功能。通过添加商品类服务器上托管的RegionServers来扩展HBase集群。例如,如果一个集群从10个扩展到20个RegionServers,则它在存储和处理能力方面都会翻倍。RDBMS可以很好地扩展,但只能达到某一点 - 具体而言就是单个数据库服务器的大小 - 并且为了获得最佳性能,需要专门的硬件和存储设备。

Hbase的特点:
1,一致的读/写:HBase不是“最终一致的”DataStore。这使它非常适合诸如高速计数器聚合之类的任务。
2,自动分片:HBase表通过区域分布在集群上,随着数据增长,区域会自动分割和重新分配。
3,自动RegionServer故障切换
4,Hadoop/HDFS集成:HBase支持HDFS作为其分布式文件系统。
5,MapReduce:HBase支持通过MapReduce进行大规模并行处理,以便将HBase用作源和接收器。
6,Java客户端API:HBase支持易于使用的Java API进行编程式访问。
7,Thrift/REST API:HBase还支持非Java前端的Thrift和REST。
8,块缓存和Bloom过滤器:HBase支持块缓存和Bloom过滤器,以实现高容量查询优化。
9,操作管理:HBase提供内置的网页以提供运营洞察力以及JMX指标。

二、HBase、MapReduce和CLASSPATH

默认情况下,部署到 MapReduce 集群的 MapReduce 作业无权访问 $HBASE_CONF_DIR 类或 HBase 类下的 HBase 配置。
要为 MapReduce 作业提供他们需要的访问权限,可以添加 hbase-site.xml_to _ $ HADOOP_HOME / conf,并将 HBase jar 添加到 $ HADOOP_HOME / lib 目录。然后,您需要在群集中复制这些更改。或者你可以编辑 $ HADOOP_HOME / conf / hadoop-env.sh,并将 hbase 依赖添加到HADOOP_CLASSPATH 变量中。这两种方法都不推荐使用,因为它会使用 HBase 引用污染您的 Hadoop 安装。它还需要您在 Hadoop 可以使用 HBase 数据之前重新启动 Hadoop 集群。
推荐的方法是让 HBase 添加它的依赖 jar 并使用 HADOOP_CLASSPATHor -libjars。
自 HBase 0.90.x 以来,HBase 将其依赖 JAR 添加到作业配置本身。依赖关系只需要在本地 CLASSPATH 可用,从这里它们将被拾取并捆绑到部署到MapReduce 集群的 fat 工作 jar 中。一个基本的技巧就是将完整的 hbase 类路径(所有 hbase 和依赖 jar 以及配置)传递给 mapreduce 作业运行器,让hbase 实用程序从完整类路径中选取需要将其添加到 MapReduce 作业配置中的源代码。
下面的示例针对名为 usertable 的表运行捆绑的 HBase RowCounter MapReduce 作业。它设置为 HADOOP_CLASSPATH 需要在 MapReduce 上下文中运行的 jar 包(包括配置文件,如 hbase-site.xml)。确保为您的系统使用正确版本的 HBase JAR;请在下面的命令行中替换 VERSION 字符串 w/本地 hbase 安装的版本。反引号(`符号)使 shell 执行子命令,设置输入 hbase classpath 为 HADOOP_CLASSPATH。这个例子假设你使用 BASH 兼容的 shell。

$ HADOOP_CLASSPATH=`${HBASE_HOME}/bin/hbase classpath` \
  ${HADOOP_HOME}/bin/hadoop jar ${HBASE_HOME}/lib/hbase-mapreduce-VERSION.jar \
  org.apache.hadoop.hbase.mapreduce.RowCounter usertable

上述的命令将针对 hadoop 配置指向的群集上的本地配置指向的 hbase 群集启动行计数 mapreduce 作业。
hbase-mapreduce.jar 的主要内容是一个 Driver(驱动程序),它列出了几个与 hbase 一起使用的基本 mapreduce 任务。例如,假设您的安装是hbase 2.0.0-SNAPSHOT:

$ HADOOP_CLASSPATH=`${HBASE_HOME}/bin/hbase classpath` \
  ${HADOOP_HOME}/bin/hadoop jar ${HBASE_HOME}/lib/hbase-mapreduce-2.0.0-SNAPSHOT.jar
An example program must be given as the first argument.
Valid program names are:
  CellCounter: Count cells in HBase table.
  WALPlayer: Replay WAL files.
  completebulkload: Complete a bulk data load.
  copytable: Export a table from local cluster to peer cluster.
  export: Write table data to HDFS.
  exportsnapshot: Export the specific snapshot to a given FileSystem.
  import: Import data written by Export.
  importtsv: Import data in TSV format.
  rowcounter: Count rows in HBase table.
  verifyrep: Compare the data from tables in two different clusters. WARNING: It doesn't work for incrementColumnValues'd cells since the timestamp is changed after being appended to the log.

可能会发现更多有选择性的 hbase mapredcp 工具输出;它列出了针对 hbase 安装运行基本 mapreduce 作业所需的最小 jar 集。它不包括配置。如果您希望MapReduce 作业找到目标群集,则可能需要添加这些文件。一旦你开始做任何实质的事情,你可能还必须添加指向额外的 jar 的指针。只需在运行 hbase mapredcp 时通过系统属性 Dtmpjars 来指定附加项。
对于不打包它们的依赖关系或调用 TableMapReduceUtil#addDependencyJars 的作业,以下命令结构是必需的:

$ HADOOP_CLASSPATH=`${HBASE_HOME}/bin/hbase mapredcp`:${HBASE_HOME}/conf hadoop jar MyApp.jar MyJobMainClass -libjars $(${HBASE_HOME}/bin/hbase mapredcp | tr ':' ',') ...

注意:
如果您从构建目录运行 HBase 而不是安装位置,该示例可能无法运行。您可能会看到类似以下的错误:

java.lang.RuntimeException: java.lang.ClassNotFoundException: org.apache.hadoop.hbase.mapreduce.RowCounter$RowCounterMapper

如果发生这种情况,请尝试按如下方式修改该命令,以便在构建环境中使用来自 target/ 目录的 HBase JAR 。

$ HADOOP_CLASSPATH=${HBASE_BUILD_HOME}/hbase-mapreduce/target/hbase-mapreduce-VERSION-SNAPSHOT.jar:`${HBASE_BUILD_HOME}/bin/hbase classpath` ${HADOOP_HOME}/bin/hadoop jar ${HBASE_BUILD_HOME}/hbase-mapreduce/target/hbase-mapreduce-VERSION-SNAPSHOT.jar rowcounter usertable

三、HBase MapReduce操作示例

1,HBase MapReduce 读数据

以只读方式将 HBase 用作 MapReduce 源的示例。具体来说,有一个 Mapper 实例,但没有 Reducer,并且没有任何内容从 Mapper 发出。

Configuration config = HBaseConfiguration.create();
Job job = new Job(config, "ExampleRead");
job.setJarByClass(MyReadJob.class);     // class that contains mapper

Scan scan = new Scan();
scan.setCaching(500);        // 1 is the default in Scan, which will be bad for MapReduce jobs
scan.setCacheBlocks(false);  // don't set to true for MR jobs
// set other scan attrs
...
TableMapReduceUtil.initTableMapperJob(
  tableName,        // input HBase table name
  scan,             // Scan instance to control CF and attribute selection
  MyMapper.class,   // mapper
  null,             // mapper output key
  null,             // mapper output value
  job);
job.setOutputFormatClass(NullOutputFormat.class);   // because we aren't emitting anything from mapper

boolean b = job.waitForCompletion(true);
if (!b) {
  throw new IOException("error with job!");
}

映射器实例将扩展 TableMapper:

public static class MyMapper extends TableMapper<Text, Text> {

  public void map(ImmutableBytesWritable row, Result value, Context context) throws InterruptedException, IOException {
    // process data for the row from the Result instance.
   }
}

2,HBase MapReduce 数据复制

使用 HBase 作为 MapReduce 的源代码和接收器的示例。这个例子将简单地将数据从一个表复制到另一个表。

Configuration config = HBaseConfiguration.create();
Job job = new Job(config,"ExampleReadWrite");
job.setJarByClass(MyReadWriteJob.class);    // class that contains mapper

Scan scan = new Scan();
scan.setCaching(500);        // 1 is the default in Scan, which will be bad for MapReduce jobs
scan.setCacheBlocks(false);  // don't set to true for MR jobs
// set other scan attrs

TableMapReduceUtil.initTableMapperJob(
  sourceTable,      // input table
  scan,             // Scan instance to control CF and attribute selection
  MyMapper.class,   // mapper class
  null,             // mapper output key
  null,             // mapper output value
  job);
TableMapReduceUtil.initTableReducerJob(
  targetTable,      // output table
  null,             // reducer class
  job);
job.setNumReduceTasks(0);

boolean b = job.waitForCompletion(true);
if (!b) {
    throw new IOException("error with job!");
}

需要解释的是 TableMapReduceUtil 正在做什么,特别是对于减速器。TableOutputFormat 被用作 outputFormat 类,并且正在配置几个参数(例如,TableOutputFormat.OUTPUT_TABLE),以及将 reducer 输出键设置为 ImmutableBytesWritable 和 reducer 值为 Writable。这些可以由程序员在作业和 conf 中设置,但 TableMapReduceUtil 试图让事情变得更容易。
以下是示例映射器,它将创建 Put 并匹配输入 Result 并发出它。注意:这是 CopyTable 实用程序的功能。

public static class MyMapper extends TableMapper<ImmutableBytesWritable, Put>  {

  public void map(ImmutableBytesWritable row, Result value, Context context) throws IOException, InterruptedException {
    // this example is just copying the data from the source table...
      context.write(row, resultToPut(row,value));
    }

    private static Put resultToPut(ImmutableBytesWritable key, Result result) throws IOException {
      Put put = new Put(key.get());
      for (KeyValue kv : result.raw()) {
        put.add(kv);
      }
      return put;
    }
}

TableOutputFormat 负责将 Put 发送到目标表。

3,HBase MapReduce 汇总计数到HBase 表

使用 HBase 作为 MapReduce 源,并使用一个总结步骤。此示例将计算表中某个值的不同实例的数量,并将这些汇总计数写入另一个表中。

Configuration config = HBaseConfiguration.create();
Job job = new Job(config,"ExampleSummary");
job.setJarByClass(MySummaryJob.class);     // class that contains mapper and reducer

Scan scan = new Scan();
scan.setCaching(500);        // 1 is the default in Scan, which will be bad for MapReduce jobs
scan.setCacheBlocks(false);  // don't set to true for MR jobs
// set other scan attrs

TableMapReduceUtil.initTableMapperJob(
  sourceTable,        // input table
  scan,               // Scan instance to control CF and attribute selection
  MyMapper.class,     // mapper class
  Text.class,         // mapper output key
  IntWritable.class,  // mapper output value
  job);
TableMapReduceUtil.initTableReducerJob(
  targetTable,        // output table
  MyTableReducer.class,    // reducer class
  job);
job.setNumReduceTasks(1);   // at least one, adjust as required

boolean b = job.waitForCompletion(true);
if (!b) {
  throw new IOException("error with job!");
}

在此示例映射器中,选择一个带有字符串值的列作为要汇总的值。该值用作从映射器发出的密钥,IntWritable 代表实例计数器。

public static class MyMapper extends TableMapper<Text, IntWritable>  {
  public static final byte[] CF = "cf".getBytes();
  public static final byte[] ATTR1 = "attr1".getBytes();

  private final IntWritable ONE = new IntWritable(1);
  private Text text = new Text();

  public void map(ImmutableBytesWritable row, Result value, Context context) throws IOException, InterruptedException {
    String val = new String(value.getValue(CF, ATTR1));
    text.set(val);     // we can only emit Writables...
    context.write(text, ONE);
  }
}

在 reducer 中,“ones” 被计数(就像任何其他的 MR 例子一样),然后发出一个 Put。

public static class MyTableReducer extends TableReducer<Text, IntWritable, ImmutableBytesWritable>  {
  public static final byte[] CF = "cf".getBytes();
  public static final byte[] COUNT = "count".getBytes();

  public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
    int i = 0;
    for (IntWritable val : values) {
      i += val.get();
    }
    Put put = new Put(Bytes.toBytes(key.toString()));
    put.add(CF, COUNT, Bytes.toBytes(i));

    context.write(null, put);
  }
}

4,HBase MapReduce 写数据到HDFS文件

与HBase MapReduce摘要到HBase示例非常相似,不同之处在于,它将 HBase 用作 MapReduce 源,但将 HDFS 用作接收器。差异在于作业设置和减速器中。映射器保持不变。

Configuration config = HBaseConfiguration.create();
Job job = new Job(config,"ExampleSummaryToFile");
job.setJarByClass(MySummaryFileJob.class);     // class that contains mapper and reducer

Scan scan = new Scan();
scan.setCaching(500);        // 1 is the default in Scan, which will be bad for MapReduce jobs
scan.setCacheBlocks(false);  // don't set to true for MR jobs
// set other scan attrs

TableMapReduceUtil.initTableMapperJob(
  sourceTable,        // input table
  scan,               // Scan instance to control CF and attribute selection
  MyMapper.class,     // mapper class
  Text.class,         // mapper output key
  IntWritable.class,  // mapper output value
  job);
job.setReducerClass(MyReducer.class);    // reducer class
job.setNumReduceTasks(1);    // at least one, adjust as required
FileOutputFormat.setOutputPath(job, new Path("/tmp/mr/mySummaryFile"));  // adjust directories as required

boolean b = job.waitForCompletion(true);
if (!b) {
  throw new IOException("error with job!");
}

前面的Mapper可以与此示例保持不变。至于减速机,它是一种“通用”的减速机,而不是扩展的制表机和发射装置。

public static class MyReducer extends Reducer<Text, IntWritable, Text, IntWritable>  {

  public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
    int i = 0;
    for (IntWritable val : values) {
      i += val.get();
    }
    context.write(key, new IntWritable(i));
  }
}

文章来源:
https://hbase.apache.org/book.html#mapreduce
https://www.w3cschool.cn/hbase_doc/

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晓之以理的喵~~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值