跳转到主要内容

一个高效、可移植的纠删码工具

项目描述

生成冗余信息块,以便在某些块丢失的情况下,可以从剩余的块中恢复原始数据。此软件包包括命令行工具、C API、Python API 和 Haskell API。

Package Build Tests PyPI release status

简介和许可协议

此软件包实现了一种“纠删码”或“前向纠错码”。

您可以在 GNU 通用公共许可证(版本 2)或您选择的任何更高版本下使用此软件包。您还可以在传递性宽限期公共许可证(版本 1.0)或您选择的任何更高版本下使用此软件包。(您可以选择在任一许可证的条款下使用此软件包。)有关 GNU 通用公共许可证(版本 2)的条款,请参阅 COPYING.GPL 文件。有关传递性宽限期公共许可证(版本 1.0)的条款,请参阅 COPYING.TGPPL.rst 文件。

纠删码最广为人知的例子是 RAID-5 算法,该算法使得在丢失任何一块硬盘的情况下,存储的数据可以完全恢复。zfec 软件包中的算法具有类似的效果,但它不是从单个元素的丢失中恢复,而是可以参数化以预先选择可以容忍丢失的元素数量。

此软件包主要基于 Luigi Rizzo 等人旧的“fec”库,这是一个成熟且优化的纠删码实现。zfec 软件包对原始“fec”软件包进行了几个更改,包括添加 Python API、重构 C API 以支持零拷贝操作、对核心代码进行了一些清理和优化,以及添加了一个名为“zfec”的命令行工具。

安装

pip安装zfec

要运行自测,请从解包的源树或 git checkout 中执行 tox

要运行 Haskell API 的测试: cabal run test:tests

社区

目前可以通过以下命令通过 git 在网络上获取源代码

git clone https://github.com/tahoe-lafs/zfec

请将有关 zfec 的信息发布到 Tahoe-LAFS 邮件列表,并贡献补丁

<https://tahoe-lafs.org/cgi-bin/mailman/listinfo/tahoe-dev>

如果您发现 zfec 中存在错误,请在 github 上创建一个问题

<https://github.com/tahoe-lafs/zfec/issues>

概述

此软件包执行两个操作:编码和解码。编码通过产生额外的“校验块”(也称为“辅助块”)来扩展输入数据的大小。解码通过接收一些数据——原始数据的任何组合块(称为“主块”)和“辅助块”,并生成原始数据。

编码通过两个整数 k 和 m 参数化。m 是产生的块的总数,k 是重建原始数据所需的块数。m 必须至少为 1,最多为 256,k 必须至少为 1,最多为 m。

(请注意,当 k == m 时,执行纠删编码没有意义——它退化成 Unix “split” 工具的等价物,该工具简单地将输入分割成连续的段。同样,当 k == 1 时,它退化成 Unix “cp” 工具的等价物——每个块都是输入数据的完整副本。)

请注意,每个“主块”是原始数据的一个片段,因此其大小是原始数据大小的 1/k,每个“辅助块”大小相同,因此所有块使用的总空间是原始数据大小的 m/k 倍(加上一些填充以使最后一个主块与所有其他块大小相同)。除了块本身包含的数据外,还有一些必要的元数据用于后续重建。这些数据包括:1. K 的值,2. M 的值,3. 每个块的 sharenum,4. 使用的填充字节数。 “zfec” 命令行工具压缩这些数据片段,并将它们添加到每个份额的开头,因此由 “zfec” 命令行工具产生的每个份额文件比单独的份额数据大 1 到 4 字节。)

解码步骤需要输入由编码步骤产生的 k 个块。解码步骤输出的是先前输入到编码步骤的数据。

命令行工具

bin/ 目录包含两个 Unix 风格的命令行工具“zfec”和“zunfec”。执行 zfec --helpzunfec --help 以获取使用说明。

性能

要运行基准测试,请使用可选的 –k= 和 –m= 参数执行包含的 bench/bench_zfec.py 脚本。

以下是 i7-12700k 的结果

