我读到了关于salting以及如何在顺序键的情况下将其用于负载平衡。基本上,salt应该将顺序行分发到不同的区域服务器。
我还阅读了这个article,它解释了如何在被腌制的桌子上运行MR作业。
因此,它建议生成盐:
.text()
所以你基本上采用原始密钥的哈希值并进行模数除法以得到盐。
您还需要根据salt指定预分割,以便每个区域包含具有相同salt的行。
所有这一切似乎都是合理的。我的问题是,添加更多区域服务器时会发生什么??
预计您还会增加区域数量,因此您必须更改拆分策略,以便新区域遵循“区域中的一个盐 - 所有区域”规则。您还需要通过增加numberOfRegions来执行模数除法。
所有这些意味着当我尝试获取在区域数量较少时添加的行时,我可以搞乱查询。例如,在开始时你可以除以模10(10个区域),然后你将除以模50(现在,50个区域)。
任何人都可以正确解释这种盐渍/预分裂的完整程序吗?
答案 0 :(得分:1)
盐用于避免单个区域的热点。在您的情况下,numberOfRegions
被视为使用顺序键进行批量写入所涉及的区域数。此数字不必与群集中的区域总数一致。例如,如果10个区域可以处理您的写入量,则应在公式中使用numberOfRegions
等于10,或者如果将来建议将写入次数加倍,则应使用20。并且您不需要遵循该规则中的所有行的规则。您需要找到足以处理写入数量的区域数量。
此外,现在您不需要像您提到的博客文章那样编写自定义输入表格式。您可以为单个地图缩小作业指定多个扫描。在这种情况下,将自动处理数据位置。每次扫描都会产生几个输入分割,每个区域对应一次扫描数据。参见下面的示例
List<Scan> scans = new ArrayList<>();
for(int i = 0; i < numberOfRegions; i++){
Scan scan = new Scan();
scan.setBatch(500);
scan.setAttribute(Scan.SCAN_ATTRIBUTES_TABLE_NAME, YOUR_TABLE_NAME);
String regionSalt = StringUtils.leftPad(Integer.toString(i), 3, "0");
scan.setStartRow( Bytes.toBytes(regionSalt + "|" + scanStart));
scan.setStartRow( Bytes.toBytes(regionSalt + "|" + scanStop);
scans.add(scan);
}
TableMapReduceUtil.initTableMapperJob(
scans,
YourMapper.class,
Text.class,
Text.class,
job);