一个KCore算法引发的StackOverflow奇案

文章讲述了在Spark集群上运行KCore算法时遇到的StackOverflow问题,从本地测试正常到集群运行出错,经过一系列调试,发现错误根源在于RDD的f函数闭包和VertexRDD的non-transient成员变量,导致Task序列化链增长引发StackOverflow。通过细致的Debug最终解决了问题。

本文只概述一下此案,不做技术上的深究:

        这是一次扑朔迷离的Spark StackOverflow侦破过程,这也是程序员悲情debug的故事。故事起源于一个图算法:KCore算法。该算法的特点决定了需要迭代很多轮才能收敛。在亿级别的数据上,迭代个几百次是家常便饭。当我们翘首期盼迭代收敛结果时,它却引发了一综StackOverflow的奇案。

        一开始,该算法在本地小数集上测试通过,没有任何问题,但放到集群上运行后,总是出现StackOverflow的错误。起初,我们认为错误原因不过是典型的RDD的lineage过长,也就是lineage的长度随着算法迭代次数增加而不断变长,最后导致Spark在序列化该lineage的时候调用栈溢出。于是,我们随手拎起checkpoint的宝刀,每迭代几轮就checkpoint一下,以为可以轻而易举地截断lineage,从而解决这个问题。可是当checkpoint加入后,错误仍然出现。迫不得已,我们进行了小米加步枪式的Debug。

        在Debug过程中,StackOverflow这种类型的错误,展现了比OutOfMemory更难驯服的个性,尤其是在大规模的分布式集群上。这逼迫我们设法把案发现场转移到单机环境,并通过非常Geek的方式,模拟出算法在分布式环境下的出错情景,重现案发现场,终于追溯到了问题的根源所在:RDD异常的 f 函数闭包和VertexRDD中non-transient成员变量。这两个Bug导致Task的序列化链,可以偷偷穿越被断掉的lineage不断延续,也就是Task的序列化链随着迭代次数的增加而不断增长,最终造成了StackOverflow错误。

        整个断案过程耗时一周,可谓扑朔迷离,柳暗花明又一村,最终水落石出,基本圆满地解决了这个案件。

       


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值