Spark Scala创建具有排序日期值的成对RDD

Spark Scala创建具有排序日期值的成对RDD,scala,sorting,datetime,apache-spark,rdd,Scala,Sorting,Datetime,Apache Spark,Rdd,警告:我对spark和scala是新手。我发现了一些关于堆栈溢出的问题,这些问题与我的问题非常相似,但无法将它们转化为我的问题 上下文。我最初有一对RDD和表单的记录(id,日期),我想创建表单的RDD(id,上次看到的日期)。在原始数据中,日期是一个字符串,我使用Joda将其转换为DateTime 我已经使用combineByKey成功地做到了这一点,我知道groupByKey效率低下,在大的情况下可能不实用,但我正在尝试了解使用调用范围的方法 我要做的是groupByKey,然后mapVal

警告:我对spark和scala是新手。我发现了一些关于堆栈溢出的问题,这些问题与我的问题非常相似,但无法将它们转化为我的问题

上下文。我最初有一对RDD和表单的记录(id,日期),我想创建表单的RDD(id,上次看到的日期)。在原始数据中,日期是一个字符串,我使用Joda将其转换为
DateTime

我已经使用
combineByKey
成功地做到了这一点,我知道
groupByKey
效率低下,在大的情况下可能不实用,但我正在尝试了解使用调用范围的方法

我要做的是
groupByKey
,然后
mapValues
,获取由
groupByKey
生成的值列表,以获得列表中的最大值

我所尝试的:

(我根据不同的堆栈溢出问题创建了DateTime上的排序,因此存在排序。)

我已经尝试了很多方法,大多数方法都给了我一个例外,任务是不可序列化的。一个例子是,

rdd.groupByKey().mapValues(_.toList.sorted.last)
我已经尝试过这方面的多种变体;)如果没有
toList
,我会得到一个异常,它不是
Iterable[org.joda.time.DateTime]
的成员。我成功地使用了
mapValues
并做了一些更简单的事情,但一旦我尝试添加排序,事情就糟了。我尝试了排序并指定排序

深入了解为什么发送到排序方法的内容不可序列化对我总体上是有帮助的。我不知道当我掉进这个陷阱时该如何识别

一个类似的堆栈溢出问题建议不要使用
mapValues
,只需使用
sortBy
并指定它位于第二个元素上,因此
.sortBy(u.\u 2)
。这对我来说也是失败的。理想情况下,如果这样做有意义,我也想知道

这似乎是一件非常简单的事情,而且可能很常见,所以我觉得我错过了一些东西

编辑-添加以获取异常的详细信息。但请注意,我无法重现此错误

错误堆栈中的不可序列化错误表明,我在另一个堆栈溢出中使用的隐式排序是罪魁祸首。请注意,我无法重现这个困扰了我好几个小时的错误(请参阅答案)

Joda模块就在前面定义过

object Joda {
 implicit def dateTimeOrdering: Ordering[DateTime] =  
   Ordering.fromLessThan(_ isBefore _)
}

我最初的问题实际上有两个部分: *如何使用groupBy转换RDD,以便检索每个id的最后一个可见日期,以及 *为什么我尝试的方法会出现“任务不可序列化”错误

不幸的是,在重新启动spark shell并返回我的步骤后,我无法重现此错误。我在问题中列出的代码,加上我已经建立的日期时间顺序,效果很好。我最近遇到了另一个类似的问题,我可以将其追溯到隐式值中的冲突,我之前在shell中为完全不同的目的设置了隐式值。我怀疑这也是罪魁祸首,但无法证实

注释中引用的另一个堆栈溢出问题表明Joda为其他人造成了问题

为了完整性,我可以通过多种方式进行转换并提取最后的日期。最直接的是@zero323在他们使用reduceByKey的评论中给出的

使用groupByKey,问题中的代码

rdd.groupByKey().mapValues(_.toList.sorted.last)
当以下隐式排序到位时,工作正常:

object Joda {
   implicit def dateTimeOrdering: Ordering[DateTime] =  
   Ordering.fromLessThan(_ isBefore _)}
import Joda._
同样地

rdd.groupByKey.mapValues(_.toList.max)
结果相同

我还使用定义的顺序复制了结果,并显式地传递给sorted


不幸的是,我无法确定为什么对象Joda在第一次会话中抛出异常,而在接下来的多次尝试中却没有

我最初的问题实际上有两个部分: *如何使用groupBy转换RDD,以便检索每个id的最后一个可见日期,以及 *为什么我尝试的方法会出现“任务不可序列化”错误

不幸的是,在重新启动spark shell并返回我的步骤后,我无法重现此错误。我在问题中列出的代码,加上我已经建立的日期时间顺序,效果很好。我最近遇到了另一个类似的问题,我可以将其追溯到隐式值中的冲突,我之前在shell中为完全不同的目的设置了隐式值。我怀疑这也是罪魁祸首,但无法证实

注释中引用的另一个堆栈溢出问题表明Joda为其他人造成了问题

为了完整性,我可以通过多种方式进行转换并提取最后的日期。最直接的是@zero323在他们使用reduceByKey的评论中给出的

使用groupByKey,问题中的代码

rdd.groupByKey().mapValues(_.toList.sorted.last)
当以下隐式排序到位时,工作正常:

object Joda {
   implicit def dateTimeOrdering: Ordering[DateTime] =  
   Ordering.fromLessThan(_ isBefore _)}
import Joda._
同样地

rdd.groupByKey.mapValues(_.toList.max)
结果相同

我还使用定义的顺序复制了结果,并显式地传递给sorted


不幸的是,我无法确定为什么对象Joda在第一次会话中抛出异常,而在接下来的多次尝试中却没有

只需
rdd.reduceByKey((x,y)=>if(x.isAfter(y))x else y)
并确保阅读感谢@zero323。另一个更紧凑的combineByKey版本,我没有尝试过。似乎遇到序列化问题在Spark中很常见,因此,尽管我现在为我的小练习找到了多个解决方案,但我想更好地理解为什么要处理toList和排序抛出错误。也许我的问题真的应该重述到导致序列化错误的原因。对于序列化问题,你应该真正检查链接的问题。乔达克拉斯