跳到内容

贡献许可

本项目是根据 BSL 许可协议 的条款发布的,因此您的贡献也将在相同的条款下获得许可。为了能够接受您的贡献,我们需要您明确确认您有能力并愿意根据这些条款提供贡献,我们使用的机制是 ArcticDB 个人贡献者许可协议

个人 - 若要根据这些条款参与贡献,请在您的贡献中每个提交的最后一行包含以下内容。您必须使用您的真实姓名(不允许使用化名或匿名贡献)。

Signed-Off By: Random J. Developer <random@developer.example.org>. By including this sign-off line I agree to the terms of the Contributor License Agreement.

公司 - 对于希望向 ArcticDB 贡献的公司,请联系 info@arcticdb.io,我们将安排将 CLA 发送给贵公司的授权签字人。

Docker 快速入门

本快速入门使用 vcpkg 的构建依赖项来构建发布版本。PyPi 上的 ArcticDB 版本使用 vcpkg 依赖项的方式如下所述。

请注意,以下说明将构建一个 Linux X86_64 发布版本。

1) 启动 ArcticDB 构建 Docker 镜像

在 Linux 终端中运行

docker pull ghcr.io/man-group/cibuildwheel_manylinux:2.12.1-3a897
docker run -it ghcr.io/man-group/cibuildwheel_manylinux:2.12.1-3a897

:warning: 以下说明不一定需要在提供的 Docker 镜像中运行。只要基本的构建依赖项可用,它们就可以在任何 Linux 发行版上的任何 Python 安装中运行。

如果在提供的 Docker 镜像之外运行,请将以下示例中的 /opt/python/cp39-cp39/bin/python3 更改为适合您的 Python 路径。

2) 检出 ArcticDB 及子模块

cd
git clone https://github.com/man-group/ArcticDB.git
cd ArcticDB
git submodule init && git submodule update

3) 启动构建

MY_PYTHON=/opt/python/cp39-cp39/bin/python3  # change if outside docker container/building against a different python
$MY_PYTHON -m pip install -U pip setuptools wheel grpcio-tools
ARCTIC_CMAKE_PRESET=skip $MY_PYTHON setup.py develop
# Change the below Python_EXECUTABLE value to build against a different Python version
cmake -DPython_EXECUTABLE=$MY_PYTHON -DTEST=off --preset linux-debug cpp
pushd cpp
cmake --build --preset linux-debug
popd

4) 运行 ArcticDB

确保以下命令在 Git 项目根目录下运行

# PYTHONPATH first part = Python module, second part compiled C++ binary
PYTHONPATH=`pwd`/python:`pwd`/cpp/out/linux-debug-build/arcticdb/ $MY_PYTHON

现在,在 Python shell 中

from arcticdb import Arctic

除了设置 PYTHONPATH 环境变量,您还可以通过运行以下命令将相应的路径安装到您的 Python 环境中(请注意,这将调用构建工具,因此会编译自上次编译以来更改过的所有文件)

$MY_PYTHON -m pip install -ve .

请注意,由于此操作会将二进制文件复制到您的 Python 安装目录,因此每次更改 C++ 文件后都必须运行此命令。

使用 mamba 和 conda-forge 构建

本节使用来自 conda-forge 的构建依赖项。这是在 conda-forge 上发布 ArcticDB 的先决条件。

⚠️ 截至本文撰写时,由于 libprotobuf 的链接问题,无法在此设置下在 Windows 上安装 ArcticDB。参见:https://github.com/man-group/ArcticDB/pull/449

  • 安装 mamba
  • 从其规范文件 (environment-dev.yml) 创建 arcticdb 环境
mamba env create -f environment-dev.yml
  • 激活 arcticdb 环境(每个新的 shell 会话都需要这样做)
mamba activate arcticdb

构建 CMake 目标

对于构建类型、操作系统和构建系统,定义了几个 CMake 预设

例如

  • 对于使用 mamba 和 conda-forge 在 Linux 上进行调试构建,使用
export ARCTICDB_USING_CONDA=1
cmake -DTEST=off --preset linux-conda-debug cpp
cd cpp

