{"id":17972352,"url":"https://github.com/apache/incubator-graphar","last_synced_at":"2025-10-24T17:41:02.597Z","repository":{"id":64289589,"uuid":"540480040","full_name":"apache/incubator-graphar","owner":"apache","description":"An open source, standard data file format for graph data storage and retrieval.","archived":false,"fork":false,"pushed_at":"2025-05-07T01:53:44.000Z","size":7173,"stargazers_count":275,"open_issues_count":80,"forks_count":70,"subscribers_count":31,"default_branch":"main","last_synced_at":"2025-05-13T01:29:46.910Z","etag":null,"topics":["big-data","data-orchestration","etl","graph","graph-analysis","graph-storage","pyspark","spark"],"latest_commit_sha":null,"homepage":"https://graphar.apache.org/","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/apache.png","metadata":{"files":{"readme":"README-zh-cn.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-09-23T14:30:07.000Z","updated_at":"2025-05-11T19:19:12.000Z","dependencies_parsed_at":"2023-11-14T04:21:17.214Z","dependency_job_id":"ada368d6-bdf1-4cd0-b8c9-ad1875ce1f60","html_url":"https://github.com/apache/incubator-graphar","commit_stats":null,"previous_names":["graphscope/graphar","apache/incubator-graphar","alibaba/graphar"],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apache%2Fincubator-graphar","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apache%2Fincubator-graphar/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apache%2Fincubator-graphar/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apache%2Fincubator-graphar/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/apache","download_url":"https://codeload.github.com/apache/incubator-graphar/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254471060,"owners_count":22076585,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["big-data","data-orchestration","etl","graph","graph-analysis","graph-storage","pyspark","spark"],"created_at":"2024-10-29T16:13:01.811Z","updated_at":"2025-10-24T17:41:02.591Z","avatar_url":"https://github.com/apache.png","language":"C++","funding_links":[],"categories":["大数据"],"sub_categories":[],"readme":"\u003ch1 align=\"center\" style=\"clear: both;\"\u003e\n    \u003cimg src=\"docs/images/graphar-logo.svg\" width=\"350\" alt=\"GraphAr\"\u003e\n\u003c/h1\u003e\n\u003cp align=\"center\"\u003e\n    一种用于图数据存储和读取的开源标准数据文件格式。\n\u003c/p\u003e\n\n[![GraphAr\nCI](https://github.com/apache/incubator-graphar/actions/workflows/ci.yml/badge.svg)](https://github.com/apache/incubator-graphar/actions)\n[![Docs\nCI](https://github.com/apache/incubator-graphar/actions/workflows/docs.yml/badge.svg)](https://github.com/apache/incubator-graphar/actions)\n[![GraphAr\nDocs](https://img.shields.io/badge/docs-latest-brightgreen.svg)](https://graphar.apache.org/docs/)\n[![Good First\nIssue](https://img.shields.io/github/labels/apache/incubator-graphar/Good%20First%20Issue?color=green\u0026label=Contribute)](https://github.com/apache/incubator-graphar/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)\n[![README-en](https://shields.io/badge/README-English-blue)](README.md)\n\n## GraphAr 项目简介\n\n\u003cimg src=\"docs/images/overview.png\" class=\"align-center\" width=\"770\"\nalt=\"Overview\" /\u003e\n\n图计算是大数据中的一种常见计算类型，例如社交网络分析、数据挖掘、网络路由和科学计算等。\n\nGraphAr（全称为“Graph Archive”，直译为图的归档）项目旨在使各种应用程序和系统（包括内存和外存中的存储、数据库、图计算系统和交互式图查询框架）能够方便高效地构建和访问图数据。\n\n它可以用于图数据的导入/导出和持久化存储，进行系统间高效的数据交换，从而减轻系统协作时的负担。此外，它还可以直接作为图计算应用的数据源。\n\n为实现这一目标，GraphAr 项目提供了：\n\n- GraphAr 格式：一种标准化的、与系统无关的图数据存储格式；\n- 各种语言的开发库：一组各种语言下用于读取、写入和转换 GraphAr 格式数据的开发库；\n\n通过使用 GraphAr 项目，用户可以：\n- 使用 GraphAr 格式以系统无关的方式存储和持久化图数据；\n- 通过开发库轻松访问和生成 GraphAr 格式的数据；\n- 利用 Apache Spark 快速操作和转换 GraphAr 格式的数据\n\n## The GraphAr Format\n\nGraphAr 格式专为属性图而设计。它使用元数据记录图的所有必要信息，并以分区的方式维护实际数据。\n\n属性图由顶点和边组成，每个顶点包含一个唯一标识符，并且包括：\n- 描述顶点类型的文本标签；\n- 一组属性，每个属性可以用键值对表示。\n\n每条边包含一个唯一标识符，并且包括：\n- 出边顶点（边的起点）；\n- 入边顶点（边的终点）；\n- 描述两个顶点之间关系的文本标签；\n- 一组属性。\n\n以下是一个属性图的示例，包含两种类型的顶点（“person” 和 “comment”）以及三种类型（“likes”, “knows” 和 “hasCreator”）的边。\n\n\u003cimg src=\"docs/images/property_graph.png\" class=\"align-center\"\nwidth=\"700\" alt=\"property graph\" /\u003e\n\n### GraphAr 的顶点\n\n#### 顶点的逻辑表\n\n每种类型的顶点（即具有相同标签的顶点）构成一个逻辑顶点表，每个顶点在此类型内被分配一个全局索引（称为内部顶点 ID），从 0 开始，对应于逻辑顶点表中顶点的行号。下图中提供了标签为 “person” 的顶点逻辑表的示例布局供参考。\n\n通过内部顶点 ID 和顶点标签，可以唯一标识一个顶点，并且可以从该表中访问其相应的属性。内部顶点 ID 还用于在维护图的拓扑结构时标识边的起始顶点和终止顶点。\n\n\u003cimg src=\"docs/images/vertex_logical_table.png\" class=\"align-center\"\nwidth=\"650\" alt=\"vertex logical table\" /\u003e\n\n####  顶点的物理表\n\n为了提高读写效率，逻辑顶点表将被分割成多个连续的顶点块。为了保持随机访问的能力，相同标签的顶点块大小是固定的。为了支持访问所需属性而无需从文件中读取所有属性，并且能够在不修改现有文件的情况下为顶点添加属性，逻辑表的列将被分为多个列组。\n\n以 person 顶点表为例，如果块大小设置为 500，那么逻辑表将被分成每个 500 行的子逻辑表，最后一个子逻辑表可能少于 500 行。用于维护属性的列也将被分成不同的组（例如，在我们的示例中为 2 个组）。因此，总共创建了 4 个物理顶点表来存储该示例逻辑表，如下图所示。\n\n\u003cimg src=\"docs/images/vertex_physical_table.png\" class=\"align-center\"\nwidth=\"650\" alt=\"vertex physical table\" /\u003e\n\n\u003e [!NOTE]\n\u003e 为了有效利用诸如 Parquet 之类 payload 文件格式的过滤下推功能，内部顶点 ID 作为一列存储在 payload 文件中。由于内部顶点 ID 是连续的，payload 文件格式可以对内部顶点 ID 列使用增量编码，这不会给存储带来太多的开销。\n\n### GraphAr 的边\n\n#### 边的逻辑表\n\n为了维护一种类型的边（具有相同的源标签、边标签和目标标签），会建立一个逻辑边表。为了支持从图存储文件中快速创建图，逻辑边表可以以类似于 [CSR/CSC](https://en.wikipedia.org/wiki/Sparse_matrix) 的方式维护拓扑信息，即边按照源或目标的内部顶点 ID 排序。通过这种方式，需要一个偏移表来存储每个顶点的边的起始偏移量，并且具有相同源/目标的边将连续存储在逻辑表中。\n\n以 person knows person 边的逻辑表为例，逻辑边表看起来如下所示：\n\n\u003cimg src=\"docs/images/edge_logical_table.png\" class=\"align-center\"\nwidth=\"650\" alt=\"edge logical table\" /\u003e\n\n#### 边的物理表\n与顶点表相同，逻辑边表也被分割为一些子逻辑表，每个子逻辑表包含源（或目标）顶点在相同顶点块中的边。根据分区策略和边的顺序，边可以按照以下四种类型之一存储在 GraphAr 中：\n\n- **ordered_by_source**：逻辑表中的所有边按照源的内部顶点 ID 排序，并进一步按源顶点 ID 进行分区，这可以看作是 CSR 格式。\n- **ordered_by_dest**：逻辑表中的所有边按照目标的内部顶点 ID 排序，并进一步按目标顶点 ID 进行分区，这可以看作是 CSC 格式。\n- **unordered_by_source**：使用源顶点的内部 ID 作为分区键，将边分割成不同的子逻辑表，并且每个子逻辑表中的边是无序的，这可以看作是 COO 格式。\n- **unordered_by_dest**：使用目标顶点的内部 ID 作为分区键，将边分割成不同的子逻辑表，并且每个子逻辑表中的边是无序的，这也可以看作是 COO 格式。\n\n之后，一个子逻辑表会进一步被划分为具有预定义固定行数的边块（称为边块大小）。最终，一个边块会按照以下方式分离为物理表：\n\n- 一个 `adjList` 表（仅包含两列：源和目标的内部顶点 ID）。\n- 0 个或多个边属性表，每个表包含一组属性。\n\n此外，对于 **ordered_by_source** 或 **ordered_by_dest** 类型的边，还会有一个偏移表。偏移表用于记录每个顶点的边的起始点。偏移表的分区应与相应的顶点表的分区保持一致。每个偏移块的第一行总是 0，表示对应子逻辑边表的起始点。\n\n以 `person--knows-\u003eperson` 边为例来说明。假设顶点块大小设置为 500，边块大小为 1024，并且边是 **ordered_by_source** 类型的，那么这些边可以存储在以下物理表中：\n\n\u003cimg src=\"docs/images/edge_physical_table1.png\" class=\"align-center\"\nwidth=\"650\" alt=\"edge logical table1\" /\u003e\n\n\u003cimg src=\"docs/images/edge_physical_table2.png\" class=\"align-center\"\nwidth=\"650\" alt=\"edge logical table2\" /\u003e\n\n## 基准测试（Benchmark）\n\n我们的实验在阿里云 r6.6xlarge 实例上进行，该实例配备了 24 核 Intel(R) Xeon(R) Platinum 8269CY CPU（主频 2.50GHz）、192GB 内存，运行 64 位 Ubuntu 20.04 LTS 系统。数据存储在一块容量为 200GB 的 PL0 ESSD 上，最大 I/O 吞吐量为 180MB/s。我们在其他平台和类 S3 存储上的附加测试也得到了相似的结果。\n\n### 数据集\n\n我们使用了来自 [Graph500](https://graph500.org/) 和 [LDBC](https://doi.org/10.1145/2723372.2742786) 的大规模图数据集，包含数亿个顶点。其他实验中涉及的数据集可在论文 [GraphAr: An Efficient Storage Scheme for Graph Data in Data Lakes](https://arxiv.org/abs/2312.09577) 中查阅。\n\n\u003ctable\u003e\n    \u003cthead\u003e\n        \u003ctr\u003e\n            \u003cth\u003eAbbr.\u003c/th\u003e\n            \u003cth\u003eGraph\u003c/th\u003e\n            \u003cth\u003e|V|\u003c/th\u003e\n            \u003cth\u003e|E|\u003c/th\u003e\n        \u003c/tr\u003e\n    \u003c/thead\u003e\n    \u003ctbody\u003e\n        \u003ctr\u003e\n            \u003ctd\u003eG8\u003c/td\u003e\n            \u003ctd\u003eGraph500-28\u003c/td\u003e\n            \u003ctd\u003e268M\u003c/td\u003e\n            \u003ctd\u003e4.29B\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n            \u003ctd\u003eG9\u003c/td\u003e\n            \u003ctd\u003eGraph500-29\u003c/td\u003e\n            \u003ctd\u003e537M\u003c/td\u003e\n            \u003ctd\u003e8.59B\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n            \u003ctd\u003eSF30\u003c/td\u003e\n            \u003ctd\u003eSNB Interactive SF-30\u003c/td\u003e\n            \u003ctd\u003e99.4M\u003c/td\u003e\n            \u003ctd\u003e655M\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n            \u003ctd\u003eSF100\u003c/td\u003e\n            \u003ctd\u003eSNB Interactive SF-100\u003c/td\u003e\n            \u003ctd\u003e318M\u003c/td\u003e\n            \u003ctd\u003e2.15B\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n            \u003ctd\u003eSF300\u003c/td\u003e\n            \u003ctd\u003eSNB Interactive SF-300\u003c/td\u003e\n            \u003ctd\u003e908M\u003c/td\u003e\n            \u003ctd\u003e6.29B\u003c/td\u003e\n        \u003c/tr\u003e\n    \u003c/tbody\u003e\n\u003c/table\u003e\n\n### 存储效率\n\n\u003cimg src=\"docs/images/benchmark_storage.png\" class=\"align-center\" width=\"700\" alt=\"storage consumption\"/\u003e\n\n我们对比了两种基线方法：\n1. **“plain”**：对源节点和目标节点列使用普通编码；\n2. **“plain + offset”**：在 “plain” 方法基础上，对边排序并添加偏移列以标记每个顶点起始边的位置。\n\n结果表明，GraphAr 在存储方面具有显著优势：平均仅需 “plain + offset” 所需存储空间的 **27.3%**，这主要得益于 delta 编码的应用。\n\n### I/O 速度\n\n\u003cimg src=\"docs/images/benchmark_IO_time.png\" class=\"align-center\" width=\"700\" alt=\"I/O time\"/\u003e\n\n图 (a) 显示 GraphAr 明显优于基线方法（CSV），平均性能提升达 **4.9 倍**。图 (b) 中，“Imm”（不可变）和 “Mut”（可变）是 GraphScope 的本地内存存储形式。尽管 GraphAr 的查询时间略高于内存存储方式，这是由于固有的 I/O 开销所致，但它仍显著优于先加载再执行查询的方式，在两个变体下分别提升了 **2.4 倍** 和 **2.5 倍**。这表明 GraphAr 是处理低频查询的有效选择。\n\n### 标签过滤（Label Filtering）\n\n\u003cimg src=\"docs/images/benchmark_label_simple_filter.png\" class=\"align-center\" width=\"700\" alt=\"Simple condition filtering\"/\u003e\n\n**简单条件下的标签过滤性能**\n\n对于每个图，我们分别将每个标签作为目标标签进行过滤实验。GraphAr 持续优于所有基线方法。平均来看，相比 “string” 方法，性能提升了 **14.8 倍**；相比 “binary (plain)” 方法，性能提升了 **8.9 倍**；相比 “binary (RLE)” 方法，性能提升了 **7.4 倍**。\n\n\u003cimg src=\"docs/images/benchmark_label_complex_filter.png\" class=\"align-center\" width=\"700\" alt=\"Complex condition filtering\"/\u003e\n\n**复杂条件下的标签过滤性能**\n\n在每个图中，我们通过 AND 或 OR 组合两个标签作为过滤条件。“基于合并解码”的方法表现最佳，其中 “binary (RLE) + merge” 相比 “binary (RLE)” 方法最高提升了 **60.5 倍**。\n\n## 开发库\n\nGraphAr 提供了一组用于读取、写入和转换文件的库。目前，以下库已经可用，并计划扩展对其他编程语言的支持。\n\n### C++ 库\n\n有关 C++ 库构建的详细信息，请参阅 [GraphAr C++库](./cpp)。\n\n### Spark（Scala）库\n\n有关 Scala 与 Spark 库的详细信息，请参阅 [GraphAr Spark库](./maven-projects/spark)。\n\n### Java (FFI) 库\n\n\n\u003e [!WARNING]\n\u003e Java (FFI) 库已不再更新，最后版本依赖于 C++ 库 v0.12.0。\n\nGraphAr Java 库是通过绑定到 C++ 库（当前版本为v0.12.0）创建的，使用 [Alibaba-FastFFI](https://github.com/alibaba/fastFFI) 进行实现。有关 Java 库构建的详细信息，请参阅 [GraphAr Java库](./maven-projects/java)。\n\n\n### Java 库\n\u003e [!NOTE]\n\u003e Java 库正在开发中.\n\njava 库将由纯java开发，他将会包括下面的模块：\n- **[Java-Info](./maven-projects/info)**：负责从yaml文件中解析Graphinfo（schema）\n- **Java-io-XXX**：负责从不同存储格式读取图形数据（待实现）\n- **Java-Api-XXX**：为图形操作提供高级API（待实现）\n\n### Python（PySpark）库\n\n\u003e [!NOTE] \n\u003e Python 与 PySpark 库正在开发中。\n\nPySpark 库是作为 GraphAr Spark 库的绑定进行开发的。有关 PySpark 库的详细信息，请参阅 [GraphAr PySpark库](./pyspark)。\n\n## 参与本项目\n\n- 请参阅 [贡献指南](https://github.com/apache/incubator-graphar/blob/main/CONTRIBUTING.md)。\n- 提交 [Github Issue](https://github.com/apache/incubator-graphar/issues) 以报告错误或提出功能请求。\n- 在 [开发者邮件列表](mailto:dev@graphar.apache.org)上讨论（[订阅](mailto:dev-subscribe@graphar.apache.org?subject=(send%20this%20email%20to%20subscribe)) / [取消订阅](mailto:dev-unsubscribe@graphar.apache.org?subject=(send%20this%20email%20to%20unsubscribe)) / [归档](https://lists.apache.org/list.html?dev@graphar.apache.org)）。\n- 在 [GitHub Discussion](https://github.com/apache/graphar/discussions/new?category=q-a) 中提出问题。\n\n## 开源协议\n\n**GraphAr** 遵循 [Apache License 2.0](https://github.com/apache/incubator-graphar/blob/main/LICENSE) 开源协议分发。同时请注意，某些依赖的第三方库可能采用了与 GraphAr 不同的开源许可协议。\n\n## 论文\n\n- Xue Li, Weibin Zeng, Zhibin Wang, Diwen Zhu, Jingbo Xu, Wenyuan Yu, Jingren Zhou. GraphAr: An Efficient Storage Scheme for Graph Data in Data Lakes. PVLDB, 18(3): 530 - 543, 2024.\n\n```bibtex\n@article{li2024graphar,\n  author = {Xue Li and Weibin Zeng and Zhibin Wang and Diwen Zhu and Jingbo Xu and Wenyuan Yu and Jingren Zhou},\n  title = {GraphAr: An Efficient Storage Scheme for Graph Data in Data Lakes},\n  journal = {Proceedings of the VLDB Endowment},\n  year = {2024},\n  volume = {18},\n  number = {3},\n  pages = {530--543},\n  publisher = {VLDB Endowment},\n}\n```\n\n论文的源代码、数据和其他相关文档已在[Research 分支](https://github.com/apache/incubator-graphar/tree/research)中提供。\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapache%2Fincubator-graphar","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fapache%2Fincubator-graphar","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapache%2Fincubator-graphar/lists"}