【Spark】使用break报错:Caused by: scala.util.control.BreakControl
错误信息:Caused by: scala.util.control.BreakControl
处理这个错误,首先先保证 break 与 breakable 配套使用,一般来说配套使用之后就不会报这个错了,比如下面这样:
1 def main(args: Array[String]) { 2 val numList = List(1,2,3,4,5,6,7,8,9,10); 3 val loop = new Breaks; 4 loop.breakable { 5 for( a <- numList){ 6 println( "Value of a: " + a ); 7 if( a == 4 ){ 8 loop.break; 9 } 10 } 11 } 12 println( "After the loop" ); 13 }
假如有内外循环跳出,则需要定义 val outer = new Breaks; val inner = new Breaks; 当做标志替换掉上面代码的loop。如果只是关于break使用的问题,可以看这里:
https://www.runoob.com/scala/scala-break-statement.html
而我在更正使用方法之后,出现了另外一个问题:
错误信息:Caused by: java.io.NotSerializableException: scala.util.control.Breaks
问题出现的原因:当上面涉及到的outer与inner实例需要通过网络传输到Executor中使用,而不是在Driver中使用时,由于Breaks类没有继承序列化接口,所以outer与inner无法被序列化传输到Executor,就像下面的代码一样,会报java.io.NotSerializableException错误:
1 val dfileArray = getFileName(sc) 2 val outer: Breaks = new Breaks 3 val inner: Breaks = new Breaks 4 outer.breakable{ 5 dfileArray.foreach(fileName=>{ 6 val lines: RDD[String] = sc.textFile(fileName) 7 inner.breakable{ 8 lines.foreach(line=>{ 9 if(xxx){ 10 inner.break // break 11 }else if(xxx){ 12 inner.break 13 }else if(xxx){ 14 inner.break 15 }else if(xxx){ 16 inner.break 17 } 18 }) 19 } 20 }) 21 }
解决方法:在lines.foreach之前先进行lines.collect(),collect()算子会将lines变为Array类型,后续代码会在Driver中执行,并不会进行网络数据传输,如下:
val dfileArray = getFileName(sc) val outer: Breaks = new Breaks val inner: Breaks = new Breaks outer.breakable{ dfileArray.foreach(fileName=>{ val lines: RDD[String] = sc.textFile(fileName) inner.breakable{ lines.collect().foreach(line=>{ if(xxx){ inner.break // break }else if(xxx){ inner.break }else if(xxx){ inner.break }else if(xxx){ inner.break } }) } }) }
这里不谈Driver与Executor相关内容。
以上。