`测量 K=3, M=10 的数据编码,每次编码 1000000 字节 1000 次... 平均 MB/s: 364 测量 K=3, M=10 的 primary-only 数据解码,每次 1000 次... 平均 MB/s: 1894750 测量 K=3, M=10 的 secondary-only 数据解码,每次 1000 次... 平均 MB/s: 3298 `

这是一篇分析各种纠删码及其实现性能的论文,包括 zfec

http://www.usenix.org/events/fast09/tech/full_papers/plank/plank.pdf

Zfec 在不同机器以及不同的 K 和 M 值下都表现出良好的性能。它还有一个很小的内存占用。

API

每个块都与“blocknum”关联。每个主块的 blocknum 是其索引(从零开始),因此 0’th 块是第一个主块,它是文件的前几个字节,1’st 块是下一个主块,它是文件的下几个字节,依此类推。最后一个主块的 blocknum 是 k-1。每个辅助块的 blocknum 是一个介于 k 和 255(包括)之间的任意整数。(当使用 Python API 时,如果在调用 encode() 时不指定想要哪些辅助块,则默认提供从 k 到 m-1(包括)的块。)

  • C API

    fec_encode() 以输入数组的形式接收 k 个指针,每个指针指向一个包含输入数据(即第 i 个缓冲区包含第 i 个主块)的内存缓冲区。还有一个参数是一个数组,包含要产生的辅助块的 blocknum。 (该数组中的每个元素都是辅助块的 blocknum,即它必须大于等于 k 且小于 m。)

    fec_encode() 的输出是请求的辅助块集,这些块被写入调用者提供的输出缓冲区中。

    请注意,这个 fec_encode() 是一个“低级”API,因为它要求输入数据以一组恰好大小的内存缓冲区提供。如果您是从包含所有数据的单个缓冲区开始,请参阅 easyfec.py 的“Encoder”类,了解如何将单个大缓冲区拆分为适用于 fec_encode() 的适当输入缓冲区集。如果您是从磁盘上的文件开始,请参阅 filefec.py 的 encode_file_stringy_easyfec(),了解如何从文件中读取数据并将其传递给“Encoder”类。Python 接口提供了这些高级操作,Haskell 接口也是如此。如果您在其他语言中实现了执行这些高级任务的功能,请发送补丁到 tahoe-dev@tahoe-lafs.org,以便您的 API 可以包含在 zfec 的未来版本中。

    fec_decode() 接收一个包含 k 个指针的数组,每个指针指向一个包含块的缓冲区。还有一个单独的输入参数,它是包含每个传入块的块号的数组。

    fec_decode() 的输出是从输入中缺失并需要重建的主块集合。这些重建的块写入调用者提供的输出缓冲区。

  • Python API

    encode() 和 decode() 接收一个包含 k 个缓冲区的序列,其中“序列”是任何实现 Python 序列协议的对象(例如列表或元组),而“缓冲区”是任何实现 Python 缓冲区协议的对象(例如字符串或数组)。这些缓冲区中需要存在的内容与 C API 相同。

    encode() 还接收一个包含期望块号的列表。与 C API 不同,Python API 接受列表中期望的主块号和辅助块号。encode() 返回一个包含请求块的缓冲区对象的列表。对于每个请求的主块,结果列表包含从输入列表中引用的适当主块。对于每个请求的辅助块,列表包含包含该块的新的字符串对象。

    decode() 也接收一个表示传入块的块号的整数列表。decode() 返回一个包含所有原始数据主块的缓冲区对象的列表(按顺序)。对于输入列表中存在的每个主块,结果列表简单地包含传入输入列表的对象的引用。对于不在输入列表中的每个主块,结果列表包含包含该主块的新创建的字符串对象。

    请注意,可变数据和 Python API 返回输入引用的组合可能导致一个问题。

    返回输入引用是高效的,因为它避免了不必要的复制作业,但如果传入的对象是可变的,并且在该对象被 zfec 返回调用后发生更改,那么 zfec 的结果(即对该相同对象的引用)也将被更改。这种微妙之处是您为避免数据复制所付出的代价。如果您不想担心这个问题,则可以使用不可变对象(例如 Python 字符串)来保存传递给 zfec 的数据。

  • Haskell API

    Haskell 代码已经完全 Haddocked,要生成文档,请运行 runhaskell Setup.lhs haddock

