如何将Numpy数组从PySpark worker保存到HDFS或共享文件系统?

时间:2015-11-18 22:18:21

标签: hadoop apache-spark hdfs pyspark shared-file

我想在PySpark中有效地将numpy数组从/向工作机器(函数)保存/读取到HDFS。我有两台机器A和B.A有主人和工人。 B有一名工人。对于例如我想实现以下目标:

if __name__ == "__main__":
    conf = SparkConf().setMaster("local").setAppName("Test")
    sc = SparkContext(conf = conf)
    sc.parallelize([0,1,2,3], 2).foreachPartition(func)

def func(iterator):
    P = << LOAD from HDFS or Shared Memory as numpy array>>
    for x in iterator:
        P = P + x

    << SAVE P (numpy array) to HDFS/ shared file system >>

什么是快速有效的方法?

1 个答案:

答案 0 :(得分:1)

我偶然发现了同样的问题。最后使用了HdfsCli module和tempfiles与Python3.4的解决方法。

  1. 进口:
  2. from hdfs import InsecureClient
    from tempfile import TemporaryFile
    
    1. 创建一个hdfs客户端。在大多数情况下,最好在脚本中的某个位置使用实用程序功能,例如:
    2. def get_hdfs_client():
          return InsecureClient("<your webhdfs uri>", user="<hdfs user>",
               root="<hdfs base path>")
      
      1. 将你的numpy加载并保存在一个worker函数中:
      2. hdfs_client = get_hdfs_client()
        
        # load from file.npy
        path = "/whatever/hdfs/file.npy"
        tf = TemporaryFile()
        
        with hdfs_client.read(path) as reader:
            tf.write(reader.read())
            tf.seek(0) # important, set cursor to beginning of file
        
        np_array = numpy.load(tf)
        
        ...
        
        # save to file.npy
        tf = TemporaryFile()
        numpy.save(tf, np_array)
        tf.seek(0) # important ! set the cursor to the beginning of the file
        # with overwrite=False, an exception is thrown if the file already exists
        hdfs_client.write("/whatever/output/file.npy", tf.read(),  overwrite=True) 
        

        注意:

        • 用于创建hdfs客户端的uri以http://开头,因为它使用hdfs文件系统的Web界面;
        • 确保传递给hdfs客户端的用户具有读写权限
        • 根据我的经验,开销并不重要(至少在执行时间方面)
        • 使用临时文件(与/tmp中的常规文件相比)的优点是,在脚本结束后,确保没有垃圾文件留在群集机器中,通常与否