python中的multiprocessing.map具有非常大的只读对象?

问题描述:

我有一个readonly非常大的数据框,我想做一些计算,所以我做一个multiprocessing.map并将数据框设置为全局。但是,这是否意味着对于每个进程,程序都会单独复制数据帧(所以它会很快然后是共享的)?python中的multiprocessing.map具有非常大的只读对象?

+0

注意如果你曾经创建过任何线程,那么使用多处理是完全不安全的,如果任何一个随机锁被其他线程锁定(并且有很多锁),分叉进程在尝试访问它时会死锁。 – o11c

如果我理解正确的话,你将不会被试图在Pandas DataFrame使用multiprocessing.map因为数据帧是在NumPy ndarray结构和内置NumPy的得到任何好处已经释放GIL,扩展到SMP硬件,在可用的位置使用矢量化机器指令等等。如您所说,您可能会在DataFrame结构上产生大量的RAM消耗和数据复制或共享内存锁定开销,这对您毫无益处。在这个SO Question: Multiprocessing.Pool makes Numpy matrix multiplication slower中讨论了NumPy和Python的multiprocessing模块组合的性能考虑。

,你治疗,因为这数据帧的事实,因为它意味着你可以写身边os.fork()码只读有趣的是它,由于OS CoW的(副本上写)通过叉语义()系统调用应该是一种廉价的方式来与子进程共享数据,允许每个进程以各种方式分析日期。 (当然,写入数据的任何代码都会触发新页面的分配和复制)。

模块使用罩(至少在Unix,Linux和类似的系统)下的叉()系统调用。如果在调用任何多处理函数之前创建并完全填充此大型数据结构(DataFrame),或者实例化任何创建子进程的对象,那么您可能能够访问每个进程隐式继承的DataFrame副本。我现在没有时间编写一些测试代码;但这可能会奏效。

至于将您的结果重新合并回父母或委托流程......您可以通过任何IPC(进程间通信)机制来完成此任务。如果您在调用任何多处理分支方法之前通过初始化来隐式共享数据,那么您可以简单实例化一个multiprocessing.Queue并通过它提供结果。如果没有这个,我个人会考虑在同一个系统上或在该LAN段上的任何其他系统上设置Redis的实例。使用API​​和Python模块(对hiredis自动/透明地支持Redis结果的高性能反序列化),Redis非常高效且非常易于配置和维护。

如果您的需求让您朝这个方向发展,Redis可能更容易将您的应用程序分布到多个节点上。当然,那时你也可以考虑使用PySpark,它可以提供许多功能,从Pandas DataFrames到Apache Spark RDD套件(或Spark SQL“DataFrames”)映射得相当好。这是几年前的一篇文章:Databricks: From Pandas to Apache Spark's DataFrames

一般来说,Apache Spark的重点是在不同的节点之间分配数据计算;这比在单个机器内的核心之间分配更具可扩展性。 (然后,关注归结到I/O的节点,这样每个人都可以得到它加载的数据集的数据块。这就是它非常适合于HDFS问题。

我希望帮助。

每个子流程都有自己的资源,所以这意味着。更确切地说,每个子流程都会复制原始数据框的一部分,由您的实施决定。

但它会很快然后共享一个?我不确定。除非你的数据框实现了w/r锁定,否则读取一个共享的或者分开的读取是一样的。但为什么数据帧需要锁定读取操作?这没有意义。