Apache GraphAr 介绍与核心概念详解

Apache GraphAr(孵化中)图数据标准文件格式详解:项目定位、三层核心架构、功能特性、适用场景与限制,以及与裸列存直存、图数据库原生存储、开放表格式的选型对比。

Apache GraphArApacheApache GraphAr大数据图数据库Parquet2026/10/14

Apache GraphAr 介绍与核心概念详解

目标:介绍 Apache GraphAr(孵化中,Apache GraphAr)这一图数据标准文件格式的定位、核心架构与关键概念,并给出与裸列存直存、图数据库原生存储、开放表格式(Iceberg/Hudi 等)的选型对比。文中版本信息、命令回显均来自真实环境实测(Ubuntu 22.04,Python 3.10.12,graphar 0.13.0.dev1)。

一、环境信息

本文所有结论与命令回显均在以下真实环境中验证取得,读者对照学习时可以此为基准。

  • 操作系统:Ubuntu 22.04.5 LTS(x86_64)
  • Python:3.10.12(系统自带 python3,pip 22.0.2)
  • Apache GraphAr:0.13.0.dev1(PyPI 官方 Python 包 graphar,预发布版本)
  • 官方仓库:apache/incubator-graphar(main 分支,commit 06dddb1,2026-10-10)
  • 数据文件格式:Parquet(本文实测样本),元数据格式:YAML

验证基础环境与已安装组件的版本,命令与实测回显如下:

python3 -V && pip3 --version
Python 3.10.12
pip 22.0.2 from /usr/lib/python3/dist-packages/pip (python 3.10)
pip show graphar
Name: graphar
Version: 0.13.0.dev1
Summary: An open source, standard data file format for graph data storage and retrieval.
Author-email: GraphAr community <dev@graphar.apache.org>
License: Apache-2.0
Location: /opt/venv-graphar/lib/python3.10/site-packages
Requires: pydantic, pytest, pyyaml, typer
Required-by:
graphar --version
GraphAr CLI Version: 0.13.0.dev1

💡 说明:pip show 的 Summary 一句话点明了 GraphAr 的自我定位——"图数据存储与检索的开放标准数据文件格式"。注意它是"文件格式标准",不是数据库、不是查询引擎,这一定位贯穿全文的架构与选型分析。

二、软件概述

2.1 项目定位与背景

图数据(顶点、边及其属性)在业界长期缺乏一个中立、自描述、可直接落在分布式文件系统与对象存储上的标准文件格式:图数据库使用各自的私有存储,图计算引擎各自定义输入格式,导致图数据在系统之间搬运时必须开发一对一的转换程序。Apache GraphAr(全称 Graph Archive,当前处于 Apache 软件基金会孵化阶段)正是为解决该问题而生的标准文件格式规范:

  • 以文件为中心:一份 GraphAr 数据就是一个目录,由 YAML 元数据文件与一批数据文件(实测为 Parquet 列存文件)组成,任何支持读 Parquet 与 YAML 的系统都能接入;
  • 自描述:顶点类型、属性名、数据类型、主键、分块大小、文件类型、邻接表组织方式等全部写在元数据 YAML 中,无需外部约定;
  • 面向交换与归档:适合作为图数据湖仓落盘、图数据库与图计算引擎之间的交换格式、以及图数据的长期归档格式。

从实测的包元数据也可以确认其官方属性——Author-email: GraphAr community <dev@graphar.apache.org>、License: Apache-2.0(见第一章 pip show 回显)。

2.2 版本与发布形态(实测现状)

GraphAr 目前尚无正式稳定版,各语言发布形态差异较大,选型前必须了解:

pip index versions graphar --pre
graphar (0.13.0.dev1)
Available versions: 0.13.0.dev1, 0.13.0.dev0
  INSTALLED: 0.13.0.dev1
  LATEST:    0.13.0.dev1
  • Python:PyPI 包名为 graphar(不是 pygraphar,后者是 GraphScope 的同名占位包),仅提供 0.13.0.dev0 与 0.13.0.dev1 两个预发布版本,wheel 覆盖 cp39 至 cp313;
  • Java/Spark:Maven Central 上没有 org.apache.graphar 坐标(实测访问 https://repo1.maven.org/maven2/org/apache/graphar/ 返回 404,全站检索 0 结果),Spark/Java 侧只能从官方仓库 maven-projects 目录源码构建(0.13.0-SNAPSHOT);
  • 官方示例与测试数据:官方仓库 incubator-graphar-testing 提供 ldbc_sample、modern_graph 等标准样例数据,本文的实测均基于该数据集。

⚠️ 注意:Python 包 0.13.0.dev0 与 0.13.0.dev1 虽同为预发布版本,实测 0.13.0.dev0 安装后 import graphar 会报动态链接符号错误(详见《Ubuntu 22.04 安装 Apache GraphAr 指南》常见问题一章),生产与实验一律建议安装 0.13.0.dev1。

三、核心架构

3.1 分层组成:格式规范、核心库与语言绑定

GraphAr 在工程上由三层构成,理解分层有助于判断"某一能力由哪一层提供":

层内容实测可见的证据
格式规范层定义元数据 YAML 的字段与数据文件的目录组织规则(gar/v1 版本号)官方测试数据中所有元数据文件均带 version: gar/v1
核心库层C++ 实现的读写库(libgraphar),构建在 Apache Arrow 之上Python wheel 的动态库 libgraphar.so 随包捆绑 Arrow C++ 运行时
语言绑定与工具层Python 绑定(PyPI graphar 包)、命令行工具 graphar、Java/Spark(源码构建)import graphar 成功、graphar --help 可用

Python 侧安装完成后,模块暴露的完整 API 面实测如下:

python -c "import graphar; print([n for n in dir(graphar) if not n.startswith('_')])"
['AdjacentList', 'BuilderEdge', 'BuilderVertex', 'DataType', 'Edge', 'EdgeInfo', 'EdgeIter',
 'EdgesBuilder', 'EdgesCollection', 'GraphInfo', 'Property', 'PropertyGroup', 'Vertex',
 'VertexInfo', 'VertexIter', 'VerticesBuilder', 'VerticesCollection', 'annotations',
 'graph_info', 'high_level']

💡 说明:API 名即架构的映射——GraphInfo/VertexInfo/EdgeInfo 是元数据三件套,VerticesBuilder/EdgesBuilder 是写出构建器,VerticesCollection/EdgesCollection 是高层读取集合,Property/PropertyGroup/AdjacentList/DataType 是元数据组成单元。各 API 的实测用法见《Apache GraphAr 数据读写实战详解》。

3.2 元数据与数据分离的组织方式

一份 GraphAr 图数据在磁盘上由「三层元数据 YAML + 一组数据文件」构成,实测自建图(3 个 person 顶点、4 条 knows 边)的完整产出如下:

find /root/graphar-demo -type f | sort
/root/graphar-demo/demo_graph.graph.yml
/root/graphar-demo/edge/person_knows_person/ordered_by_dest/adj_list/part0/chunk0
/root/graphar-demo/edge/person_knows_person/ordered_by_dest/creationDate/part0/chunk0
/root/graphar-demo/edge/person_knows_person/ordered_by_dest/edge_count0
/root/graphar-demo/edge/person_knows_person/ordered_by_dest/offset/chunk0
/root/graphar-demo/edge/person_knows_person/ordered_by_dest/vertex_count
/root/graphar-demo/person.vertex.yaml
/root/graphar-demo/person_knows_person.edge.yaml
/root/graphar-demo/vertex/person/firstName_lastName_gender/chunk0
/root/graphar-demo/vertex/person/id/chunk0
/root/graphar-demo/vertex/person/vertex_count

对应关系为:

  • demo_graph.graph.yml:图级元数据(GraphInfo),记录图名、版本、顶点与边子元数据文件的引用;
  • person.vertex.yaml:顶点类型元数据(VertexInfo),记录类型名、chunk 大小、属性分组;
  • person_knows_person.edge.yaml:边类型元数据(EdgeInfo),记录源/目的类型、邻接表布局、属性分组;
  • vertex/ 与 edge/ 目录:实际数据文件,按属性组与邻接表布局分目录存放 Parquet chunk 文件,并配有 vertex_count、edge_count0、offset 等辅助文件。

三层元数据的具体字段逐项解读见《Apache GraphAr 格式规格与元数据详解》。

3.3 自带 CLI 工具

PyPI 包自带一个基于 typer 的命令行工具 graphar,当前提供 show、check、import 三个子命令,用于查看元数据、校验元数据与导入数据。实测帮助输出:

graphar --help
 Usage: graphar [OPTIONS] COMMAND [ARGS]...

 GraphAr Cli

╭─ Options ────────────────────────────────────────────────────────────────────╮
│ --version  -v        Show GraphAr version and exit                           │
│ --help     -h        Show this message and exit.                             │
╰──────────────────────────────────────────────────────────────────────────────╯
╭─ Commands ───────────────────────────────────────────────────────────────────╮
│ show    Show the metadata                                                    │
│ check   Check the metadata                                                   │
│ import  Import data                                                          │
╰──────────────────────────────────────────────────────────────────────────────╯

用 check 校验前文实测产出的图元数据,一次通过:

graphar check -p /root/graphar-demo/demo_graph.graph.yml
INFO     Graph is valid

💡 说明:CLI 是 0.13 阶段快速核对一份 GraphAr 数据是否规范的最直接手段。三个子命令的参数与实测回显详见《Apache GraphAr 常用 CLI 命令与工具详解》。

四、功能特性

4.1 标准化元数据

元数据全部落在 YAML 文件中,自描述且可读,实测 graphar show 可以直接打印加载后的元数据内容(摘自 0.13.0.dev1 实测):

graphar show -p /root/graphar-demo/demo_graph.graph.yml
INFO     edges:
           - person_knows_person.edge.yaml
         name: demo_graph
         prefix: "/root/graphar-demo/"
         version: gar/v1
         vertices:
           - person.vertex.yaml

特性要点:属性可声明数据类型(int64、string 等)、是否主键(is_primary)、是否可空(is_nullable);属性可分组(property_groups)落到不同数据文件;每组可指定文件类型(实测样本覆盖 parquet 与 csv 两种)。

4.2 大图分块(Chunk)组织

顶点与边都按 chunk_size 切分存储:顶点按行拆分为 chunk0、chunk1 等文件;边先按源(或目的)顶点 chunk 分 part,再在 part 内拆 chunk。实测官方 ldbc_sample 数据集(903 个顶点、chunk_size 100)顶点 id 属性目录正好 10 个 chunk 文件:

ls /opt/incubator-graphar/testing/ldbc_sample/parquet/vertex/person/id/
chunk0
chunk1
chunk2
chunk3
chunk4
chunk5
chunk6
chunk7
chunk8
chunk9

每个顶点类型目录还配有 8 字节计数字件 vertex_count,实测内容为小端 int64 数值 903:

od -An -tu8 /opt/incubator-graphar/testing/ldbc_sample/parquet/vertex/person/vertex_count
                  903

💡 说明:分块设计使大图的读取可以按 chunk 粒度并行、按需裁剪(只读某些属性组、某些顶点段),这是 GraphAr 相对"整图一个大文件"方案的核心优势。

4.3 多种邻接表组织方式

边数据支持按不同邻接表布局(Adjacency List Layout)组织,同一份边集可以同时落地多种布局以服务不同访问模式。实测的 knows 边元数据即同时声明了三种布局(unordered_by_source、ordered_by_source、ordered_by_dest),官方测试数据中三种布局的数据文件也都实际存在。

💡 技术拓展:图的邻接表在列存上有多种经典组织方式,GraphAr 的三种邻接表类型与业界术语对应关系及取舍如下——

布局对应经典结构特点适用场景
unordered_by_sourceCOO(坐标列表)边按写入顺序存放,只记录源/目的对追加写入快、全量扫描
ordered_by_sourceCSR(压缩稀疏行)按源顶点排序并带 offset 索引沿出边方向遍历(图计算最常用)
ordered_by_destCSC(压缩稀疏列)按目的顶点排序并带 offset 索引沿入边方向遍历、入度分析

本文实测自建图采用 ordered_by_dest 布局写出(与官方测试用法一致),目的是验证 CSC 式布局的 offset 组织与读回排序语义;图计算场景一般首选 ordered_by_source(CSR)。

4.4 构建器与集合两类 API

Python 绑定提供两类风格的 API:Builder(VerticesBuilder/EdgesBuilder)逐条组装并写出数据;Collection(VerticesCollection/EdgesCollection)以集合视图读回数据。实测一次「写出 3 顶点 4 边再读回」的闭环中,EdgesCollection 按 ordered_by_dest 语义排序返回(先按目的顶点、再按源顶点),与格式规范一致。完整可执行代码与回显见《Apache GraphAr 数据读写实战详解》。

五、适用场景与限制

5.1 适用场景

结合格式定位与实测表现,GraphAr 适合以下场景:

  1. 湖仓中的图数据落盘:把图数据以标准格式直接写进 HDFS/对象存储,供多个引擎共享读取;
  2. 系统间图数据交换:图数据库导出、图计算引擎导入之间使用统一中间格式,替代一对一转换程序;
  3. 图数据归档:YAML 元数据 + Parquet 数据均为开放格式,长期可读性远好于私有二进制;
  4. 大规模图数据的属性裁剪读取:属性分组与 chunk 切分让"只读部分属性、部分顶点段"成为常态操作。

5.2 当前限制(实测确认)

选型前需要正视以下实测确认的限制:

  1. 无正式稳定版:PyPI 仅有 0.13.0.dev0/dev1 预发布版本,不带 --pre 查询会报无匹配版本:
pip index versions graphar
ERROR: No matching distribution found for graphar
  1. Java/Spark 依赖源码构建:Maven Central 无任何 GraphAr 构件,官方仓库 GitHub Releases 也只有源码归档,Spark/Java 用户需自行构建 0.13.0-SNAPSHOT;
  2. Python 侧不能凭空构造属性类型:绑定未暴露 DataType 工厂,从零建图时应加载已有元数据(如官方测试数据)后复用其 VertexInfo/EdgeInfo 组装(实测复用路径已跑通);
  3. 预发布版本质量参差:0.13.0.dev0 实测存在动态链接缺陷,仅 0.13.0.dev1 可正常使用。

⚠️ 注意:GraphAr 是"格式规范 + SDK",本身不提供图查询、事务与索引能力;需要在线查询与事务仍需落回图数据库,GraphAr 在其中承担的是交换与归档格式角色。

六、同类选型对比

6.1 定位澄清

GraphAr 解决的是"图数据以什么标准格式存放与交换",它与下面三类方案不是同一层的东西:裸列存解决"列式文件怎么存",图数据库解决"图怎么被在线查询",开放表格式解决"数据湖表怎么管理"。选型时先问自己的问题是——我要的是查询能力、表管理能力,还是一份中立可交换的图文件格式。

6.2 技术拓展:四类方案一屏对比

💡 技术拓展:图数据持久化与交换的常见方案横向对比如下——

方案代表原理/特点适用场景与取舍
裸列存直存直接用 Parquet/ORC 自行约定目录灵活、零依赖,但图语义(类型、邻接、主键)全靠私有约定,跨团队不可复用单一团队内部的数据落盘
图数据库原生存储Neo4j、NebulaGraph提供事务、索引、图查询语言,存储私有在线图查询与事务;导出交换需专门通道
开放表格式Iceberg、Hudi、Delta Lake面向"表"的 ACID、schema 演进、快照管理,表语义是二维关系湖仓表管理;表达图邻接结构需自行映射
GraphArApache GraphAr(孵化中)图语义原生的文件格式标准:顶点/边/属性组/邻接布局全部显式建模,Parquet 落地图数据交换、湖仓图落盘、归档;无查询与事务能力

本文主题即 GraphAr:当目标是"一份任何引擎都能按图语义读懂的图文件"时它是唯一对口的方案;若目标是在线查询则选图数据库,若目标是表级湖仓管理则选开放表格式——三者实践中常组合使用(例如图数据库以 GraphAr 导出、经 Iceberg 管理的湖区归档)。

6.3 选型建议

  • 需要在线图查询与事务:选图数据库,GraphAr 可作为其导入/导出格式;
  • 需要湖仓表管理与 ACID:选 Iceberg/Hudi 等表格式,图顶点边表可以再按 GraphAr 规范组织目录;
  • 需要跨引擎、跨团队的图数据交换与归档:直接采用 GraphAr,这是它不可替代的位置;
  • 只是单团队内部临时落盘:裸 Parquet 也可行,但图语义约定不可复用,长期看不如 GraphAr 规范。

七、参考链接