# You might need to use fewer threads than what's possible on your machine
# to not have it swap and freeze (e.g. we use 1 here).
cmake --build --preset linux-conda-debug -j 1
  • 对于使用 mamba 和 conda-forge 在 MacOS 上进行发布构建,使用

export ARCTICDB_USING_CONDA=1
cmake -DTEST=off --preset darwin-conda-release cpp
cd cpp

# You might need to use fewer threads than what's possible your machine
# not to have it swap and freeze (e.g. we use 1 here).
cmake --build --preset linux-conda-debug -j 1
注意:如果您不使用预设,您可能需要设置一些有用的环境变量

# To define the number of threads to use
export CMAKE_BUILD_PARALLEL_LEVEL=1
# To enable C++ tests
export ARCTICDB_BUILD_CPP_TESTS=1

构建并安装 Python 包

  • 使用在该环境中安装的依赖项,在 arcticdb 环境中构建并安装 ArcticDB。我们建议使用 editable 安装进行开发
export ARCTICDB_USING_CONDA=1
# Adapt the CMake preset to your setup.
export ARCTIC_CMAKE_PRESET=linux-conda-debug
python -m pip install --no-build-isolation --no-deps --verbose --editable .
  • 在 Python 中使用 ArcticDB
from arcticdb import Arctic

常见问题

如何针对不同的 Python 版本进行构建?

使用以下任一方式运行 cmake(配置,而非构建)

  1. 将不同版本的 Python 作为您 PATH 上的第一个 Python 版本,或者...
  2. Python_EXECUTABLE CMake 变量指向不同的 Python 二进制文件

请注意,要构建 ArcticDB 的 C++ 测试,您的安装中必须提供 Python 静态库!

如何运行 Python 测试?

请参阅下方运行测试的部分。

如何运行 C++ 测试?

请参阅下方运行测试的部分。

如何指定用于构建的 CPU 核心数?

这在构建时由 CMake 自动确定,但可以通过在构建命令中传入 --parallel <num cores> 来手动设置。

详细构建信息

Docker 镜像构建

上述 Docker 镜像基于 ManyLinux 构建。构建脚本位于此处

GitHub 输出位于此处

我们推荐您使用此镜像进行编译和测试!

设置 Linux

代码库和构建系统可以在任何相对较新的 Linux 发行版上工作,至少需要 GCC 8(推荐 10+)和 CMake 3.12(这些说明假定 3.21+)。

还需要安装一个开发版本的 Python 3.6+(包含 libpython.a.so 和完整的头文件)。请参阅pybind11 配置

我们在 Linux 上运行部分 Python 测试时需要一个 Mongo 可执行文件。您可以使用 mongod --version 命令检查是否已安装。

如果您尚未安装 mongod,请在网上搜索“mongo installation Linux”以获取针对您的发行版的安装说明。

按发行版列出的依赖项

发行版 经报告可用的版本 软件包
Ubuntu 20.04, 22.04 build-essential g++-10 libpcre3-dev libsasl2-dev libsodium-dev libkrb5-dev libcurl4-openssl-dev python3-dev
Centos 7 devtoolset-10-gcc-c++ openssl-devel cyrus-sasl-devel devtoolset-10-libatomic-devel libcurl-devel python3-devel

设置 Windows

我们推荐使用 Visual Studio 2022(或更高版本)安装编译器 (MSVC v142 或更高) 和工具 (Windows SDK, CMake, Python)。

Visual Studio 自带的 Python 足以创建发布版本,但对于调试版本,您需要单独从 Python.org 下载。

构建 arcticdb_ext 后,您需要创建到 .pyd 文件的符号链接,以便 Python 测试能针对它运行

# From the root of the ArcticDB git root checkout, in an administrator powershell session
# Change Python version as appropriate - below is for Python 3.11.
New-Item -Path .\python\arcticdb_ext.cp311-win_amd64.pyd -ItemType SymbolicLink -Value .\cpp\out\windows-cl-debug-build\arcticdb\arcticdb_ext.cp311-win_amd64.pyd

运行 Python 测试

确保 python 指向已安装 ArcticDBArcticDB 位于 PYTHON_PATH 中的 Python 解释器

python -m pip install arcticdb[Testing]
python -m pytest python/tests

运行 C++ 测试

使用 TEST=ON 配置 ArcticDB(默认为 OFF)

