如何异步处理pyspark数据帧分区

时间:2020-05-08 20:22:08

标签: apache-spark pyspark pyspark-dataframes

我最近开始玩pyspark,因为我必须处理大量数据。目前,我要做的任务是通过调用我们正在运行的http服务来获得一些价值。我的数据存储在pyspark数据框中,如下所示:

+--------------------+----------+
|                name|        id|
+--------------------+----------+
|xxxxxxxxxxxxxxxxx...|         1|
|yyyyyyyyyyyyyyyyy...|         2|
+--------------------+----------+

我正在使用udf在id列上调用该服务,并获取一个新值(new_id)并将其添加到现有数据框中。网络延迟不是问题,因为所有设备都在同一个VPN中。我的代码如下所示:

def update_df(df):
    udf_get_new_id = udf(get_new_id, ArrayType(StringType()))

    df = df.withColumn('new_id', udf_get_new_id(df.id)[0])
    # My request might fail so I want to log the status code of the request as well
    updated_df = df.withColumn('status_code', udf_get_new_id(df.id)[1])
    return updated_df

def get_new_id(id)
    url = SOME_HTTP_URL
    headers = {'content-type': 'application/json',
               'Connection': 'keep-alive',
               'Content - Length': '125',
               'cache - control': 'no - cache',
               'keep-alive': 'timeout = 5, max = 1000'
               }
    body = {'id': id}
    response_string = requests.post(url, data = json.dumps(body), headers = headers)
    status_code = response_string.status_code
    response_content = ast.literal_eval(response_string.content.decode())
    new_id = response_content['new_id']
    return [new_id, status_code]

我将这些函数称为:

updated_df = update_df(df)

start_time = timer()
updated_df.repartition(100).collect()
end_time = timer()
print(end_time - start_time)

更新后的数据应如下所示:

+--------------------+----------+----------+-----------+
|                name|        id|    new_id|status_code|
+--------------------+----------+----------+-----------+
|xxxxxxxxxxxxxxxxx...|         1|        XX|        200|
|yyyyyyyyyyyyyyyyy...|         2|        YY|        200|
+--------------------+----------+----------+-----------+

在这种情况下,我要调用的服务每秒可以处理数百万个请求,而我想尽可能地利用它,我想知道是否有方法可以优化当前代码。如果您有兴趣,这是我可以设法获得的最大处理能力(我用来运行代码的spark-submit命令):

/opt/spark-2.4.4-bin-without-hadoop/bin/spark-submit --conf spark.app.name=test_app --master yarn --deploy-mode client --num-executors 4 --executor-cores 4 --executor-memory 2G --driver-cores 4 --driver-memory 2G

我从我的一个朋友那里听说,他们将在scala中异步处理分区,并且想知道这是否是我可以用pyspark数据帧做的最好的事情,或者有什么方法可以优化它?任何反馈都非常感谢。

0 个答案:

没有答案