当 HBase 达到 hbase.hregion.max.filesize 时,HBase 通常会在中间点将一个区域拆分为 2(取决于拆分策略)。您可以依赖自动拆分,但由于行键的性质(大量“com”域与少数“org”域),您将以奇数和词法不均匀的拆分点结束。
这可能不是您的确切情况,但请考虑一下这个潜在问题:
- 从只有 1 个区域的空表开始,您可以从 com. . 并以 org 结尾。.
- 在 8000 万标记处(虚构的 com.nnnn.www),区域在“com.f*”处自动拆分为 2,产生 24000 万区域,并继续将行写入区域 2
- 在 1.2 亿标记处(虚构的 com.yyyy.www),第二个区域达到最大文件大小并在“com.p*”处拆分为 2 4000 万个区域,并继续将行写入区域 3。
- 作业以 150M 域结束,不再执行拆分。
在这种情况下,区域 1 和 2 将分别存储 40M 行,但区域 3 将存储 65M 行(它将被拆分为 80M,但可能永远不会达到这个数量)。此外,由于您将始终写入最后一个区域(即使启用了批处理),该作业将比同时向多个区域发出批量写入要慢得多。
另一个问题,假设您意识到您还需要添加 .us 域 (10M)。鉴于这种设计,他们将前往区域 3,将托管的行数增加到 75M。
确保在区域之间均匀分布键的常用方法是在行键前添加键的 md5 的几个字符(在本例中为域名)。在 HBase 中,行键的第一个字节决定了将托管它的区域。
只需在 md5 前面添加几个字符就足以防止尽可能多的热点(一个区域获得过多写入)并获得良好的自动拆分,但通常建议预先拆分表以确保更好的拆分。
如果您将 md5 的 2 个字符添加到行键中,您可以使用 15 个拆分点预先拆分表格:“10”、“20”、“30”......直到“e0”。这将创建 16 个区域,如果其中任何一个需要自动拆分,它将在它们的中间点完成。即:当从“a0”开始并以“af”结束的区域达到 hbase.hregion.max.filesize 时,它将被拆分为“a8”左右,每个区域将存储“a”桶的一半。
这是一个示例,如果您有 16 个带有 2 个字符前缀行键的预分割区域,则哪些区域将托管每一行:
- Region 1 ---------
0b|com.example4.www
- Region 2 ---------
1b|org.example.www
10|com.example.www
- Region 5 ---------
56|com.example3.www
- Region 10 ---------
96|org.example5.www
- Region 11 ---------
af|com.example5.www
- Region 14 ---------
d5|org.example3.www
db|com.example2.www
de|org.example2.www
- Region 16 ---------
fb|org.example4.www
给定更多的域,它将最终变得更加均匀,并且几乎所有区域都将存储相同数量的域。
在大多数情况下,拥有 8-16 个预分割区域就足够了,但如果没有,您可以选择 32 甚至 64 个预分割区域,直到最多 256 个(即具有“01”,“ 02", "03" ... "9f", "a0", "a1" ... 直到 "fe")