Hadoop 如何在HBase中存储数据,以便通过部分密钥扫描进行高效抓取?

Hadoop 如何在HBase中存储数据,以便通过部分密钥扫描进行高效抓取?,hadoop,optimization,hbase,database-scan,Hadoop,Optimization,Hbase,Database Scan,我的钥匙有三个组成部分: num、type、name “类型”只有两种类型A和B 而num可以有更多的值,例如0,1,2..30 我必须获取有关num和type的数据,即获取具有指定num和type的键的所有行 我可以以以下形式存储数据: 1. 编号|类型|名称 或 2. 类型| num |名称 如果我使用部分键扫描,考虑HBase如何扫描数据,哪种是存储数据的最佳策略 以下是我将如何设置部分密钥扫描: 1 两个人 scan.setStartRow(Bytes.toBytes(type + "|

我的钥匙有三个组成部分: num、type、name

“类型”只有两种类型A和B 而num可以有更多的值,例如0,1,2..30

我必须获取有关num和type的数据,即获取具有指定num和type的键的所有行

我可以以以下形式存储数据: 1. <代码>编号|类型|名称 或 2. <代码>类型| num |名称

如果我使用部分键扫描,考虑HBase如何扫描数据,哪种是存储数据的最佳策略

以下是我将如何设置部分密钥扫描: 1

两个人

scan.setStartRow(Bytes.toBytes(type + "|" + num);
scan.setStopRow(Bytes.toBytes(type + "|" + (num+1));

首先,我建议不要使用pipe作为分隔符——这是ASCII 124,落在所有字母和数字之后,排序将不是您所期望的(除非您将所有内容都放在pad上——但这会导致键过大)。对于HBase行键分隔符,您希望使用在所有有效键字符之前按字典顺序排列的内容来保留正确的排序。Tab在ascii9下运行良好

考虑到该类型只有两个有效值,并假设为随机分布,我将使用
num type
。如果将来需要,这允许您选择just on num。以相反的顺序选择just num,
type num
,是两次获取,一次用于类型“A”,另一次用于类型“B”。不是最有效的

如果您将很少只选择数字,那么选择
类型num
是有意义的,因为这是行级别上最具选择性的,如果不灵活的话


实际上,您应该同时尝试这两种方法,看看哪些方法最适合您的数据。

您可以采取以下几种方法

1) 你应该选择哪个布局,你将更频繁地扫描。然后,对于不太频繁的扫描类型,进行完全扫描(或者如果可以的话,将其限定为范围),并使用过滤器,可以构造一个行过滤器,过滤掉除所需项目以外的任何内容。 关于过滤器:

2) 您可以通过存储数据两次(每个行名存储一次)来复制数据。这会减慢写入速度,但如果同时扫描这两种数据,会对读取有很大帮助。当然,磁盘使用率也翻了一番

3) 您可以使用替代行名称构造索引,以指向相关行


您采取什么方法在很大程度上取决于数据的访问模式和读/写比率

谢谢你的详细答复。几个问题:分隔符对于所有行都是相同的,因此我不确定是否正确理解它将如何影响排序顺序。我想会影响数据大小吗?如果我们决定扫描w.r.t.num,例如特定的num'2'。如果数据被持久化为num |类型。可能的情况是,所有的2都将在一个文件中。在这种情况下,它会降低并行性吗?相反,如果它被持久化为| num类型,那么所有A | 2都在一个文件中,所有B | 2都在另一个文件中。在扫描2时,这会增加并行度吗?我应该备份一点分隔符-如果您不关心整体排序,只想将数据分组在一起,那么使用任何分隔符都可以。如果您关心它是如何排序的,那么您在选择时需要小心。使用num | type作为顺序,很有可能num为“2”的两行都位于同一区域/节点中。使用良好的扫描仪-扫描仪一次只能在一个区域上操作。如果您更担心来自不同客户的并行读取器,那么您可能需要更多的分发,并且具有类型线索可能会更好。
scan.setStartRow(Bytes.toBytes(type + "|" + num);
scan.setStopRow(Bytes.toBytes(type + "|" + (num+1));