跳转至

Qiita 微生物组多组学数据管理与分析平台

概述

Qiita 是一个专为大规模微生物组多组学研究设计的可扩展数据管理、处理与分析平台。该项目支持包括扩增子(amplicon)、宏基因组(metagenomic)、宏转录组(metatranscriptomic)、代谢组(metabolomic)和蛋白质组(proteomic)在内的多种组学数据类型,设计上可承载数百万份样本和数百 TB 级别的数据量。平台借鉴了既有 Qiita 数据模型以及 NCBI BioSample 标准,致力于为研究团队提供从样本管理、实验处理到计算分析的端到端工作流。

Qiita 采用微服务架构,由四个核心组件协同工作: - qiita-control-plane(控制平面):基于 Python/FastAPI 的 REST API 服务,负责研究项目(study)、样本(sample)、实验准备(prep)的增删改查、搜索以及工作票(work ticket)管理。 - qiita-data-plane(数据平面):基于 Rust/Arrow Flight 的高性能数据 I/O 层,通过 gRPC 协议提供批量数据存取,底层采用 DuckDB + DuckLake 引擎直接读写 Parquet 文件。 - qiita-compute-orchestrator(计算编排器):基于 Python/FastAPI 的作业生命周期管理器,通过 slurmrestd 接口实现作业提交、轮询、验证与报告。 - qiita-common(公共库):包含所有 Python 组件共享的 Pydantic 模型、配置管理以及 REST 客户端工具集。

平台正在积极开发中,当前版本尚未达到生产可用状态,但已经提供了完整的本地开发、测试和初步部署流水线。

核心知识点

1. 平台架构与组件职责

Qiita 的四层架构实现了控制逻辑与数据通道的分离,能够在不同负载类型上独立扩展。

1.1 控制平面(qiita-control-plane)

  • 技术栈:Python + FastAPI
  • 功能:暴露 RESTful API,对外提供元数据的管理界面。用户或客户端通过该服务创建研究项目、注册样本、定义实验前处理步骤(如 PCR 引物、文库构建方法等),并生成下游数据处理的“工作票”。控制平面不直接处理大规模原始数据,只记录数据的位置、格式和状态。
  • 依赖:需要 PostgreSQL 数据库存储元数据,数据库连接通过 .env.control-plane 文件中的 DATABASE_URL 指定。

1.2 数据平面(qiita-data-plane)

  • 技术栈:Rust + Apache Arrow Flight
  • 功能:面向海量数据的批量读写服务。使用 gRPC 协议提供高性能、低延迟的列式数据传输,内部使用 DuckDB 作为查询引擎,并通过 DuckLake 扩展在 Parquet 文件上直接建表和管理,避免额外的数据拷贝。该组件适合加载上千样本的原始测序数据或定量矩阵,并在数据平面内部完成过滤、聚合、格式转换等操作。
  • 依赖:需要专门的 “DuckLake catalog” PostgreSQL 数据库(独立于控制平面的业务数据库),其连接信息由 .env.data-plane 中的 DUCKLAKE_CATALOG_CONNSTR 指定。

1.3 计算编排器(qiita-compute-orchestrator)

  • 技术栈:Python + FastAPI
  • 功能:作为 HPC(高性能计算)集群的任务调度接口,通过调用 slurmrestd 的 REST API 将计算作业提交到 SLURM 调度系统。负责作业的生命周期管理:包括提交时的资源申请、运行时的状态轮询、完成后的输出验证和结果回写通知。它可以被控制平面触发,将“工作票”转换为实际的计算任务。
  • 依赖:需要配置集群队列信息、作业模板、Apptainer 容器镜像路径等,环境变量在 .env.compute-orchestrator 中维护。

1.4 公共库(qiita-common)

  • 技术栈:Python(基于 Pydantic)
  • 功能:为所有 Python 组件提供统一的 Pydantic 模型定义(如 Study、Sample、AnalysisJob 等),确保 API 数据格式、数据库 ORM 对象以及消息队列中的数据传输对象保持一致。同时封装了 REST 客户端工具,便于组件间互相调用。

2. 数据模型与存储设计

Qiita 的数据模式继承自现有 Qiita 生态系统和 BioSample 标准,强调样本元数据的规范性与可扩展性。核心实体包括: - Study:对应一个研究项目,包含项目名称、描述、负责人等全局信息。 - Sample:具体生物样本,如粪便样本、土壤样本,关联到特定 Study,并携带采集时间、宿主、地理坐标等元数据。 - Prep:实验前处理步骤的记录,将 Sample 与特定的测序平台、引物、试剂盒信息绑定,是生成原始数据文件的上游源头。

