kem*_*mri 7 python rust pyspark apache-arrow pyarrow
由于“零复制读取”、“零 Serde”和“跨系统通信无开销”的承诺,我现在对 Apache Arrow 非常感兴趣。我对这个项目的理解(通过 pyarrow 的视角)是它描述了数据的内存和格式,这样多个任务就可以像藏宝图一样读取它,并找到相同的数据(无需复制)。我想我可以在一个进程中看到它在 Python/Pandas 中是如何工作的;创建一个 Arrow 数组,将其传递给不同的对象,并观察整个“零复制”的运作过程非常容易。
然而,当我们谈论没有开销的跨系统通信时,我几乎完全迷失了。例如,PySpark 如何将 Java 对象转换为箭头格式,然后将其传递给 Python/Pandas?我试图查看这里的代码,但对于非 java/scala 人员来说,它看起来只是将 Spark 行转换为 Arrow 对象,然后转换为byteArrays (第 124 行),这看起来不像零复制、零开销大部头书。
同样,如果我想尝试将 Arrow 数组从 Python/pyarrow 传递到 Rust(使用 Rust 的 Arrow API),我无法思考如何做到这一点,特别是考虑到这种调用方法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(())
});
Run Code Online (Sandbox Code Playgroud)
$ 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)
Run Code Online (Sandbox Code Playgroud)
这里有几个问题:
Spark如何与Python共享数据?
这是使用Arrow IPC 格式通过套接字完成的,因此它不是完全零复制,但仍然比替代方案快得多
零拷贝一般是如何实现的?
我所知道的方法是在实现之间传递指针地址。例如,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% 完成。
您可以通过从指针创建缓冲区并将它们组装到数组中来在 pyarrow 中执行类似的操作
在 Rust 中如何做到这一点?
我没有 Rust 方面的专业知识,但您可以向 Arrow users@ 或 dev@ 邮件列表发送电子邮件,看看其他人做了什么,或者是否有机会为标准化做出贡献。
| 归档时间: |
|
| 查看次数: |
1721 次 |
| 最近记录: |