cmake -DPython_EXECUTABLE=<path to python> -DTEST=ON --preset linux-debug cpp

或者您可以设置以下环境变量

export ARCTICDB_BUILD_CPP_TESTS=1

请注意,<path to python> 必须指向与 Development.Embed 兼容的 Python。这通常是您通过依赖管理器安装 python3-devel 后的结果。

在提供的 Docker 镜像中,python3-devel 解析为安装在 /usr/bin/python3 的 Python 3.6,因此生成的命令将是

cmake -DPython_EXECUTABLE=/usr/bin/python3 -DTEST=ON --preset linux-debug cpp

然后构建并运行测试

cd cpp/out/linux-debug-build
make -j 1 arcticdb_rapidcheck_tests
make -j 1 test_unit_arcticdb
make test

CIBuildWheel

我们的源代码仓库支持 CIBuildWheel,它在隔离环境中针对所有支持的 Python 版本运行编译和测试。请遵循其文档。

配置

CMake 预设

为了更容易设置和共享所有环境变量、配置和命令,我们推荐使用 CMake 预设功能。

一些流行的 C++ IDE 的最新版本支持读取/导入这些预设:* Visual Studio 和 VS Code * CLion

在命令行上使用它也同样容易。

我们已经在 cpp 目录中提供了一个 CMakePresets.json 文件,用于我们的构建。您可以在同一目录下添加一个 CMakeUserPresets.json 文件进行本地覆盖。支持继承。

如果您在 Linux 上工作但没有使用我们的 Docker 镜像,您可能希望创建一个包含这些 cacheVariables 的预设:* CMAKE_MAKE_PROGRAM - makeninja 应该可以工作 * CMAKE_C_COMPILERCMAKE_CXX_COMPILER - 如果您偏好的编译器不是 cccxx

更多示例

指定 Python 版本的 Windows 预设
{
  "version": 3,
  "configurePresets": [
    {
      "name": "alt-vcpkg-debug:py3.10",
      "inherits": "windows-cl-debug",
      "cacheVariables": {
        "Python_ROOT_DIR": "C:\\Program Files\\Python310"
      },
      "environment": {
        "PATH": "C:\\Users\\me\\AppData\\Roaming\\Python\\Python310\\Scripts;C:\\Program Files\\Python310;$penv{PATH}",
        "PYTHONPATH": "C:\\Program Files\\Python310\\Lib;C:\\Users\\me\\AppData\\Roaming\\Python\\Python310\\site-packages"
      }
    }
  ],
  "buildPresets": [
    {
      "name": "alt-vcpkg-debug:py3.10",
      "configurePreset": "alt-vcpkg-debug:py3.10",
      "inheritConfigureEnvironment": true
    }
  ]
}

vcpkg 缓存

我们使用 vcpkg 来管理 C++ 依赖项。

编译依赖项需要大量磁盘空间。CMake 配置完成后,您可以删除 cpp\vcpkg\buildtrees 文件夹。

您可能还想配置一些缓存:* 二进制缓存 * 资产缓存

pybind11 配置

我们增强了 pybind11 的Python 发现功能,增加了我们自己的 PythonUtils 以改进诊断。请注意 CMake 输出中来自 PythonUtils.cmake 的警告消息,这些消息会突出显示任何与 Python 相关的配置问题。

默认情况下,我们针对 PATH 中的第一个 python 进行编译。

要覆盖此设置,请使用以下 CMake 变量之一*

  • Python_ROOT_DIR - 特定 Python 安装的通用路径“前缀”。通常,python 可执行文件位于同一目录或 bin 子目录中。此目录还应包含 includelib(rary) 子目录。
    例如,在 *nix 系统上,/usr 用于系统范围安装;/opt/pythonXX 用于本地管理的 Python 安装;/home/user/my_virtualenv 用于虚拟环境;C:\Program Files\PythonXX 用于 Windows Python 安装

  • Python_EXECUTABLE - Python 可执行文件的路径。(CMake 3.15+) CMake 将尝试通过运行此程序来提取 includelibrary 路径。这与 FindPython 的默认行为不同。

(* 注意:CMake 变量在 CMake 命令行上使用 -D 设置,或在 CMake*Presets.json 中使用 cacheVariables 键设置。名称区分大小写。

(仅)Python_ROOT_DIR 也可以设置为环境变量。在环境中设置其他变量可能无效。)