在物理存储层面,数据平面采用列式存储格式 Parquet 管理原始数据与中间结果。DuckLake 通过维护 Parquet 文件的集合和分区信息,在 PostgreSQL 中记录轻量级的元数据(catalog),使得 DuckDB 可以直接执行 SQL 查询而无需加载全部数据本地。这种设计兼顾了数据湖的灵活性和数据库的查询性能,非常适合微生物组分析中常见的大宽表(如 OTU/ASV 表、功能注释矩阵)的交互式探索。

3. 安全性:HMAC 密钥交叉认证

控制平面与数据平面之间通过 HMAC 签名的请求进行内部认证,以避免未授权的直接数据访问。两个组件需要共享完全相同的 HMAC_SECRET_KEY。开发环境中通过生成随机密钥并同步写入两份 .env 文件来实现,生产环境则需使用密钥管理服务下发。若两侧密钥不一致,会导致数据平面拒绝来自控制平面的合法请求,引发平台内部调用失败。

4. 环境配置与多组件协同

每个组件都有独立的 .env 文件(模板为 .env.<svc>.example),开发者和部署工程师需要将其复制为 .env.<svc> 并填入实际值。三个服务组件共需三个环境文件:

  • .env.control-plane:数据库连接、Secret Key 等
  • .env.data-plane:DuckLake 目录数据库连接、Secret Key、数据存储路径等
  • .env.compute-orchestrator:SLURM 端点、容器注册表、计算资源限制等

这些模板文件与原组件中的 /etc/qiita/ 部署路径共享同一份制品,实现开发与生产的一致性。

代码实操

本节演示本地开发环境的完整搭建步骤,所有操作均在项目根目录下执行。以下命令添加了详细中文注释。

# ============================
# 1. 检查并安装开发依赖工具
# ============================
# make dev-setup 会检测 uv, rust/cargo, PostgreSQL, apptainer, dbmate, grpcurl 等工具是否存在,
# 若缺失则打印对应安装命令(需手动执行),但不自动安装系统级软件包。
make dev-setup

# ============================
# 2. 安装 pre-commit 钩子
# ============================
# 用于在每次 git commit 前自动运行代码格式化和基础检查,每个 clone 只需执行一次。
make install-hooks

# ============================
# 3. 构建所有组件依赖
# ============================
# 安装 Python 依赖(通过 uv)并编译 Rust 数据平面。
make build

# ============================
# 4. 从模板创建本地环境变量文件
# ============================
# 每个组件一个 .env 文件,.example 是模板,cp 后的无后缀版本会被 .gitignore 忽略。
for svc in control-plane data-plane compute-orchestrator; do
    cp ".env.$svc.example" ".env.$svc"
done

# ============================
# 5. 生成共享 HMAC 密钥并同步写入两个文件
# ============================
# 生成 32 字节随机密钥,并用 sed 替换占位符。
# 注意必须同时更新 .env.control-plane 和 .env.data-plane,否则服务间通信会失败。
HMAC_SECRET_KEY=$(openssl rand -base64 32)
for f in .env.control-plane .env.data-plane; do
    sed -i.bak "s|^HMAC_SECRET_KEY=.*|HMAC_SECRET_KEY=$HMAC_SECRET_KEY|" "$f"
    rm "$f.bak"  # 删除备份文件
done

# ============================
# 6. 编辑各 .env 文件中的剩余占位符
# ============================
# 需要手动修改以下关键连接信息:
#   .env.control-plane:        DATABASE_URL 中的用户名
#   .env.data-plane:           DUCKLAKE_CATALOG_CONNSTR 中的用户名
# 编辑完成后,将全部环境变量加载到当前 Shell 会话:
set -a
source .env.control-plane
source .env.data-plane
source .env.compute-orchestrator
set +a

# ============================
# 7. 确保 PostgreSQL 正在运行
# ============================
# macOS (Homebrew):
brew services start postgresql@17
# Linux (systemd):
sudo systemctl start postgresql
# 首次安装 Linux 的 PostgreSQL 时,默认只有 peer 认证的 postgres 超级用户,
# 需要为自己创建超级用户角色:
sudo -u postgres createuser -s $USER

# ============================
# 8. 创建数据库并执行迁移
# ============================
# 如果 qiita 数据库不存在,会由 dbmate 自动创建;否则仅执行待处理的迁移文件。
make migrate

常用开发命令

# 运行纯单元测试(无需数据库等基础设施)
make test

# 运行控制平面的完整测试,包括需要数据库的用例
# 默认会启动一个 Docker 容器运行 Postgres,
# 若希望使用宿主机 Postgres,需设置 QIITA_USE_HOST_POSTGRES=1
make test-control-plane-with-db

# 运行跨组件的集成测试(同样需要 Postgres)
make test-integration

# 代码静态检查与格式化
make lint

# 清理构建产物
make clean

部署相关命令

