加盐时添加 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);