Pyspark不会识别作为参数传递给foreach或foreachPartition的方法的env变量

时间:2017-05-10 17:27:51

标签: python apache-spark pyspark redis-py

在下面的代码中,我尝试实例化redis-py 在URL使用env变量的连接。问题是,当我使用foreach or foreachPartition时,env变量在#save_on_redis方法中无法识别。

我只是尝试在外面创建redis连接,但是我收到了" pickle.PicklingError:无法解决'锁定' object" ,因为spark尝试在所有节点上同时运行这两个方法。

  

问题:如何在作为参数传递给foreach或foreachPartition的方法上使用env变量?

import os
from pyspark.sql import SparkSession
import redis

spark = (SparkSession
        .builder
        .getOrCreate())

print "---------"
print os.getenv("REDIS_REPORTS_URL")
print "---------"

def save_on_redis(row):
    redis_ = redis.StrictRedis(host=os.getenv("REDIS_REPORTS_URL"), port=6379, db=0)
    print os.getenv("REDIS_REPORTS_URL")
    print redis_
    redis_.set("#teste#", "fagner")


df  = spark.createDataFrame([(0,1), (0,1), (0,2)], ["id", "score"])
df.foreach(save_on_redis)

1 个答案:

答案 0 :(得分:0)

我建议你在驱动程序进程中获取env变量并将其作为python变量传递给工作进程,在那里你可以使用os.putenv

设置你的环境

示例:

In [1]: import os

In [2]: a = sc.parallelize(range(20))

In [3]: os.getenv('MY_VAR')
Out[3]: 'some_value'

In [4]: def f(iter):
    import os
    return (str(os.getenv('MY_VAR')),)
   ...:

In [5]: a.mapPartitions(f).collect()
Out[5]: ['None', 'None']

In [6]: my_var = os.getenv('MY_VAR')

In [6]: def f2(iter):
    import os
    from subprocess import check_output
    os.putenv('MY_VAR', my_var)
    return (check_output('env | grep MY_VAR', shell=True), my_var)
   ....:

In [7]: a.mapPartitions(f2).collect()
Out[7]:
['MY_VAR=some_value\n',
 'some_value',
 'MY_VAR=some_value\n',
 'some_value']

PS。根据{{​​3}},最好直接修改os.environ映射对象,而不是使用os.putenv