加盐时添加 RegionServers
Adding RegionServers when salting
我了解了加盐以及如何在顺序键的情况下将其用于负载平衡。基本上,salt 应该将顺序行分发到不同的区域服务器。
我还阅读了这个 article,它解释了如何 运行 对已加盐的表进行 MR 作业。
因此,它建议生成盐为:
StringUtils.leftPad(Integer.toString(Math.abs(keyCore.hashCode() % numberOfRegions)), 3, "0") + "|" + logicalKey
所以你基本上采用原始密钥的散列并进行模除法以获得盐。
您还需要指定基于盐的预拆分,以便每个区域包含具有相同盐的行。
这一切似乎都合情合理。我的问题是,添加更多区域服务器时会发生什么情况?
预计您还会增加区域数量,因此您必须更改拆分策略,以便新区域遵循 "one-salt-for-all-rows-in-region" 规则。您还需要通过增加的 numberOfRegions 执行模除法。
所有这些意味着当我试图获取在区域数量较少时添加的行时,我可能会弄乱 查询。例如,一开始您可以除以模 10(10 个区域),然后您将除以模 50(现在,50 个区域)。
任何人都可以正确解释这个 salting/pre-splitting 的完整过程吗?
Salt 用于避免单个区域的热点。在您的情况下, numberOfRegions
被视为涉及使用顺序键进行批量写入的区域数量。此数字不必与集群中的区域总数一致。例如,如果 10 个区域可以处理您的写入量,您应该在公式中使用 numberOfRegions
等于 10,或者 20 以防将来您建议将写入量加倍。而且您不需要对区域中的所有行都遵循一种盐的规则。您需要找到足以处理您的写入量的区域数量。
此外,现在您不需要像博客 post 中提到的那样编写自定义输入 table 格式。您可以为单个 map reduce 作业指定多个扫描。在这种情况下,数据局部性将自动处理。每次扫描都会产生几个输入分割,每个区域对应一次扫描中的数据。请参阅下面的示例
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);
我了解了加盐以及如何在顺序键的情况下将其用于负载平衡。基本上,salt 应该将顺序行分发到不同的区域服务器。
我还阅读了这个 article,它解释了如何 运行 对已加盐的表进行 MR 作业。
因此,它建议生成盐为:
StringUtils.leftPad(Integer.toString(Math.abs(keyCore.hashCode() % numberOfRegions)), 3, "0") + "|" + logicalKey
所以你基本上采用原始密钥的散列并进行模除法以获得盐。
您还需要指定基于盐的预拆分,以便每个区域包含具有相同盐的行。
这一切似乎都合情合理。我的问题是,添加更多区域服务器时会发生什么情况?
预计您还会增加区域数量,因此您必须更改拆分策略,以便新区域遵循 "one-salt-for-all-rows-in-region" 规则。您还需要通过增加的 numberOfRegions 执行模除法。
所有这些意味着当我试图获取在区域数量较少时添加的行时,我可能会弄乱 查询。例如,一开始您可以除以模 10(10 个区域),然后您将除以模 50(现在,50 个区域)。
任何人都可以正确解释这个 salting/pre-splitting 的完整过程吗?
Salt 用于避免单个区域的热点。在您的情况下, numberOfRegions
被视为涉及使用顺序键进行批量写入的区域数量。此数字不必与集群中的区域总数一致。例如,如果 10 个区域可以处理您的写入量,您应该在公式中使用 numberOfRegions
等于 10,或者 20 以防将来您建议将写入量加倍。而且您不需要对区域中的所有行都遵循一种盐的规则。您需要找到足以处理您的写入量的区域数量。
此外,现在您不需要像博客 post 中提到的那样编写自定义输入 table 格式。您可以为单个 map reduce 作业指定多个扫描。在这种情况下,数据局部性将自动处理。每次扫描都会产生几个输入分割,每个区域对应一次扫描中的数据。请参阅下面的示例
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);