知识卡片
fieldsGrouping的隐藏陷阱:按字段分组容易因热点数据导致下游处理不均衡
内容
fieldsGrouping是Storm里一种常用的数据分组方式,它根据一个或多个字段对数据进行分组,保证同一个字段值对应的数据总会被发送到同一个下游Task(不同字段值的数据则被发往不同Task)——这个特性对于需要按某个维度做聚合统计(比如按用户ID统计行为)的场景非常有用,因为它天然保证了”同一个统计对象的数据集中在同一个处理单元里”。但这个分组方式隐含着一个容易被忽视的风险:如果按某个字段(比如用户ID)分组时,不同字段值对应的数据量本身就存在巨大差异(一部分用户的数据特别多、另一部分用户的数据很少),会直接导致下游各个Task收到的数据量严重不均衡——那些恰好承接了”热门用户”数据的Task会承受远超其他Task的处理压力,而整个处理链路的实际性能,会被这些负载最重的热点Task所限制,其他负载轻的Task即使有富余的处理能力,也无法帮上忙,因为fieldsGrouping的分组规则本身决定了数据不会被重新分配。应对这个问题的思路是加入更多的分组条件、或者更换分组策略,让原本集中在少数字段值上的数据能够被进一步打散,从而让下游各个Task之间的负载更趋于均衡。这个案例给出了一条使用”按某个属性做确定性分组”这类机制时的通用警示:这类分组方式的核心承诺是”相同属性值的数据一定落在同一处理单元”,这个承诺本身没有问题,但它完全没有对”不同属性值对应的数据量是否均衡”这件事做任何保证——如果分组所依据的属性本身存在明显的数据倾斜(少数值对应海量数据,多数值只对应少量数据),这种分组方式几乎必然会制造出处理能力上的热点瓶颈,评估要不要用某个字段做分组之前,有必要先审视这个字段在真实数据分布上是不是足够均匀。
参考来源
- 位置:《高可用架构(第1卷)》第6章《大数据与数据库》"6.2 实时计算在点评"节,"6.2.6 Storm使用经验分享"(源文件:_epub-src/OEBPS/Text/Chapter6_2_7.xhtml)
- 结论依据:原文说明"假设某个Bolt根据用户ID对数据进行fieldsGrouping,如果某一些用户的数据特别多,而另外一些用户的数据又比较少,那么就可能使得下一级处理Bolt收到的数据不均衡,整个处理的性能就会受制于某些数据量大的节点。可以加入更多的分组条件或者更换分组策略,使得数据具有均衡性",直接支撑本卡片结论。
- 原始内容:假设某个Bolt根据用户ID对数据进行fieldsGrouping,如果某一些用户的数据特别多,而另外一些用户的数据又比较少,那么就可能使得下一级处理Bolt收到的数据不均衡,整个处理的性能就会受制于某些数据量大的节点。