我正在尝试对我的HBase数据集进行一些处理。但是我对HBase和Hadoop生态系统还很陌生。
我想从这个社区中获得一些反馈,以查看我对HBase及其上的MapReduce操作的理解是否正确。
这里有一些背景:
而且我想要实现的是,我可以根据某些列值过滤掉行,并将这些行导出到HDFS文件系统或类似的文件。
例如,我们有一个名为“类型”的列,它可能包含值1或2或3。我想拥有3个不同的HDFS文件(或目录,因为HDFS上的数据已分区),它们的记录类型为1 ,2、3。
据我所知,MapReduce似乎是解决这类问题的好方法。
我已经进行了一些研究和实验,并可以获得想要的结果。但是我不确定我是否了解HBase TableMapper和Scan的行为,但这对我们的代码性能至关重要,因为我们的数据集非常大。
为了简化问题,我以正式的RowCounter实现为例,我想确认我的知识是正确的。
所以我对带有MapReduce的HBase的疑问是:
以最简单的RowCounter形式(没有任何可选参数),它实际上是全表扫描。 HBase遍历表中的所有记录,并将行发送到RowCounterMapper中的map方法。这是正确的吗?
TableMapper将根据表中有多少个区域来划分任务。例如,如果我们的HBase表中只有1个区域,则它将只有1个映射任务,并且实际上等于一个线程,并且不利用hadoop集群的任何并行处理?
如果以上正确,我们是否可以配置HBase为一个区域生成多个任务?例如,当我们在仅具有1个区域的表上执行RowCounter时,它仍然具有10或20个任务,并以并行方式对行进行计数?
由于TableMapper也依赖于Scan操作,所以我也想确认我对Scan操作和性能的理解。
如果我使用setStartRow / setEndRow限制数据集的范围,因为对行键进行了索引,因为它不会发出全表扫描,所以它不会影响我们的性能。
在我们的情况下,我们可能需要根据修改后的时间过滤数据。在这种情况下,我们可以使用scan.setTimeRange()限制数据集的范围。我的问题是,由于HBase不会为时间戳编制索引,因此与仅通过MapReduce作业本身对其进行过滤相比,该扫描是否将成为全表扫描,并且没有任何优势?
最后,实际上我们在讨论如何进行此导出。而且,我们有以下两种方法,但不确定哪种方法更好。
使用上述MapReduce方法。但是我们不确定并行性是否会受到表具有多少个区域的约束。也就是说,并发永远不会超过区域数,除非增加区域,否则我们无法提高性能。
我们在单独的位置维护行键列表(可能在HDFS上),我们使用spark读取文件,然后使用简单的Get操作获取记录。所有并发发生在spark / hadoop一侧。
我想就此社区中哪种解决方案更好提供一些建议,这将非常有帮助。谢谢。
似乎您的集群很小。可伸缩性还取决于区域服务器(RS)的数量。因此,仅增加表中的区域数量而不增加区域服务器的数量并不能真正帮助您加快工作速度。我认为该表格本身的80个区域/ RS足够不错。我假设您将使用TableInputFormat,它通过运行1个映射器/区域来工作,并基于扫描对象执行服务器端过滤。我同意使用TableInputFormat进行扫描是从hbase导出大量数据的最佳方法,但可伸缩性和性能不仅仅与区域数量成正比。还有许多其他因素,例如每个RS上的RS数量,RAM和磁盘,其中一些是数据的均匀分布。
通常,我会选择#1,因为您只需要准备一个扫描对象,然后hbase会处理其余的工作。
#2更加麻烦,因为您需要在hbase外部维护行键状态。