如何在Scala Spark中访问类型签名以进行debuging

时间:2017-04-24 01:11:12

标签: scala apache-spark

当从spark-shell运行spark时,当创建的每个已定义变量时,shell会打印出该变量的类型签名以及实例的toString。

如何在不使用shell(用于调试日志或stdout / stderr)的情况下以编程方式生成相同的签名来自spark脚本或类?

示例代码在spark shell中运行(参见下面的粗体输出)

val data = Array("one", "two", "three", "two", "three", "three")
val dataRdd = sc.parallelize(data)
val dataTupleRdd =  dataRdd.map(word => (word, 1))
val countsRdd = dataTupleRdd.reduceByKey(_ + _)
countsRdd.foreach(println)

代码在spark shell中运行(参见下面的输出:我想从api生成): 我想要生成的示例类型信息(在日志或输出中):
数组[字符串]
org.apache.spark.rdd.RDD [字符串]
org.apache.spark.rdd.RDD [(String,Int)]

Welcome to
      ____              __
     / __/__  ___ _____/ /__
    _\ \/ _ \/ _ `/ __/  '_/
   /___/ .__/\_,_/_/ /_/\_\   version 2.1.0
      /_/

Using Scala version 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_45)
Type in expressions to have them evaluated.
Type :help for more information.

scala> val data = Array("one", "two", "three", "two", "three", "three")
data: Array[String] = Array(one, two, three, two, three, three)

scala> val dataRdd = sc.parallelize(data)
dataRdd: org.apache.spark.rdd.RDD[String] = ParallelCollectionRDD[0] at parallelize at <console>:26

scala> val dataTupleRdd =  dataRdd.map(word => (word, 1))
dataTupleRdd: org.apache.spark.rdd.RDD[(String, Int)] = MapPartitionsRDD[1] at map at <console>:28

scala> val countsRdd = dataTupleRdd.reduceByKey(_ + _)
countsRdd: org.apache.spark.rdd.RDD[(String, Int)] = ShuffledRDD[2] at reduceByKey at <console>:30

scala> countsRdd.foreach(println)
(two,2)
(one,1)
(three,3)

3 个答案:

答案 0 :(得分:1)

你的问题很难理解,因为它意味着你需要等到运行时才能看到你拥有的东西。在像Scala这样的静态类型语言中,情况并非如此。您可以自己显式键入值(必要时使用IDE)并准确查看编译时的内容。

因此,如果您只关心类型,那么Scala语言(以及帮助您推理事情的IDE)可以满足您的需求。但是,RDD还提供了toDebugString方法,该方法描述了RDD及其依赖关系。这对于调试非常有用 - 特别是在识别您正在处理的RDD的特定类型时。但它并没有告诉你所包含的类型,因为你已经知道了。

答案 1 :(得分:0)

您可以使用此getClass.getSimpleName获取日志记录的可读名称,例如:

val data = Array("one", "two", "three", "two", "three", "three")
print(data.getClass.getSimpleName)     // Output: String[]

另外,如果您使用的是intelliJ,则可以使用命令+ P来检查变量的类型。

答案 2 :(得分:0)

虽然其他答案是正确的,但通常不需要这样做,你可以这样做:

auto get_functor = [&](bool const check) -> std::function<std::string(foo const&)> {
    return [=](foo const&) -> std::string {
        if (check) {
            return "some string";
        } else {
            return "another string";
        }
    };
};
std::cout << run(get_functor(true));

按名称参数(import scala.reflect.runtime.universe._ def typeName[A](x: => A)(implicit tag: WeakTypeTag[A]) = tag.toString )确保可以安全地调用它,例如=> A上没有实际评估foo(x, bar(y))bar,或者是懒惰值。有关foo s。

的详情,请参阅http://docs.scala-lang.org/overviews/reflection/typetags-manifests.html