【发布时间】:2020-06-09 02:16:40
【问题描述】:
我正在尝试对我的 HBase 数据集进行一些处理。但我对 HBase 和 Hadoop 生态系统还很陌生。
我想从这个社区得到一些反馈,看看我对 HBase 的理解和对它的 MapReduce 操作是否正确。
这里有一些背景:
- 我们有一个大约 1TB 的 HBase 表,超过 1 亿条记录。2。它有 3 个区域服务器,每个区域服务器包含大约 80 个区域,总区域为 240.3。据我所知,表中的记录应该非常均匀地分布到每个区域。
我想要实现的是,我可以根据某些列值过滤掉行,并将这些行导出到 HDFS 文件系统或类似的东西。
例如,我们有一个名为“type”的列,它可能包含值 1 或 2 或 3。我想要 3 个不同的 HDFS 文件(或目录,因为 HDFS 上的数据已分区)具有类型的记录分别为 1、2、3。
据我所知,MapReduce 似乎是解决这类问题的好方法。
我做了一些研究和实验,可以得到我想要的结果。但我不确定我是否理解 HBase TableMapper 和 Scan 的行为,但这对我们的代码性能至关重要,因为我们的数据集非常大。
为了简化问题,我以官方RowCounter的实现为例,我想确认我的知识是正确的。
所以我对带有 MapReduce 的 HBase 的问题是:
在最简单的 RowCounter 形式中(没有任何可选参数),它实际上是全表扫描。 HBase 遍历表中的所有记录,并将行发送到 RowCounterMapper 中的 map 方法。这是正确的吗?
TableMapper 将根据我们在一个表中有多少个区域来划分任务。例如,如果我们的 HBase 表中只有 1 个区域,那么它就只有 1 个 map 任务,它实际上相当于一个线程,并且没有利用我们的 hadoop 集群的任何并行处理?
如果以上是正确的,我们是否可以配置 HBase 为一个区域生成多个任务?比如我们对只有1个region的表做RowCounter,它还有10个或20个任务,并行计算行数?
由于 TableMapper 也依赖于 Scan 操作,所以我也想确认一下我对 Scan 操作和性能的理解。
如果我使用 setStartRow / setEndRow 来限制我的数据集的范围,因为 rowkey 被索引,它不会影响我们的性能,因为它不会发出全表扫描。
在我们的例子中,我们可能需要根据修改时间过滤我们的数据。在这种情况下,我们可能会使用 scan.setTimeRange() 来限制数据集的范围。我的问题是,既然 HBase 不索引时间戳,那么这个扫描会不会变成全表扫描,和我们只是通过 MapReduce 作业本身过滤它相比没有任何优势?
最后,实际上我们讨论了应该如何进行此导出。我们有以下两种方法,但不确定哪一种更好。
使用上述 MapReduce 方法。但我们不确定并行度是否会受到表有多少区域的限制。即,并发永远不会超过区域数,除非我们增加区域,否则我们无法提高性能。
我们在一个单独的地方(可能在 HDFS 上)维护了一个 rowkey 列表,我们使用 spark 读取文件,然后使用简单的 Get 操作获取记录。所有的并发都发生在 spark/hadoop 端。
我想从这个社区获得一些关于哪种解决方案更好的建议,这将非常有帮助。谢谢。
【问题讨论】: