簡體   English   中英

函數使用rdd.map()映射到RDD的某些行被多次調用

[英]Function mapped to RDD using rdd.map() called multiple times for some rows

我有一個有一些記錄的源數據框。 我想對該數據幀的每一行執行一些操作。 為此,使用了rdd.map函數。 但是,查看使用累加器記錄的日志,看起來某些行多次調用了映射函數。 根據文檔,僅應調用一次。

我嘗試在一個小的腳本中復制問題,並注意到相同的行為。 該腳本如下所示:

import os
import sys
os.environ['SPARK_HOME'] = "/usr/lib/spark/"
sys.path.append("/usr/lib/spark/python/")
from pyspark.sql import *
from pyspark.accumulators import AccumulatorParam


class StringAccumulatorParam(AccumulatorParam):
    def zero(self, initialValue=""):
        return ""

    def addInPlace(self, s1, s2):
        return s1.strip() + " " + s2.strip()

def mapped_func(row, logging_acc):
    logging_acc += "Started map"
    logging_acc += str(row)
    return "test"

if __name__ == "__main__":
    spark_session = SparkSession.builder.enableHiveSupport().appName("rest-api").getOrCreate()
    sc = spark_session.sparkContext
    df = spark_session.sql("select col1, col2, col3, col4, col5, col6 from proj1_db.dw_table where col3='P1'")
    df.show()
    logging_acc = sc.accumulator("", StringAccumulatorParam())
    result_rdd = df.rdd.map(lambda row: Row(row, mapped_func(row, logging_acc)))
    result_rdd.toDF().show()
    print "logs: " + str(logging_acc.value)

以下是相關的輸出:

+----+----+----+----+----+----+
|col1|col2|col3|col4|col5|col6|
+----+----+----+----+----+----+
|   1|   1|  P1|   2|  10|  20|
|   3|   1|  P1|   1|  25|  25|
+----+----+----+----+----+----+

+--------------------+----+
|                  _1|  _2|
+--------------------+----+
|[1, 1, P1, 2, 10,...|test|
|[3, 1, P1, 1, 25,...|test|
+--------------------+----+

logs: Started map Row(col1=1, col2=1, col3=u'P1', col4=2, col5=10, col6=20) Started map Row(col1=1, col2=1, col3=u'P1', col4=2, col5=10, col6=20) Started map Row(col1=3, col2=1, col3=u'P1', col4=1, col5=25, col6=25)

第一個表是源數據幀,第二個表是在映射函數調用之后創建的結果數據幀。 如圖所示,該函數在第一行被調用兩次。 誰能幫助我了解正在發生的事情,以及如何確保映射的函數每行僅調用一次。

根據文檔,僅應調用一次。

事實並非如此。 任何轉換都可以執行任意次(通常在發生故障或支持輔助邏輯的情況下), 文檔明確指出

對於操作內部執行的累加器更新,Spark保證每個任務對累加器的更新將僅應用一次

因此,可以在每個任務中多次更新轉換中使用的隱式累加器(例如map )。

在您的情況下,會發生多次執行,因為將RDD轉換為DataFrame時不提供架構。 在這種情況下,Spark將執行另一次數據掃描以從數據推斷架構,即

spark.createDataFrame(result_rdd, schema)

但是,那只能解決這個特定的問題,並且關於轉換和累加器行為的一般觀點仍然存在。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM