尝试确认我对HBase和MapReduce行为的理解



我正在尝试在我的HBase数据集上做一些过程。但我对HBase和Hadoop生态系统很陌生。

我想从这个社区得到一些反馈,看看我对HBase和MapReduce操作的理解是否正确。

这里有一些背景:

  1. 我们有一个大约 1TB 的 HBase 表,超过 1 亿条记录.2.它有 3 个区域服务器,每个区域服务器包含大约 80 个区域,使总区域为 240.3。据我所知,表中的记录应该非常统一地分布到每个地区。

我想要实现的是,我可以根据一些列值过滤掉行,并将这些行导出到 HDFS 文件系统或类似的东西。

例如,我们有一个名为"type"的列,它可能包含值 1、2 或 3。我希望有 3 个不同的 HDFS 文件(或目录,因为 HDFS 上的数据是分区的(,它们分别具有类型 1、2、3 的记录。

据我所知,MapReduce似乎是解决这类问题的好方法。

我做了一些研究和实验,可以得到我想要的结果。但我不确定我是否理解HBase TableMapper和Scan的行为,但它对我们的代码性能至关重要,因为我们的数据集非常大。

为了简化问题,我会以官方的 RowCounter 实现为例,我想确认我的知识是正确的。

所以我关于HBase与MapReduce的问题是:

  1. 在最简单的 RowCounter 形式(没有任何可选参数(中,它实际上是全表扫描。 HBase 循环访问表中的所有记录,并将行发送到 RowCounterMapper 中的映射方法。这是对的吗?

  2. TableMapper 将根据表中有多少个区域来划分任务。例如,如果我们的 HBase 表中只有 1 个区域,它将只有 1 个映射任务,它实际上等于单个线程,并且没有利用我们的 hadoop 集群的任何并行处理?

  3. 如果上述是正确的,我们是否可以将 HBase 配置为为一个区域生成多个任务?例如,当我们对只有 1 个区域的表执行 RowCounter 时,它仍然有 10 或 20 个任务,并且以并行方式计算行?

由于 TableMapper 也依赖于扫描操作,因此我还想确认我对扫描操作和性能的理解。

  1. 如果我使用 setStartRow/setEndRow 来限制数据集的范围,因为 rowkey 被索引,它不会影响我们的性能,因为它不会发出全表扫描。

  2. 在我们的例子中,我们可能需要根据修改时间过滤数据。在这种情况下,我们可能会使用 scan.setTimeRange(( 来限制数据集的范围。我的问题是,由于HBase不索引时间戳,因此此扫描是否会成为全表扫描,并且与我们仅通过MapReduce作业本身过滤它相比没有任何优势?

最后,实际上我们对如何进行此导出进行了一些讨论。我们有以下两种方法,但不确定哪一种更好。

  1. 使用上述MapReduce方法。但我们不确定并行性是否会受到表有多少个区域的约束。即,并发永远不会超过区域计数,除非增加区域,否则我们无法提高性能。

  2. 我们在单独的位置(可能在 HDFS 上(维护一个行键列表,我们使用 Spark 读取文件,然后使用简单的 Get 操作获取记录。所有并发都发生在火花/哈doop端。

我想就这个社区的哪种解决方案更好提出一些建议,这将非常有帮助。谢谢。

似乎你有一个非常小的集群。可伸缩性还取决于区域服务器 (RS( 的数量。因此,仅仅增加表中的区域数而不增加区域服务器数并不能真正帮助您加快作业速度。我认为该表本身的 80 个区域/RS 就足够了。 我假设您将要使用 TableInputFormat,它通过运行 1 个映射器/区域来工作,并根据扫描对象执行服务器端过滤器。我同意使用TableInputFormat进行扫描是从hbase导出大量数据的最佳方法,但可扩展性和性能不仅与区域数量成正比。还有许多其他因素,例如每个RS上的#RS,RAM和磁盘,数据的均匀分布就是其中的一部分。

一般来说,我会选择#1,因为你只需要准备一个扫描对象,然后hbase就会负责休息。

#2 更麻烦,因为您需要在 hbase 之外维护行键状态。

最新更新