开发指南

ArcticDB 在写入时有很多选项可以配置数据在磁盘上的存储方式。在添加新功能时,不仅测试最简单的情况很重要,还需要测试新功能与这些各种选项的交互方式。本节旨在指导在添加新功能时应考虑哪些方面。

向后兼容性

磁盘上存储的数据

由于 ArcticDB 是一个纯客户端数据库,因此数据可能由比需要读取相同数据的客户端版本更高的客户端写入。如果更改是破坏性的,导致旧版本客户端无法读取数据,则应在 PR 和在线文档中清楚地记录这一点。如果可能,还应添加版本号,以便将来在同一领域的更改会显示更清晰的错误消息。

API

对 API 的任何更改(包括何时抛出异常以及异常的类型)都必须权衡其对现有用户造成的破坏性行为。请务必在 PR 描述中清楚地说明 API 更改,以便审阅者尽可能清楚地了解。如果更改是破坏性的,请确保在 PR 描述中适当突出显示。对于 NativeVersionStore API 尤其如此,因为 Man Group 内部有许多用户在使用它。

快照

在 ArcticDB 中,符号彼此之间几乎完全解耦。唯一主要例外是快照功能。每当更改涉及从存储中删除任何键时,必须注意这些键实际上可能仍被快照需要。类似地,任何修改快照(包括删除快照)的操作,都必须确保该快照是最后一个引用的所有键也被删除。有关更多详细信息,请参阅教程API 文档

批量方法

几乎所有主要的读写方法都有相应的批量版本。如果为非批量版本添加了功能,那么它也几乎总是应该适用于批量版本。我们还应该努力确保批量方法在可能遇到的各种情况下的行为一致性。例如,如果指定的版本不存在,read_batchread_metadata_batch 应该有相同的行为。

动态 schema

静态 schema 比动态 schema 简单得多,因此仅使用静态 schema 添加和测试的功能可能无法在动态 schema 下“直接工作”。特别是,应考虑以下情况

  • 在首次调用 write不存在的列,在后续调用 append存在
  • 在首次调用 write存在的列,在后续调用 append不存在
  • 将带有“小”类型(例如 uint8)的数值列追加到带有较大类型(例如 int16)的数值列,反之亦然。

分段

大多数测试都使用少量数据编写,以尽量减少运行时间。然而,许多 bug 只有在写入的数据被按列或按行切片时才会暴露出来。使用配置为切片成小数据段(例如 2x2)的测试 fixtures 可以帮助及早发现这些问题。

数据子选择

ArcticDB 的许多用例涉及写入包含数十万列或数十亿行的大符号。在这些情况下,读取数据的方法几乎总是需要带有一些参数来减少返回给用户的数据量。最常用的有

  • 独立的 headtail 方法*
  • columns - 仅选择列的一个子集
  • date_rangerow_range - 选择连续的行范围
  • 更高级的过滤 - 请参阅处理管道一节

处理管道

仅使用 columnsdate_rangerow_range 参数读取数据经过了大量优化,以避免不必要的内存数据复制。任何提供 query_builder 可选参数的读类似方法,或者等效地,应用了进一步处理的惰性读取,走的都是完全不同的代码路径,因为我们事先不知道输出数据的形状。虽然没有必要针对每种可能的分析操作都全面测试所有新功能,但通常值得使用一个简单的过滤器进行测试,该过滤器排除一部分原本会返回给用户的数据。

稀疏列

写入 ArcticDB 的大多数数据使用稠密列,这意味着在给定的行切片内,每一行在每一列中都有一个关联的值(即使该值是 NaN)。稀疏列的概念也已实现,在稀疏列中,列可能在行切片内的某些、部分或所有行中缺少值。任何读类似方法都应该能够处理这两种类型的存储列。

Pickling

当数据无法规范化为 ArcticDB 中支持的数据类型时,仍然可以使用 write_pickle 等方法进行存储。有许多操作无法对 Pickled 数据执行,例如 appendupdatedate_range 搜索等等。如果用户尝试执行对 Pickled 数据不支持的操作,他们收到一个有用的错误消息是很重要的。