spark源码阅读准备:使用 idea remote debug + sbt debug spark源码单元测试

背景

阅读spark源码时,从spark的单元测试入手是一个非常好的选择,spark的单元测试覆盖了非常多的场景,从单元测试入手非常有助于我们理解spark原理。
如:BroadcastSuite中的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
encryptionTest("Cache broadcast to disk") { conf =>
conf.setMaster("local")
.setAppName("test")
.set(config.MEMORY_STORAGE_FRACTION, 0.0)
sc = new SparkContext(conf)
val list = List[Int](1, 2, 3, 4)
val broadcast = sc.broadcast(list)
assert(broadcast.value.sum === 10)
}

test("One broadcast value instance per executor") {
val conf = new SparkConf()
.setMaster("local[4]")
.setAppName("test")

sc = new SparkContext(conf)
val list = List[Int](1, 2, 3, 4)
val broadcast = sc.broadcast(list)
val instances = sc.parallelize(1 to 10)
.map(x => System.identityHashCode(broadcast.value))
.collect()
.toSet

assert(instances.size === 1)
}

非常简单易懂,从字面意思我们就能理解这个单元测试是做什么的,那么如何debug呢?这就开启我们的debug之旅。

基本原理

采用java jdwp(Java Debug Wire Protocol) 实现,也就是远程debug,它定义了调试器(debugger)和被调试的 Java 虚拟机(target vm)之间的通信协议。

想要具体了解,可以参考此篇 使用jdwp远程debug java代码

我们采用idea作为服务器listner,spark sbt单元测试作为客户端的方式进行debug。

具体操作

idea remote debug listner开启

1、点击run下的edit configuration

2、配置remote debug,具体如下图所示
端口这些一般使用默认的就好

3、点击debug按钮,启动remote debug listner

SBT 操作

基于sbt,我们可以运行spark的单元测试,在运行我们设置好jvm参数即可链接上idea的remote debug listner,下面以运行spark core项目下的BroadcastSuite下的 test("Using TorrentBroadcast locally") 为例

1、进入spark目录
2、运行./build/sbt ,启动spark自带的sbt server


此时,sbt server启动完毕,可以看到我们在spark-parent总的项目下

3、输入 project core ,切换到spark core 子module下

4、输入

1
set javaOptions in Test += "-agentlib:jdwp=transport=dt_socket,server=n,suspend=y,address=localhost:5005"

表示运行单元测试时,启动jvm代理,连接到本地5005端口,也就是上文idea启动的监听端口

5、运行单元测试

1
2
testOnly *BroadcastSuite -- -z "Using TorrentBroadcast locally"

其中,-z 后面的参数为scala test后面跟的字段

运行结果如下图所示:

可以看到,单元测试运行到broadcastSuit时被阻塞,这是因为我们在idea断debug了。


可以看到,idea的spark源码已经顺利进入断点模式,可以愉快的debug spark源码了,祝大家阅读源码愉快。

参考资料

基于spark源码做单元测试