实用工具

filefec.py 模块有一个用于高效读取文件并将其分块编码的实用函数。此模块由 bin/ 目录中的“zfec”和“zunfec”命令行工具使用。

依赖项

需要C编译器。要使用Python API或命令行工具,还需要Python解释器。我们已测试过与Python 2.7、3.5和3.6兼容。对于Haskell接口,需要GHC >= 6.8.1。

致谢

感谢原始fec库的作者Luigi Rizzo,以及为其做出贡献的人:Phil Karn、Robert Morelos-Zaragoza、Hari Thirumoorthy和Dan Rubenstein。感谢Mnet黑客编写了早期的Python包装器,尤其是Myers Carpenter和Hauke Johannknecht。感谢Brian Warner和Amber O’Whielacronx在API、文档、调试、压缩和单元测试方面的帮助。感谢Adam Langley改进C API并贡献Haskell API。感谢GCC(从Richard M. Stallman开始)和Valgrind(从Julian Seward开始)的创造者,他们提供了一对出色的工具。感谢我在Allmydata的同事们——Fabrice Grinda、Peter Secor、Rob Kinninmont、Brian Warner、Zandr Milewski、Justin Boreta、Mark Meras——资助这项工作并在自由软件许可证下发布。感谢Jack Lloyd、Samuel Neves和David-Sarah Hopwood。

下载文件

下载适用于您平台的文件。如果您不确定该选择哪一个,请了解更多关于安装包的信息

源代码发行版

zfec-1.5.7.4.tar.gz (84.6 kB 查看哈希值)

上传时间 源代码

构建发行版

zfec-1.5.7.4-pp39-pypy39_pp73-win_amd64.whl (60.8 kB 查看哈希值)

上传时间 PyPy Windows x86-64

zfec-1.5.7.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (59.8 kB 查看哈希值)

上传时间 PyPy manylinux: glibc 2.17+ x86-64

zfec-1.5.7.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (59.5 kB 查看哈希值)

上传时间 PyPy manylinux: glibc 2.17+ i686 manylinux: glibc 2.5+ i686

zfec-1.5.7.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl (58.1 kB 查看哈希值)

上传时间 PyPy macOS 10.9+ x86-64

zfec-1.5.7.4-pp38-pypy38_pp73-win_amd64.whl (60.8 kB 查看哈希值)

上传时间 PyPy Windows x86-64

zfec-1.5.7.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (59.8 kB 查看哈希值)

上传时间 PyPy manylinux: glibc 2.17+ x86-64

zfec-1.5.7.4-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (59.5 kB 查看哈希值)

上传时间 PyPy manylinux: glibc 2.17+ i686 manylinux: glibc 2.5+ i686

zfec-1.5.7.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl (58.1 kB 查看哈希值)

上传时间 PyPy macOS 10.9+ x86-64

zfec-1.5.7.4-pp37-pypy37_pp73-win_amd64.whl (60.8 kB 查看哈希值)

上传于 PyPy Windows x86-64

zfec-1.5.7.4-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (59.9 kB 查看哈希值)

上传于 PyPy manylinux: glibc 2.17+ x86-64

zfec-1.5.7.4-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (59.6 kB 查看哈希值)

上传于 PyPy manylinux: glibc 2.17+ i686 manylinux: glibc 2.5+ i686

zfec-1.5.7.4-pp37-pypy37_pp73-macosx_10_9_x86_64.whl (58.1 kB 查看哈希值)

上传于 PyPy macOS 10.9+ x86-64

zfec-1.5.7.4-cp312-cp312-win_amd64.whl (60.7 kB 查看哈希值)

上传于 CPython 3.12 Windows x86-64

zfec-1.5.7.4-cp312-cp312-win32.whl (59.1 kB 查看哈希值)

