【问题标题】:How does apache arrow facilitate "No overhead for cross-system communication"?apache 箭头如何促进“跨系统通信无开销”?
【发布时间】:2020-01-17 19:59:31
【问题描述】:

由于“零复制读取”、“零 serde”和“跨系统通信无开销”的承诺,我现在对 Apache Arrow 非常感兴趣。我对这个项目的理解(通过 pyarrow 的镜头)是它描述了数据的内存格式,这样多个任务就可以像藏宝图一样读取这个。找到相同数据的方法(无需复制)。我想我可以在一个进程中看到它在 Python/Pandas 中是如何工作的;创建一个箭头数组非常容易,将它传递给不同的对象,并观察整个“零拷贝”的运行情况。

但是,当我们谈论没有开销的跨系统通信时,我几乎完全迷失了。例如,PySpark 如何将 Java 对象转换为箭头格式,然后将其传递给 Python/Pandas?我试图查看代码here,但对于非 java/scala 的人来说,它看起来像是将 spark 行转换为 Arrow 对象,然后转换为 byteArrays(第 124 行),这看起来不像零副本,零开销。

同样,如果我想尝试将 Arrow 数组从 Python/pyarrow 传递给 Rust(使用 Rust 的 Arrow API),我不知道该怎么做,特别是考虑到 @ 987654322@ 从 Python 调用 Rust 函数的方法似乎不适用于 Arrow 原语。有没有办法将 Rust 和 Python 都指向相同的内存地址?我是否必须以某种方式将箭头数据作为 byteArray 发送?

// lib.rs
#[macro_use]
extern crate cpython;

use cpython::{PyResult, Python};
use arrow::array::Int64Array;
use arrow::compute::array_ops::sum;

fn sum_col(_py: Python, val: Int64Array) -> PyResult<i64> {
    let total = sum(val).unwrap();
    Ok(total)
}

py_module_initializer!(rust_arrow_2, initrust_arrow_2, Pyinit_rust_arrow_2, |py, m| {
    m.add(py, "__doc__", "This module is implemented in Rust.")?;
    m.add(py, "sum_col", py_fn!(py, sum_col(val: Int64Array)))?;
    Ok(())
});
$ cargo build --release
...
error[E0277]: the trait bound `arrow::array::array::PrimitiveArray<arrow::datatypes::Int64Type>: cpython::FromPyObject<'_>` is not satisfied
  --> src/lib.rs:15:26
   |
15 |     m.add(py, "sum_col", py_fn!(py, sum_col(val: Int64Array)))?;
   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `cpython::FromPyObject<'_>` is not implemented for `arrow::array::array::PrimitiveArray<arrow::datatypes::Int64Type>`
   |
   = note: required by `cpython::FromPyObject::extract`
   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

【问题讨论】:

  • 向 user@arrow.apache.org 发送了一封电子邮件,而 Wes 的回复(简而言之)是该功能目前不存在,尽管它正在开发中。这是电子邮件链:lists.apache.org/list.html?user@arrow.apache.org
  • AFAIR 零拷贝是不可能的,因为不同的平台将使用不同的方式来保留缺失值 (NA)。

标签: python pyspark rust pyarrow apache-arrow


【解决方案1】:

这里有几个问题:

  1. spark如何与python共享数据?

    这是通过使用Arrow IPC format 的套接字完成的,因此它不是完全零拷贝,但仍然比其他方法快得多

  2. 一般如何实现零拷贝?

    我知道的方法是在实现之间传递指针地址。例如,Arrow 中的 Gandiva 模块通过 [JNI] (https://github.com/apache/arrow/blob/master/java/gandiva/src/main/java/org/apache/arrow/gandiva/evaluator/JniWrapper.java#L65) 通过传递数据缓冲区地址并将它们重新组合成 RowBatch 来实现这一点。

    专门针对 python/Java 互操作的第二种方法是 Jpype,尽管实现不是 100% 完成。

    您可以通过从指针创建 buffers 并将它们组装成 arrays 来在 pyarrow 中执行类似的操作

  3. 如何在 Rust 中完成?

    我没有 Rust 方面的专业知识,但您可以通过电子邮件向 Arrow users@ 或 dev@ 邮件列表发送电子邮件,看看其他人做了什么,或者是否有机会为标准化做贡献。

【讨论】:

  • 非常有用的信息和链接,尤其是 IPC 组件。在跨越语言障碍时,我需要尝试一下它的实际功能,但这对我来说绝对是朝着正确方向迈出的一步 - 谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-06-29
  • 1970-01-01
  • 2023-04-09
  • 1970-01-01
  • 2018-06-28
  • 1970-01-01
相关资源
最近更新 更多