# 构建并输出 systemd 单元文件和 nginx 配置的安装说明
make deploy

# 健康检查:验证三个服务均已启动
make verify-health

在生产环境中,make deploy 会将事先准备好的 .env 文件安装至 /etc/qiita/,并配置 systemd 托管所有服务进程。前端通过 nginx 反向代理:REST 请求路由至控制平面,gRPC 流量则负载均衡到多个数据平面实例。

常见问题

Q1: 执行 make migrate 时提示无法连接到 PostgreSQL

原因:PostgreSQL 服务未启动,或 DATABASE_URL 中的地址信息不正确。 解决: - 检查服务状态:pg_isready 或 systemd/journalctl。 - 检查 .env.control-plane 中的 DATABASE_URL,确保主机、端口、用户名、密码与当前运行的实例匹配。 - Linux 初次安装可能仅存在 postgres 用户,需要先创建与操作系统用户名一致的角色并赋予创建数据库权限:sudo -u postgres createuser -s $USER

Q2: 测试或运行时出现 HMAC 签名验证错误

原因:控制平面和数据平面的 HMAC_SECRET_KEY 不一致。 解决:重新生成一个密钥,并同时更新 .env.control-plane.env.data-plane 两个文件,确保两个文件中的值逐字节相同。然后重启受影响的组件。

Q3: 运行集成测试时数据平面报“DuckLake catalog connection failed”

原因:数据平面需要一个独立的 DuckLake 目录数据库,该数据库并不由 make migrate 自动创建(make migrate 只管理控制平面的业务数据库)。 解决: 1. 确认 .env.data-plane 中的 DUCKLAKE_CATALOG_CONNSTR 指向一个有效的 PostgreSQL 数据库。 2. 手动创建该数据库:createdb ducklake_catalog(名字根据连接字符串而定)。 3. 数据平面在首次启动时会自动初始化所需的表结构,无需额外迁移步骤。

Q4: macOS 上运行 make dev-setup 提示 apptainer 不可用

原因:apptainer 是 Linux only 的工具,用于构建计算工作流的容器镜像。 影响:macOS 开发者会收到一条跳过安装的提示,但这不影响大部分开发测试,除非需要测试和构建与容器计算作业相关的功能。多数单元测试和集成测试均不依赖 apptainer,可以照常进行。

Q5: 我只需要修复一个文档或脚本错误,也需要完整安装所有依赖吗?

不需要。根据贡献内容选择合适的安装深度: - 仅修改文档或脚本:执行 make dev-setupmake install-hooks,然后用 make lint 检查格式即可。 - 修改纯 Python 逻辑且不涉及数据库:只需执行步骤 1-3,make build 安装依赖后即可使用 make test 运行无 DB 的单元测试。 - 涉及数据库或跨组件改动:按完整流程配置。

Q6: 运行 make test-control-plane-with-db 时如何选择数据库来源?

默认会在 Docker 中启动一个临时 PostgreSQL 容器。若开发者希望使用本地 Postgres 实例(例如已配置好且拥有测试数据的),可以通过环境变量 QIITA_USE_HOST_POSTGRES=1 让测试套件直接连接宿主机数据库。相关详细说明可参阅 docs/runbooks/integration-tests-host-postgres.md

速查表

组件速览

组件语言/框架主要功能依赖服务
qiita-control-planePython / FastAPI研究、样本、前处理的 CRUD,工作票管理PostgreSQL (业务库)
qiita-data-planeRust / Arrow Flight批量数据读写,Parquet 查询引擎PostgreSQL (DuckLake目录)
qiita-compute-orchestratorPython / FastAPI通过 slurmrestd 管理 HPC 作业SLURM 集群,Apptainer
qiita-commonPython (Pydantic)共享模型、配置和客户端工具

常用命令备忘

任务命令
初次环境检查make dev-setup
安装依赖与编译make build
单元测试make test
控制平面完整测试(需DB)make test-control-plane-with-db
跨组件集成测试make test-integration
代码检查make lint
创建本地数据库与迁移make migrate
清理构建产物make clean
生成生产环境部署及配置make deploy
服务健康检查make verify-health

环境变量文件模板位置

组件模板文件关键配置项
控制平面.env.control-plane.exampleDATABASE_URL, HMAC_SECRET_KEY
数据平面.env.data-plane.exampleDUCKLAKE_CATALOG_CONNSTR, HMAC_SECRET_KEY
计算编排器.env.compute-orchestrator.exampleSLURM 端点, Apptainer 路径

所有模板最终都会被部署到生产环境的 /etc/qiita/ 目录下,由 systemd 管理的服务直接加载。


项目状态警告:Qiita 当前仍处于积极开发阶段,API 和数据格式可能发生大幅变更,不建议用于生产环境。请密切关注官方仓库的更新与里程碑发布。