上传于 CPython 3.12 Windows x86

zfec-1.5.7.4-cp312-cp312-musllinux_1_1_x86_64.whl (89.2 kB 查看哈希值)

上传于 CPython 3.12 musllinux: musl 1.1+ x86-64

zfec-1.5.7.4-cp312-cp312-musllinux_1_1_i686.whl (85.0 kB 查看哈希值)

上传于 CPython 3.12 musllinux: musl 1.1+ i686

zfec-1.5.7.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (86.3 kB 查看哈希值)

上传于 CPython 3.12 manylinux: glibc 2.17+ x86-64

zfec-1.5.7.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (83.0 kB 查看哈希值)

上传于 CPython 3.12 manylinux: glibc 2.17+ i686 manylinux: glibc 2.5+ i686

zfec-1.5.7.4-cp312-cp312-macosx_11_0_arm64.whl (58.3 kB 查看哈希值)

上传于 CPython 3.12 macOS 11.0+ ARM64

zfec-1.5.7.4-cp312-cp312-macosx_10_9_x86_64.whl (58.7 kB 查看哈希值)

上传于 CPython 3.12 macOS 10.9+ x86-64

zfec-1.5.7.4-cp312-cp312-macosx_10_9_universal2.whl (69.6 kB 查看哈希值)

上传于 CPython 3.12 macOS 10.9+ universal2 (ARM64, x86-64)

zfec-1.5.7.4-cp311-cp311-win_amd64.whl (60.7 kB 查看哈希值)

上传于 CPython 3.11 Windows x86-64

zfec-1.5.7.4-cp311-cp311-win32.whl (59.0 kB 查看哈希值)

上传于 CPython 3.11 Windows x86

zfec-1.5.7.4-cp311-cp311-musllinux_1_1_x86_64.whl (89.0 kB 查看哈希值)

上传于 CPython 3.11 musllinux: musl 1.1+ x86-64

zfec-1.5.7.4-cp311-cp311-musllinux_1_1_i686.whl (85.0 kB 查看哈希值)

上传于 CPython 3.11 musllinux: musl 1.1+ i686

zfec-1.5.7.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (86.1 kB 查看哈希值)

上传于 CPython 3.11 manylinux: glibc 2.17+ x86-64

zfec-1.5.7.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (82.9 kB 查看哈希值)

上传于 CPython 3.11 manylinux: glibc 2.17+ i686 manylinux: glibc 2.5+ i686

zfec-1.5.7.4-cp311-cp311-macosx_11_0_arm64.whl (58.2 kB 查看哈希值)

上传于 CPython 3.11 macOS 11.0+ ARM64

zfec-1.5.7.4-cp311-cp311-macosx_10_9_x86_64.whl (58.6 kB 查看哈希值)

上传于 CPython 3.11 macOS 10.9+ x86-64

zfec-1.5.7.4-cp311-cp311-macosx_10_9_universal2.whl (69.5 kB 查看哈希值)

上传时间 CPython 3.11 macOS 10.9+ universal2 (ARM64, x86-64)

zfec-1.5.7.4-cp310-cp310-win_amd64.whl (60.7 kB 查看哈希值)

上传时间 CPython 3.10 Windows x86-64

zfec-1.5.7.4-cp310-cp310-win32.whl (59.0 kB 查看哈希值)

上传时间 CPython 3.10 Windows x86

zfec-1.5.7.4-cp310-cp310-musllinux_1_1_x86_64.whl (88.0 kB 查看哈希值)

上传时间 CPython 3.10 musllinux: musl 1.1+ x86-64

zfec-1.5.7.4-cp310-cp310-musllinux_1_1_i686.whl (84.0 kB 查看哈希值)

上传时间 CPython 3.10 musllinux: musl 1.1+ i686

zfec-1.5.7.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (84.3 kB 查看哈希值)

上传时间 CPython 3.10 manylinux: glibc 2.17+ x86-64

zfec-1.5.7.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (81.4 kB 查看哈希值)

