我在使用Scala的Spark 2.3.0时遇到一些奇怪的行为,我需要一些建议。
我有一个DataFrame,我们称之为elemsDF
,它看起来像这样:
+--------------------+--------------------+--------+----------+-----------+------------------+------+
| ref_el_id| ref_id|time_rel|signalname|signalvalue|standard_deviation|p_date|
+--------------------+--------------------+--------+----------+-----------+------------------+------+
|897cc061-3d02-422...|b6ddddeb-ea26-485...| 0.1| s1| 1.0| 0.0|201611|
|aecb9ee1-5a7b-4d5...|b6ddddeb-ea26-485...| 0.0| s1| 0.0| 0.0|201611|
|36e51ce6-f19d-4ff...|f66d637a-5af1-4eb...| 0.1| s1| 1.0| 0.0|201611|
|2fec8f90-f033-431...|f66d637a-5af1-4eb...| 0.0| s1| 0.0| 0.0|201611|
+--------------------+--------------------+--------+----------+-----------+------------------+------+
列ref_el_id
和ref_id
是由UserDefinedFunction
在某些时候创建的随机生成的UUID。
import java.util.UUID
def genUuidUdf: UserDefinedFunction = udf(() => UUID.randomUUID().toString)
现在很正常,每次我显示elemsDF
时,都会重新计算UUID。
elemsDF.show()
+--------------------+--------------------+--------+----------+-----------+------------------+------+
| ref_el_id| ref_id|time_rel|signalname|signalvalue|standard_deviation|p_date|
+--------------------+--------------------+--------+----------+-----------+------------------+------+
|897cc061-3d02-422...|b6ddddeb-ea26-485...| 0.1| s1| 1.0| 0.0|201611|
|aecb9ee1-5a7b-4d5...|b6ddddeb-ea26-485...| 0.0| s1| 0.0| 0.0|201611|
|36e51ce6-f19d-4ff...|f66d637a-5af1-4eb...| 0.1| s1| 1.0| 0.0|201611|
|2fec8f90-f033-431...|f66d637a-5af1-4eb...| 0.0| s1| 0.0| 0.0|201611|
+--------------------+--------------------+--------+----------+-----------+------------------+------+
elemsDF.show()
+--------------------+--------------------+--------+----------+-----------+------------------+------+
| ref_el_id| ref_id|time_rel|signalname|signalvalue|standard_deviation|p_date|
+--------------------+--------------------+--------+----------+-----------+------------------+------+
|e1bfd5a9-91fc-422...|364c9a75-3990-427...| 0.1| s1| 1.0| 0.0|201611|
|6bfaa133-ee1e-4e9...|364c9a75-3990-427...| 0.0| s1| 0.0| 0.0|201611|
|6f4fc033-3aa1-4e9...|d3e4f33c-2e3c-423...| 0.1| s1| 1.0| 0.0|201611|
|d70e66a4-da5d-49c...|d3e4f33c-2e3c-423...| 0.0| s1| 0.0| 0.0|201611|
+--------------------+--------------------+--------+----------+-----------+------------------+------+
到目前为止,我们坚持使用DataFrame并修复了为UUID计算的值。
elemsDF.persist()
由于persist()
是惰性操作,因此需要执行一项操作才能将其激活。再次运行show()
可完成此操作。
elemsDF.show()
+--------------------+--------------------+--------+----------+-----------+------------------+------+
| ref_el_id| ref_id|time_rel|signalname|signalvalue|standard_deviation|p_date|
+--------------------+--------------------+--------+----------+-----------+------------------+------+
|4a23d926-9bfa-484...|0d67060b-8a76-492...| 0.1| s1| 1.0| 0.0|201611|
|b1536569-917b-44b...|0d67060b-8a76-492...| 0.0| s1| 0.0| 0.0|201611|
|325d8e49-c6e6-4b0...|bc575378-0216-46c...| 0.1| s1| 1.0| 0.0|201611|
|bbcc9c19-95e0-45c...|bc575378-0216-46c...| 0.0| s1| 0.0| 0.0|201611|
+--------------------+--------------------+--------+----------+-----------+------------------+------+
elemsDF.show()
+--------------------+--------------------+--------+----------+-----------+------------------+------+
| ref_el_id| ref_id|time_rel|signalname|signalvalue|standard_deviation|p_date|
+--------------------+--------------------+--------+----------+-----------+------------------+------+
|4a23d926-9bfa-484...|0d67060b-8a76-492...| 0.1| s1| 1.0| 0.0|201611|
|b1536569-917b-44b...|0d67060b-8a76-492...| 0.0| s1| 0.0| 0.0|201611|
|325d8e49-c6e6-4b0...|bc575378-0216-46c...| 0.1| s1| 1.0| 0.0|201611|
|bbcc9c19-95e0-45c...|bc575378-0216-46c...| 0.0| s1| 0.0| 0.0|201611|
+--------------------+--------------------+--------+----------+-----------+------------------+------+
所以这很有意义。现在,这些值是固定的,不会一遍又一遍地重新计算。
现在奇怪的行为;我尝试使用groupBy
和聚合函数,但是,即使在持久保存DataFrame之后,这样做似乎也会在内部强制重新计算。
elemsDF.groupBy("ref_id").agg(count("signalname")).show
+--------------------+---------+
| ref_id|n_signals|
+--------------------+---------+
|d8ec0aa2-8097-40a...| 2|
|e4071400-8298-410...| 2|
+--------------------+---------+
elemsDF.groupBy("ref_id").agg(count("signalname")).show
+--------------------+-----------------+
| ref_id|count(signalname)|
+--------------------+-----------------+
|cc206b29-c9ad-49d...| 2|
|454019c4-80ec-449...| 2|
+--------------------+-----------------+
有人可以向我解释这里发生了什么,我应该怎么做才能避免这种行为?
编辑:谢谢@ user10938362,但是链接的问题是关于没有在UDF创建的新列中获得期望的随机值,并且genUuidUdf.asNonDeterministic
没什么区别。每次show
都没有persist
时,仍然会产生不同的UUID,即使持久保存groupBy
之后,仍然会强制重新计算并生成新的随机值。
编辑:我的问题被标记为重复,尽管不是建议问题的重复,但它是另一个question的重复。
TL; DR是:不要编写不确定的UDF。