如何在Spark中调试ClassCastException错误?

时间:2017-08-14 16:23:11

标签: java apache-spark elasticsearch casting pyspark

当我尝试在pyspark中通过elasticsearch-spark连接器5.1.2从spark 2.1.1到elasticsearch 2.4进行简单读取时(ES_READ_FIELD_EXCLUDE和ES_READ_FIELD_AS_ARRAY_INCLUDE是环境变量,其余的是作为参数传递给我的读数的变量功能或包含在自我对象中):

df = spark.read.format("org.elasticsearch.spark.sql") \
            .option("es.net.proxy.http.host", self.server) \
            .option("es.net.proxy.http.port", self.port) \
            .option("es.net.http.auth.user", self.username) \
            .option("es.net.http.auth.pass", self.password) \
            .option("es.net.proxy.http.user", self.username) \
            .option("es.net.proxy.http.pass", self.password) \
            .option("query", qparam) \
            .option("pushdown", "true") \
            .option("es.read.field.exclude",ES_READ_FIELD_EXCLUDE) \
            .option("es.read.field.as.array.include",ES_READ_FIELD_AS_ARRAY_INCLUDE) \
            .load(self.index) \
            .limit(limit) \
            .select(*fields) \
            .withColumn("id", monotonically_increasing_id())

我收到此ClassCastException错误(从Double到Long):

WARN scheduler.TaskSetManager: Lost task 42.0 in stage ...: java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.Long
at scala.runtime.BoxesRunTime.unboxToLong(BoxesRunTime.java:105) ...

奇怪的是,它有时会起作用,有时却不起作用。我怀疑读取具有NULL值的数据或没有某些字段内容的数据会导致问题,但这只是一个假设,我可能错了。

有没有办法更好地追踪错误,我不知道在哪里看。

1 个答案:

答案 0 :(得分:2)

我发现了我的问题。首先,我使用了最新的dev build for spark elasticsearch连接器(6.0.0-beta1),希望它可以解决问题。事实并非如此,但这次错误信息更具信息性:

org.elasticsearch.hadoop.EsHadoopIllegalArgumentException:
Incompatible types found in multi-mapping: 
Field [my_problematic_field] has conflicting types of [LONG] and [DOUBLE].

现在我理解了从一开始就得到的长到两倍的强制类异常。它与我的字段有关,它在一个索引中定义为long,在另一个索引中定义为double(我在ES中使用一个索引别名指向一系列索引)。问题是这些字段在第一次插入各自的索引时由ES动态映射,有些字段被铸造的时间很长(因为第一个值是例如123)而其他字段被转换为double(因为第一个值是例如123.0)。

我不知道是否有办法解决这个问题,而无需重新索引我的所有数据(数十亿!)