上传时间 CPython 3.10 manylinux: glibc 2.17+ i686 manylinux: glibc 2.5+ i686

zfec-1.5.7.4-cp310-cp310-macosx_11_0_arm64.whl (58.2 kB 查看哈希值)

上传时间 CPython 3.10 macOS 11.0+ ARM64

zfec-1.5.7.4-cp310-cp310-macosx_10_9_x86_64.whl (58.6 kB 查看哈希值)

上传时间 CPython 3.10 macOS 10.9+ x86-64

zfec-1.5.7.4-cp310-cp310-macosx_10_9_universal2.whl (69.4 kB 查看哈希值)

上传时间 CPython 3.10 macOS 10.9+ universal2 (ARM64, x86-64)

zfec-1.5.7.4-cp39-cp39-win_amd64.whl (60.7 kB 查看哈希值)

上传时间: CPython 3.9 Windows x86-64

zfec-1.5.7.4-cp39-cp39-win32.whl (59.0 kB 查看哈希值)

上传时间: CPython 3.9 Windows x86

zfec-1.5.7.4-cp39-cp39-musllinux_1_1_x86_64.whl (87.8 kB 查看哈希值)

上传时间: CPython 3.9 musllinux: musl 1.1+ x86-64

zfec-1.5.7.4-cp39-cp39-musllinux_1_1_i686.whl (83.8 kB 查看哈希值)

上传时间: CPython 3.9 musllinux: musl 1.1+ i686

zfec-1.5.7.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (84.1 kB 查看哈希值)

上传时间: CPython 3.9 manylinux: glibc 2.17+ x86-64

zfec-1.5.7.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (81.2 kB 查看哈希值)

上传时间: CPython 3.9 manylinux: glibc 2.17+ i686 manylinux: glibc 2.5+ i686

zfec-1.5.7.4-cp39-cp39-macosx_11_0_arm64.whl (58.2 kB 查看哈希值)

上传时间: CPython 3.9 macOS 11.0+ ARM64

zfec-1.5.7.4-cp39-cp39-macosx_10_9_x86_64.whl (58.6 kB 查看哈希值)

上传时间: CPython 3.9 macOS 10.9+ x86-64

zfec-1.5.7.4-cp39-cp39-macosx_10_9_universal2.whl (69.4 kB 查看哈希值)

上传时间: CPython 3.9 macOS 10.9+ universal2 (ARM64, x86-64)

zfec-1.5.7.4-cp38-cp38-win_amd64.whl (60.7 kB 查看哈希值)

上传时间: CPython 3.8 Windows x86-64

zfec-1.5.7.4-cp38-cp38-win32.whl (59.0 kB 查看哈希值)

上传于 CPython 3.8 Windows x86

zfec-1.5.7.4-cp38-cp38-musllinux_1_1_x86_64.whl (87.7 kB 查看哈希值)

上传于 CPython 3.8 musllinux: musl 1.1+ x86-64

zfec-1.5.7.4-cp38-cp38-musllinux_1_1_i686.whl (83.7 kB 查看哈希值)

上传于 CPython 3.8 musllinux: musl 1.1+ i686

zfec-1.5.7.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (84.4 kB 查看哈希值)

上传于 CPython 3.8 manylinux: glibc 2.17+ x86-64

zfec-1.5.7.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (81.5 kB 查看哈希值)

上传于 CPython 3.8 manylinux: glibc 2.17+ i686 manylinux: glibc 2.5+ i686

zfec-1.5.7.4-cp38-cp38-macosx_11_0_arm64.whl (58.2 kB 查看哈希值)

上传于 CPython 3.8 macOS 11.0+ ARM64

zfec-1.5.7.4-cp38-cp38-macosx_10_9_x86_64.whl (58.6 kB 查看哈希值)

上传于 CPython 3.8 macOS 10.9+ x86-64

zfec-1.5.7.4-cp38-cp38-macosx_10_9_universal2.whl (69.4 kB 查看哈希值)

上传于 CPython 3.8 macOS 10.9+ universal2 (ARM64, x86-64)

由以下支持