我有一个非常简单的 Spark 程序(使用 Clojure 中的 Flambo,但应该很容易跟进)。这些都是JVM上的对象。我正在一个 local
实例上测试(尽管我猜想 Spark 仍然进行序列化和反序列化)。
(let [dt (t/date-time 2014)
input (f/parallelize sc [{:the-date dt :x "A"}
{:the-date dt :x "B"}
{:the-date dt :x "C"}
{:the-date dt :x "D"}])
by-date (f/map input (f/fn [{the-date :the-date x :x}] [the-date x])))
输入是一个由四个元组组成的RDD,每个元组都有相同的日期对象。第一个map生成一个键值对RDD,其中键为日期,值为x。
input
的内容如预期所示:
=> (f/foreach input prn)
[#<DateTime 2014-01-01T00:00:00.000Z> "A"]
[#<DateTime 2014-01-01T00:00:00.000Z> "B"]
[#<DateTime 2014-01-01T00:00:00.000Z> "C"]
[#<DateTime 2014-01-01T00:00:00.000Z> "D"]
需要明确的是,相等性和 .hashCode
适用于日期对象:
=> (= dt dt)
true
=> (.hashCode dt)
1260848926
=> (.hashCode dt)
1260848926
他们是JodaTime的DateTime实例,实现了预期的相等性比较。
当我尝试使用
countByKey
时,得到了预期的结果:=> (f/count-by-key by-date)
{#<DateTime 2014-01-01T00:00:00.000Z> 4}
但是当我使用
groupByKey
时,它似乎不起作用。=> (f/foreach (f/group-by-key by-date) prn)
[#<DateTime 2014-01-01T00:00:00.000Z> ["A"]]
[#<DateTime 2014-01-01T00:00:00.000Z> ["B"]]
[#<DateTime 2014-01-01T00:00:00.000Z> ["C"]]
[#<DateTime 2014-01-01T00:00:00.000Z> ["D"]]
所有的键都是相同的,因此我期望结果是一个具有日期为键和值为
["A", "B", "C", "D"]
的单个条目。由于所有的值都是列表,所以发生了一些事情。某种方式上,
groupByKey
没有正确地将键进行比较。但是countByKey
可以做到。这两者之间有什么区别?我该如何使它们行为相同?有任何想法吗?