- 数据库
- 图数据库
- 分布式数据库
- 后端
【免费下载链接】dgraph
high-performance graph database for real-time use cases
本篇指南以 Dgraph 仓库的 CONTRIBUTING.md 为骨架,完整讲解如何从源码搭建 Dgraph 开发环境、编译 dgraph 二进制与本地 Docker 镜像、理解其分层测试体系(unit / integration / integration2 / upgrade / fuzz),并落实提交 PR 时必须遵守的编码规范与许可证要求。读完本文,你将能够独立完成一次从git clone到make test、再到提交合格 PR 的完整开发流程,并对 Dgraph 背后的构建与测试机制有源码级的理解。
快速开始:先认识项目
Dgraph 是一个面向实时场景的高性能图数据库。开始贡献之前,官方建议先完成两件事:
- 阅读官方入门指南,理解 Dgraph 的核心概念(图模型、DQL 查询、GraphQL 集成);
- 完成一次 Dgraph 交互式教程(tour),实际操作一遍查询与变更。
这两步是理解仓库代码(dql/、query/、edgraph/ 等核心包)的认知基础。而本篇接下来聚焦的是仓库内可以直接验证的开发链路:环境搭建 → proto 代码生成 → 编译 → 镜像 → 测试 → 提交规范。
开发环境搭建
前置依赖
根据 CONTRIBUTING.md 的 Prerequisites 章节,参与 Dgraph 开发需要以下工具:
| 依赖 | 用途 | 安装说明 |
|---|---|---|
| Git | 获取与管理源码 | 可能已随系统安装,或通过包管理器安装 |
| Make | 驱动构建与测试流程 | 可能已随系统安装,或通过包管理器安装 |
| Docker + Docker Compose | 集成测试的集群运行环境 | 独立安装,需保证内存资源充足 |
| Go 1.27.0 及以上 | 编译与运行测试 | 从 Go 官方安装包安装 |
| trunk | 代码风格检查(CI 复用) | Dgraph 的 CI 用 trunk 做 lint,本地安装可节省提交返工时间 |
关于 Go 版本,仓库的 go.mod 中声明了go 1.27.0,而依赖检查脚本 t/scripts/check-deps-go.sh 会直接从go.mod解析所需版本并与本机go version比对,版本过低会直接报错。这意味着版本要求以仓库 go.mod 为准,安装后无需手工记忆版本号。
从源码克隆并初始化
git clone <Dgraph 仓库地址> cd ./dgraph make setup # 自动安装工具依赖(gotestsum、ack 等) make install # 构建并安装 dgraph 二进制执行后,源码位于$GOPATH/src/...对应的 Git 仓库中,编译出的二进制则被安装到$GOPATH/bin(若GOBIN已设置则为$GOBIN,见 dgraph/Makefile)。
make setup的实际行为是调用make check-deps AUTO_INSTALL=true(见 Makefile),它会依次运行 t/Makefile 中声明的依赖检查目标:
check-deps-go:解析 go.mod 中的 Go 版本并校验;check-deps-docker:校验 Docker 与 Docker Compose;check-deps-gotestsum:安装/校验测试输出汇总工具 gotestsum;check-deps-ack:安装/校验ack(t/ 测试框架用于按名称定位测试函数);check-deps-cross-compiler:在非 Linux 主机上校验交叉编译工具链;check-deps-protoc:Linux 上校验 protoc 编译器;check-docker-available-memory:检查 Docker 可用内存(低于 8GB 会告警,macOS 上可自动修复)。
这套脚本体系让首次环境搭建基本做到"一条命令完成"。
可选:从源码搭建 Badger
Dgraph 的存储层依赖 Badger(KV 引擎,在仓库中通过github.com/dgraph-io/badger/v4 v4.9.4引入,见 go.mod)。Dgraph 仓库自带 vendor 版本的 Badger,如果只开发 Dgraph,无需单独检出 Badger 仓库;但如果你想同时为 Badger 贡献代码,则需要单独检出:
go get -t -v github.com/dgraph-io/badger执行后 Badger 源码会位于$GOPATH/src/...对应的 Git 仓库中。
Protocol Buffers 与 gRPC 代码生成
Dgraph 使用 Protocol Buffers。如果你修改了.proto文件,就必须重新编译生成对应的 Go 代码。
安装 protoc 编译器
编译 proto 文件需要protoc(版本 3.0.0 及以上)。在 Linux 上也可以通过包管理器快速安装:
sudo apt update && sudo apt install -y protobuf-compiler安装 gogo protobuf 插件
Dgraph 使用 gogo protobuf 体系。要获取 gogo 的 protoc 编译器插件:
go get -u github.com/gogo/protobuf/protoc-gen-gofast注意:从 protos/Makefile 的
check目标可以看到,当前仓库实际还会安装protoc-gen-go@v1.31.0与protoc-gen-go-grpc@v1.3.0,并依赖depcheck.sh校验依赖版本,保证生成代码与 go.mod 中的依赖保持一致。
重新生成 .pb.go
在包含.proto文件的目录下执行:
cd protos make regenerate该目标(protos/Makefile)的完整流程值得展开:
- tidy-deps:执行
go mod tidy -v整理依赖; - copy-protos:从
dgo(客户端 API)与badger模块的 go.mod 路径中拷贝api.proto与badgerpb.proto到临时目录,供protoc的--proto_path引用; - check:运行
depcheck.sh并安装所需插件; - protoc 编译:按
--proto_path组合(含 dgo、badger 的 proto 路径)生成--go_out=pb与--go-grpc_out=pb; - patch-pb:执行 patch_pb.sh 对生成的代码做补丁处理。
在非 Linux 平台上,regenerate会自动封装进 Docker 容器(golang:1.27.0镜像)内执行,避免本机缺少 protoc 的环境差异(见 protos/Makefile)。
编译完成后会生成所需的.pb.go文件(仓库中对应的产物为 protos/pb/pb.pb.go 与 protos/pb/pb_grpc.pb.go)。此外 protos/pb/sensitive.go 中定义了涉及加密等敏感字段的处理逻辑,属于生成代码之上的定制层。
构建 Dgraph 二进制
构建 Dgraph 有两条命令,区别在于产物位置与是否携带版本信息:
make dgraph:在./dgraph/dgraph生成二进制(对应 Makefile 的dgraph目标,实际委托dgraph/Makefile执行);make install:将二进制安装到$GOPATH/bin/dgraph(若未在 PATH 中需手动添加$GOPATH/bin)。
两条命令都会通过-ldflags把版本信息注入二进制(dgraph/Makefile),注入的构建期变量包括:
x.dgraphVersion:版本号(默认取自git describe --always --tags,发布流水线可通过DGRAPH_VERSION覆盖);x.dgraphCodename:代号(默认dgraph);x.gitBranch:当前分支;x.lastCommitSHA:最近提交的短 SHA;x.lastCommitTime:最近提交时间。
这些变量的宿主定义位于 buildvars/buildvars.go(命令行工具为 buildvars/cmd/buildvars/buildvars.go),dgraph version命令输出的正是这些注入值。一个典型的构建与验证过程如下:
$ make install Installing Dgraph... Commit SHA256: 15839b156e9920ca2c4ab718e1e73b6637b8ecec Old SHA256: 596e362ede7466a2569d19ded91241e457e665ada785d05a902af2c6f2cea508 Installed dgraph to /Users/<homedir>/go/bin/dgraph $ dgraph version Dgraph version : v24.0.2-103-g15839b156 Dgraph codename : dgraph Dgraph SHA-256 : 9ce738cd055dfebdef5d68b2a49ea4e062e597799498607dbd1bb618d48861a6 Commit SHA-1 : 15839b156 Commit timestamp : 2025-01-10 17:56:49 -0500 Branch : username/some-branch-that-im-on Go version : go1.22.12 jemalloc enabled : true构建的底层细节
- jemalloc 集成:在 Linux/macOS 上默认启用
jemalloc构建标签(dgraph/Makefile),用于优化内存分配性能。若系统未安装 jemalloc,make会从官方发布页下载 5.3.1 源码并本地编译安装(dgraph/Makefile)。 - 调试构建:设置
BUILD_DEBUG=1会追加-gcflags="all=-N -l"(禁用优化,便于 dlv 调试);设置BUILD_RACE=1会追加-race开启竞态检测。 - fork 友好:
make install特意用go build -o $(INSTALL_TARGET)而非go install,以便BIN变量被重命名(如 fork 出别的二进制名)时仍能正确输出文件名(dgraph/Makefile)。
在非 Linux 机器上构建
非 Linux 平台(主要是 macOS)的构建说明见 t/README.md 与 Makefile:由于 Docker 容器内运行的是 Linux 二进制,make install在 macOS 上会自动额外交叉编译一份Linux 二进制到$GOPATH/linux_$(GOHOSTARCH)/dgraph,并依赖对应架构的交叉编译器(aarch64-unknown-linux-gnu-gcc/x86_64-unknown-linux-gnu-gcc)。Docker Compose 文件通过${LINUX_GOBIN}环境变量自动定位这份二进制,因此 macOS 用户改完代码只需重新make install,无需手动搬运二进制。
构建本地 Docker 镜像
make image-local该命令(Makefile)等价于local-image目标,其流程为:
- 构建 Linux 版 dgraph 二进制(非 Linux 主机走交叉编译);
- 将二进制移入
linux/目录; - 用 contrib/Dockerfile 构建镜像,标签为
dgraph/dgraph:local; - 清理临时目录。
构建完成后,你就可以在本地 Docker 环境中直接使用该镜像测试改动,例如配合 dgraph/docker-compose.yml 拉起集群。
如果你需要发布带版本号的镜像,可使用make docker-image(标签为dgraph/dgraph:$(DGRAPH_VERSION),默认local),或make docker-image-standalone一并构建 standalone 变体(依赖 contrib/standalone 的 Makefile,用于无外置依赖的单机部署镜像)。
测试:Dgraph 的分层测试体系
Dgraph 拥有"复杂精细"(原文措辞)的测试框架与广泛的覆盖率:仓库内包含超过 200 个测试文件、2000+ 个测试/基准函数(TESTING.md)。完整测试跑一遍可能需要数小时,因此仓库在标准 Go 测试之上自研了一个 Go 编写的测试运行器 t/t.go,提供比标准框架更强的控制力与灵活性。
常用测试命令
# 首次使用:安装工具依赖 make setup # 默认测试(约 30 分钟):integration 套件 + integration2 make test # 跑完仓库内所有测试 make test-all # 按类型运行 make test-unit # 纯单元测试——无需 Docker、无构建标签 make test-integration # 通过 t/ 运行器 + Docker 的集成测试 make test-integration-heavy # 所有重型测试:systest-heavy + ldbc + load make test-integration2 # 基于 dgraphtest 的 Integration2 测试 make test-upgrade # 升级测试 # 通过变量精细控制 make test TAGS=integration2 PKG=systest/vector make test SUITE=all # 运行 t/ 运行器的全部套件 make test TIMEOUT=90m # 覆盖单包超时(默认 30m)运行make help可查看全部可用目标与变量。完整的测试指南见仓库根目录的 TESTING.md。
make test 的控制变量
结合 Makefile 与make help输出的说明,make test支持以下变量(优先级:TAGS > FUZZ > SUITE > 默认值):
| 变量 | 作用 | 示例 |
|---|---|---|
SUITE | 选择 t/ 运行器的测试套件 | make test SUITE=integration |
TAGS | Go 构建标签,绕过 t/ 运行器 | make test TAGS=integration2 |
PKG | 限定具体包 | make test PKG=systest/export |
TEST | 运行指定测试函数 | make test TEST=TestGQLSchema |
TIMEOUT | 单包测试超时(默认 30m) | make test TIMEOUT=90m |
FUZZ | 启用 fuzz 测试 | make test FUZZ=1 |
FUZZTIME | 每个包的 fuzz 时长(默认 300s) | make test FUZZ=1 FUZZTIME=60s |
不传任何变量时,make test默认先跑 t/ 运行器的integration套件,再跑带integration2标签的 Go 测试。
测试类型与构建标签
Dgraph 用 Go 构建标签把成本较高、依赖集群的测试从默认的go test ./...中隔离出去(TESTING.md):
| 类型 | 构建标签 | 说明 | 示例文件 |
|---|---|---|---|
| 单元测试 | 无 | 单函数/组件隔离测试,无需集群,速度快 | dql/dql_test.go、types/value_test.go、schema/parse_test.go |
| 集成测试 | //go:build integration | 组件交互与全系统工作流,需要 Docker 集群 | acl/acl_test.go、worker/worker_test.go、query/query0_test.go |
| Upgrade 测试 | //go:build upgrade | 跨版本升级与迁移场景 | acl/upgrade_test.go、worker/upgrade_test.go |
| 基准测试 | 函数名Benchmark前缀 | 性能测试与优化 | query/benchmark_test.go、dql/bench_test.go |
| Fuzz 测试 | -fuzz=Fuzz | 随机输入探测解析器崩溃 | dql/parser_fuzz_test.go |
其中集成、升级、基准测试需要运行中的 Dgraph 集群(Docker),分为两类驱动方式:t/ 运行器驱动,以及dgraphtest包(通过 Docker Go client 对本地集群做编程式控制)。新测试优先使用dgraphtest(集群管理)与dgraphapi(客户端操作),testutil仅保留向后兼容(TESTING.md)。
t/ 运行器详解
测试框架的入口是 t/t.go,构建后得到t可执行文件。它的关键设计参数包括:默认拉起 3 个 Zero 节点与 6 个 Alpha 节点(NumZeroNodes/NumAlphaNodes,t/t.go),并通过 Docker Compose 管理集群生命周期。常用参数如下:
| 参数 | 作用 |
|---|---|
--suite=X | 选择套件:all、ldbc、load、unit、integration、systest、systest-baseline、systest-heavy、vector、core,可逗号组合 |
--pkg=X | 只运行指定包,可逗号多选 |
--test=X | 只运行指定测试函数(借助 ack 定位) |
--timeout=X | 单包超时(如 60m、2h),默认 30m,--race下为 180m |
-j=N | 并发创建多少个集群(默认 1,资源有限时勿调高) |
--keep | 测试结束后保留集群容器,便于故障分析 |
-r | 清理所有测试容器 |
--prefix=X | 复用已存在的集群前缀,不再新起集群 |
--dry | 仅列出将要执行的包,不真正运行 |
--skip-slow | 跳过已知的慢包 |
各套件的内容划分(详见 TESTING.md):unit是纯单元测试;integration是默认套件(除重型外的全部集成测试);core聚焦查询、变更、schema、GraphQL e2e、ACL、TLS、worker;systest为系统级集成测试(含 baseline 与 heavy);vector面向向量索引与 HNSW 相似度检索;ldbc是 LDBC 基准查询套件;load覆盖 21million、1million、bulk_live、bgindex 等重型数据加载场景;all则是 t/ 运行器内的全部包。
Docker Compose 发现机制:运行器先在测试包目录内寻找docker-compose.yml(例如 systest/export/docker-compose.yml),找不到则逐级向上,最终回退到仓库根级默认配置 dgraph/docker-compose.yml。因此需要特殊集群拓扑的测试,应在自己的测试目录内自带 compose 文件。
测试写作规范(摘要)
如果为改动补充测试,仓库约定如下(详见 TESTING.md):
- 命名:函数以
Test开头、camelCase 且描述性(如TestVectorIndexRebuilding);文件名以_test.go结尾并匹配源文件(schema.go→schema_test.go); - 表驱动测试:一个测试函数内用结构体切片覆盖多个用例,并用
t.Run建立子测试,失败信息清晰; - 断言:默认使用
require.*(失败立即终止),仅在极少数场景用assert.*; - 资源清理:用
defer+t.Cleanup保证失败时也释放集群与客户端连接; - 辅助函数:标记
t.Helper(),让失败定位到真实调用行; - 禁止反模式:不用
time.Sleep做同步(改用轮询/显式等待),不共享可变全局状态,不依赖测试执行顺序,不忽略错误返回值; - 并行化:
t.Parallel()仅用于不共享资源的测试,集成测试与改全局状态的测试禁用; - 共享集群:用
testify/suite(SetupSuite/SetupTest/TearDownTest等钩子),同一套测试方法可同时跑integration与upgrade两种模式,典型示例见 acl/integration_test.go 与 systest/plugin 的集成+升级双套件。
提交贡献的规范
基本原则
在多年构建大规模可扩展系统的经验中,Dgraph 团队将"尽可能追求简单"视为构建健壮系统的唯一途径——无论是设计、编码,还是重写一个昨天才辛苦完成、今天看来可以更简洁的模块。据此,贡献 PR 时需要遵循:
- 欢迎 Pull Request,前提是愿意付出努力满足指南。Fork 仓库后,请针对
main分支创建 PR,并仔细遵循 PR 模板中的说明; - 做好准备在官方公开文档中记录你的新增/变更(如适用);
- 追求清晰、易读、可维护的代码;
- 功能采用简单、最小化的实现方式,与 Go 的哲学一致;
- 新功能必须附带通过的单元测试,适当时还要有集成测试;
- 重构现有代码(提升性能、可读性或可测试性)优先于新增功能;
- 不要向当前用不到的模块添加函数,除非它明确服务于已规划的功能;
- 不要交付半成品功能——那种需要大幅改动才能完整工作的功能;
- 像躲避癌症一样避免技术债务;
- 离开时让代码比你进入时更干净。
代码风格
- 遵循 Go Code Review 注释规范;
- 提交前至少用
go fmt格式化代码;理想情况下使用trunk,因为 CI 会对代码运行trunk检查; - 看到任何明显违反风格指南的代码,可直接修复并提交 PR,无需请求许可;
- 避免不必要的垂直留白,用判断力或参考 code review 意见;
- 代码与注释换行宽度不超过 120 字符,除非这样做会降低可读性。
许可证头
每个新源文件必须以许可证头开头。Dgraph、Badger 以及 Dgraph 客户端(dgo、dgraph-js、pydgraph、dgraph4j)大部分采用 Apache 2.0 许可证:
/* * SPDX-FileCopyrightText: © 2017-2026 Istari Digital, Inc. * SPDX-License-Identifier: Apache-2.0 */仓库内几乎所有 Go 源文件(如 Makefile、t/t.go)都携带了同样的 SPDX 头,新增文件照此办理即可。值得注意的是,Dgraph 的许可证是混合的:dgraph version输出明确写着 "Licensed variously under the Apache Public License 2.0 and Dgraph Community License"(见 LICENSE.txt),社区版二进制与商业版(Enterprise)在核心模块许可上存在差异,贡献前应留意该条款。
签名提交(Signed Commits)
签名提交有助于验证贡献者的真实性。Dgraph 使用签名提交并优先推荐(但不强制)——对于打算长期、规律性贡献的开发者,这是推荐的一步。可按 GPG 签名提交的标准流程生成并配置 GPG 密钥,然后在git commit -S时启用签名。
结语
从git clone、make setup、make install构建出带版本信息的二进制,到make image-local产出本地 Docker 镜像,再到用 t/ 运行器与 Go 构建标签驱动分层测试,最后以规范的代码风格、SPDX 许可证头与签名提交交付 PR——这条完整的开发链路既是 Dgraph 仓库 CONTRIBUTING.md 的文档骨架,也被 Makefile、dgraph/Makefile、protos/Makefile、t/t.go 与 TESTING.md 等源码与配置文件逐一印证。对于希望深入参与 Dgraph 开发的工程师而言,掌握这条链路不仅是贡献的门槛,也是理解一个大型 Go 图数据库如何构建、测试与演进的绝佳入口。
- 数据库
- 图数据库
- 分布式数据库
- 后端
【免费下载链接】dgraph
high-performance graph database for real-time use cases
相关推荐
Thumbor 源码开发与贡献指南:环境搭建、测试运行与代码规范全解析
Thumbor 源码开发与贡献指南:环境搭建、测试运行与代码规范全解析 Thumbor 是 globo.com 开源的智能图片缩略图服务(项目核心代码见 thu
后端图像处理计算机视觉date-fns 贡献指南全解析:从环境搭建、测试体系到代码风格与文档规范
date fns 贡献指南全解析:从环境搭建、测试体系到代码风格与文档规范 date fns 是一套面向浏览器与 Node.js 的现代 JavaScript
前端后端Instructor 贡献指南:环境搭建、代码规范、测试与发布流程全解析
Instructor 贡献指南:环境搭建、代码规范、测试与发布流程全解析 本指南是 Instructor(面向 LLM 的 Pydantic 结构化输出库)的完
网页爬虫后端AI 应用
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考