我有一个HBase数据库,它存储有向图的邻接列表,每个方向的边存储在一对列族中,其中每一行表示一个顶点。我正在编写一个mapreduce作业,它将所有节点作为输入,这些节点的边缘也指向相同的顶点,边缘指向某个其他顶点(指定为查询的主题)。这有点难以解释,但在下图中,当查询顶点'A'时,作为输入的节点集将是{A,B,C},因为它们都具有来自顶点的边缘'1':
要在HBase中执行此查询,我首先在反向边缘列族中查找边缘为'A'的顶点,产生{1},并为该集合中的每个元素查找具有该元素边缘的顶点该集合,在前沿列族中。
这应该产生一组键值对:{1:{A,B,C}}。
现在,我想获取这组查询的输出并将其传递给hadoop mapreduce作业,但是,我无法找到一种方法将hbase查询“链接”在一起以向TableMapper提供输入Hbase mapreduce API。到目前为止,我唯一的想法是提供另一个初始映射器,它获取第一个查询的结果(在反向边缘表上),对于每个结果,在前沿边缘表上执行查询,并产生要传递给的结果第二个地图工作。但是,从地图作业中执行IO会让我感到不安,因为它似乎与mapreduce范例相反(如果几个映射器都试图立即访问HBase,可能会导致瓶颈)。因此,任何人都可以建议执行此类查询的替代策略,或者以这种方式提供有关使用hbase和mapreduce的最佳实践的任何建议吗?我也有兴趣知道我的数据库架构是否有任何改进可以缓解这个问题。
谢谢,
添
答案 0 :(得分:2)
使用Map / Reduce范例,你的问题不是很顺利。我已经看到许多M / R链接在一起解决了最短路径问题。这不是那么有效,但需要在减速器级别获得全局视图。
在您的情况下,您似乎可以通过跟踪边缘并保留已显示节点的列表来执行映射器中的所有请求。
但是,从地图工作中执行IO会让我感到不安
你不应该担心。您的数据模型绝对是随机的,尝试执行数据局部性将非常困难,因此您没有太多选择,只能通过网络查询所有这些数据。 HBase旨在处理大型并行查询。对不相交的数据进行多次映射查询将产生一个良好的请求分布和高吞吐量。
确保在HBase表中保持较小的块大小以优化读取,并尽可能少地为您的区域提供HFile。我假设你的数据在这里是非常静态的,所以做一个主要的压缩会将HFile合并在一起并减少要读取的文件数。