【问题标题】:Adding RegionServers when salting加盐时添加 RegionServers
【发布时间】:2015-12-18 09:47:48
【问题描述】:

我阅读了有关加盐以及在顺序键的情况下如何将其用于负载平衡的信息。基本上,salt 应该将连续的行分配给不同的区域服务器。

我还阅读了这个article,它解释了如何在加盐的表上运行 MR 作业。

因此,建议生成盐为:

StringUtils.leftPad(Integer.toString(Math.abs(keyCore.hashCode() % numberOfRegions)), 3, "0") + "|" + logicalKey

所以你基本上取原始密钥的哈希并进行模除以获得盐。

您还需要指定基于盐的预分割,以便每个区域都包含具有相同盐的行。

所有这些似乎都是合理的。我的问题是,当您添加更多区域服务器时会发生什么

预计您还会增加区域数量,因此您必须更改拆分策略,以便新区域遵循“区域内的所有行一个盐”规则。您还需要通过增加的 numberOfRegions 执行模除法。

所有这一切意味着当我尝试获取在区域数量较少时添加的行时,我可能会搞砸查询。例如,一开始您可以除以模 10(10 个区域),然后您将除以模 50(现在是 50 个区域)。

谁能解释一下这个加盐/预分裂的完整过程吗?

【问题讨论】:

    标签: hadoop hbase


    【解决方案1】:

    盐用于避免单个区域的热点。在您的情况下,numberOfRegions 被视为使用顺序键进行批量写入所涉及的区域数。此数字不必与集群中的区域总数一致。例如,如果 10 个区域可以处理您的写入量,则您应该在公式中使用等于 10 的numberOfRegions,或者如果将来您建议将写入次数加倍,则使用 20。而且您不需要为该区域的所有行遵循规则一盐。您需要找到足以处理写入量的区域数量。

    此外,现在您不需要像您提到的博客文章中那样编写自定义输入表格式。您可以为单个 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);
    

    【讨论】:

    • 感谢您的回答,我明白除了一部分之外的所有内容 - “并且您不需要为该区域的所有行遵循规则一盐”。如果您查看我引用的文章,您将了解区域中的行应该具有相同盐的原因。这样做的原因是能够通过指定 STARTROW 和 ENDROW 进行扫描,同时使用记录作为 MR 作业的输入。如果我错了,请纠正我,但我认为有必要吗?还有一个问题,如何知道哪些区域数量足以处理写入?
    • 如果您将通过指定 STARTROW 和 ENDROW 来使用 SCAN,它将起作用,这取决于 STARTROW 和 ENDROW 是否属于同一区域。至于您需要多少个区域来为您的写入提供服务,这取决于许多因素,例如您的记录大小、集群配置和网络、硬件。该区域每秒可以处理几千到几万个写入请求的典型值。
    • 但是,如果键是:1-timestamp1、2-timestamp2、3-timestamp3、1-timestamp4,并且您想获取 ts1 和 ts4 之间的所有行,您将如何指定 STARTROW 和 ENDROW?您还必须在 START、END 中包含盐值,并且您只能为此指定一个值。每个区域一个盐的想法是启用数据局部性 - Hadoop的每个TaskTracker将只处理其节点上的数据,因此它需要修改START,END以便在开始时包含适当的solt。 blog.cloudera.com/blog/2015/06/…
    • 我在这种情况下添加了一个设置 mapreduce 作业的示例。
    • 是的,过滤列表将在这种情况下工作。一般来说,适用于单次扫描的方法也适用于多次扫描。
    猜你喜欢
    • 2011-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-18
    • 2021-09-27
    • 2014-05-03
    • 2010-11-30
    • 2021-11-12
    相关资源
    最近更新 更多