NebulaGraph 介绍与服务器 Docker 部署
整理时间:2026-09-21 | 落地版本:开源社区版 3.8.0(nGQL)
一、NebulaGraph 是什么
国产开源的分布式图数据库,C++ 编写,shared-nothing 架构,专为「关系密集 + 超大规模」场景设计。官方口径可存千亿点、万亿边,毫秒级多跳查询。
三个核心设计取舍
| 设计 | 含义 |
|---|---|
| 存储与计算分离 | 查询层无状态,挂掉不影响数据;存储层用本地盘 + Raft 副本,靠加机器扩容 |
| 图原生存储 | 不是关系库上加一层图接口,多跳查询无需多层 JOIN |
| nGQL 查询语言 | GO 语法贴近 SQL 工程师直觉,兼容 openCypher 子集 |
物理架构(三类服务)
客户端 ──9669──> graphd(查询层,无状态,可多副本)
│
├──9559──> metad(元数据,Raft 高可用)
└──9779──> storaged(数据存储,Raft 副本)- graphd:唯一对外入口,负责解析 nGQL、生成执行计划。无状态,可随意增减。
- metad:存 schema、分区分布、集群拓扑。
- storaged:真正存点和边,数据按分区打散。
数据模型要点
- 点(Vertex)= VID + 一个或多个 Tag。Tag 相当于「类型 + 属性组」,一个点可以同时是
company和exhibitor,比 Neo4j 的单 label 更灵活。 - 边(Edge)有方向,也可以带属性。关系本身携带的信息(如参展年份、展位号)必须放在边上,不要建成独立实体——这是最常见的建模错误。
- VID 必须全局唯一,用业务主键(统一社会信用代码、展会编号),不要用自增数字。
二、版本现状(选型必读,最大的坑)
| 开源社区版 | 企业版 / 云版 | |
|---|---|---|
| 当前版本 | 3.8.0(2024-05 后内核未再发版) | Enterprise v5.3 |
| 查询语言 | nGQL + openCypher 子集 | ISO-GQL |
| 向量检索 | 无 | v5.1 起原生支持 |
| 图 + 向量 + 全文混合检索 | 需外接向量库 | v5.2 起支持 |
| 内置图算法 | 需自行实现 | 中心性 / 社区发现 / 链路预测等 |
| 授权 | Apache 2.0 | 商业授权 |
关键结论:
- 开源线没有 4.x / 5.x,能下载到的就是 3.8.0。
- 企业版是另一套语言(GQL),从开源迁企业版是换语言,不是升版本。
- 开源版没有向量检索、没有内置图算法,这两块要外接(向量库用 Milvus/ES,图算法用 NetworkX)。
三、服务器 Docker 部署
3.1 仓库与分支(易错点)
仓库:https://github.com/vesoft-inc/nebula-docker-compose
# 正确分支是 release-3.8;README 表格里的 v3.8.0 是 tag,不是分支名
git clone -b release-3.8 https://github.com/vesoft-inc/nebula-docker-compose.git
cd nebula-docker-compose不要用
master分支。 它已与release-3.8分叉:master 用nightly镜像、多了data-init权限初始化服务、服务以user: "10001:10001"运行。生产要锁版本,用release-3.8(镜像v3.8.0)。
3.2 两个 compose 文件怎么选
| 文件 | 容器数 | 构成 | 建议 |
|---|---|---|---|
docker-compose-lite.yaml | 3 | metad0 / storaged0 / graphd | ✅ 单机样板用这个 |
docker-compose.yaml | 10 | metad0-2 + storaged0-2 + graphd/graphd1/graphd2 + console | 仅演示集群拓扑时用 |
镜像完全相同,都是 vesoft/nebula-{metad,storaged,graphd}:v3.8.0,差异只在副本数量和多出的 console 服务。
# 单机部署
docker compose -f docker-compose-lite.yaml up -d
# 查看状态
docker compose -f docker-compose-lite.yaml ps3.3 资源需求
| 模式 | 空载内存 | 建议配置 |
|---|---|---|
| lite(3 容器) | ≈ 1.2 GB | 2 核 / 4–8 GB / 20 GB 盘 |
| 完整版(10 容器) | ≈ 3.5 GB | 4 核 / 16 GB / 50 GB 盘 |
进程空载占用参考:metad 约 150–250 MB,storaged 约 300–600 MB(读缓存是大头),graphd 约 300–500 MB。
单机跑完整版的「3 副本」没有高可用意义——物理机一挂全挂,只是拓扑图好看。
3.4 端口说明
| 端口 | 属于 | 作用 | 项目要用吗 |
|---|---|---|---|
| 9669 | graphd | nGQL 查询 / SDK 连接 | ✅ 唯一必须 |
| 19669 | graphd | HTTP 状态与指标 /status /stats | 可选,健康检查 |
| 9559 | metad | meta 内部 RPC | ❌ 集群内部 |
| 9779 | storaged | storage 内部 RPC | ❌ 集群内部 |
| 19559 / 19779 | metad / storaged | 内部 HTTP 状态 | ❌ 不用 |
| 19560 / 19670 / 19780 | 全部 | 内部 HTTP/2 通信 | ❌ 用不到 |
项目接入只需 9669。 graphd 无状态,多副本时连任意一个结果一致。
端口映射差异:
- lite:9559 / 19559 / 9779 / 19779 / 9669 / 19669 全部固定映射到宿主机。
- 完整版:只有
graphd的9669:9669固定,其余是随机端口(32768+)。
⚠️ 安全提醒:lite 把 9559 / 9779 也发布到
0.0.0.0,而 NebulaGraph 对 metad / storaged 端口不做鉴权。若有公网 IP,这三个端口等于对全网敞开。上线前改为只留 9669:metad0: ports: - 9559 # 只写容器端口,宿主机不再暴露,容器间仍互通 storaged0: ports: - 9779
四、部署后的关键一步:ADD HOSTS
lite 版不会自动注册 storage 节点,必须手动执行一次,否则 storaged 未注册、建图空间和写数据全部失败。
官方文档「自 3.1.0 起自动执行 ADD HOSTS」这条只对完整版生效——因为完整版里有 console 容器专门做这件事,lite 版没有。
连入控制台
3.x 起 nebula-console 已从内核镜像拆出,graphd 镜像内不含该二进制,所以不能 docker exec 进 graphd 执行。正确做法是临时起一个 console 容器:
# 网络名按实际容器网络填,可用 docker network ls 查看
docker run --rm -ti --network nebula-docker-compose-380_nebula-net \
vesoft/nebula-console:v3.8.0 -u root -p nebula -addr graphd -port 9669镜像 tag 拉不到时改用
v3.6.0,这是 release-3.8 的 compose 里锁的版本,必然存在。
进入后执行:
ADD HOSTS "storaged0":9779;
SHOW HOSTS;storaged0 / 9779 显示 ONLINE 才算部署完成。
五、建图空间与 Schema
CREATE SPACE expo(vid_type=FIXED_STRING(64), partition_num=10, replica_factor=1);
-- CREATE SPACE 后需等十几秒才能 USE,立即执行会报 space not found
USE expo;
CREATE TAG company(name string, credit_code string, city string);
CREATE TAG exhibition(name string, start_date date);
CREATE TAG venue(name string, city string);
CREATE EDGE exhibits(since int, booth string); -- 关系属性放在边上
CREATE EDGE held_at();
CREATE EDGE belongs_to();
-- 从业务主键找不到 VID 时,必须先建索引再 LOOKUP
CREATE TAG INDEX idx_company_name ON company(name(64));
REBUILD TAG INDEX idx_company_name; -- 异步,用 SHOW JOB 确认完成
SUBMIT JOB STATS; -- 刷新统计信息两个硬约束:
replica_factor在 lite 下必须写 1(只有 1 个 storaged,写 3 找不到副本直接失败)。完整版有 3 个 storaged 才可写 3。partition_num建库后永久不可改,3.x 只能重建 Space。数据量不大时设 1~10 够用,别照抄 100。
六、数据导入
| 数据量 | 用什么 |
|---|---|
| 千条以内 | 直接 INSERT VERTEX / INSERT EDGE |
| 十万~千万 | nebula-importer(CSV + YAML 映射,带并发和错误容忍) |
| 亿级以上 | Spark Connector / Flink Connector |
INSERT VERTEX company(name, credit_code) VALUES "91310000XXX":("某科技公司","91310000XXX");
INSERT EDGE exhibits(since, booth) VALUES "91310000XXX"->"EXPO2026":(2024,"A12");写入务必批量提交(每批 2000~5000 条)+ 多线程。
常用查询
-- 多跳:某展会的参展商,都属于哪些行业
GO 1 STEPS FROM "EXPO2026" OVER exhibits REVERSELY YIELD dst(edge) AS cid
| GO 1 STEPS FROM $-.cid OVER belongs_to YIELD dst(edge) AS industry;
-- openCypher 风格
MATCH (c:company)-[e:exhibits]->(x:exhibition) WHERE x.name == "2026 国际会展"
RETURN c.name, e.booth, e.since;七、Web 可视化界面:NebulaGraph Studio
两种部署模式都不含 Web 界面。 完整版里的 console 服务看名字像控制台,实际是:
console:
image: docker.io/vesoft/nebula-console:v3.6.0
entrypoint: ""
command: sh -c '循环执行 ADD HOSTS ... && tail -f /dev/null'它启动时执行一次 ADD HOSTS 然后挂起,是 CLI 引导容器,且没有 ports 段,不暴露任何端口。
真正的界面是 NebulaGraph Studio,需单独部署,配 3.8.0 的版本是 3.10.0:
docker run -d --name nebula-studio --restart=always \
--network nebula-docker-compose-380_nebula-net \
-p 7001:7001 \
vesoft/nebula-graph-studio:v3.10.0访问 http://<服务器IP>:7001,Config Server 填 Host graphd / Port 9669 / 用户 root。
最易翻车点:Studio 自己也是容器,Host 填
127.0.0.1指的是 Studio 自己,连不上。要么加入 nebula 网络用服务名graphd,要么填服务器局域网 IP。启动前先ss -lntp | grep 7001确认端口没被占。
Studio 能做的四件事:执行 nGQL、可视化建 Schema、导入 CSV、点开节点按关系展开子图(查脏数据最直观)。
八、Python SDK 接入
from nebula3.gclient.net import ConnectionPool
from nebula3.Config import Config
config = Config()
config.max_connection_pool_size = 10
pool = ConnectionPool()
ok = pool.init_servers([("你的服务器IP", 9669)], config)
session = pool.get_session("root", "nebula")
resp = session.execute("USE expo; GO 1 STEPS FROM \"EXPO2026\" OVER exhibits YIELD dst(edge);")
print(resp.rows())
session.release()安装:pip install nebula3-python
对接 LLM 时,LangChain / LlamaIndex 都有官方 NebulaGraph 图存储适配(llama-index-graph-stores-nebula)。
九、运维命令
# 启停
docker compose -f docker-compose-lite.yaml up -d
docker compose -f docker-compose-lite.yaml down # 保留数据
docker compose -f docker-compose-lite.yaml down -v # 连数据一起删,慎用
# 看日志
docker compose -f docker-compose-lite.yaml logs -f storaged0
# 看资源占用
docker stats目录结构:数据在 compose 目录下的 ./data/meta0、./data/storage0;日志在 ./logs。
十、坑清单(部署前必读)
- 分支写
release-3.8,不是 README 表格里的v3.8.0(那是 tag);别用master。 - lite 版必须手动
ADD HOSTS,否则 storaged 未注册,写数据全失败。 - graphd 镜像里没有 nebula-console 二进制,连接要用临时 console 容器或用 SDK。
- lite 建 Space 必须
replica_factor=1。 partition_num建库后不可改,只能重建 Space。CREATE SPACE后要等十几秒才能USE。- 不建索引 = 全表扫描,
LOOKUP慢十有八九是这个原因。 REBUILD INDEX是异步的,建完立刻查可能查不到,用SHOW JOB确认。- 超点是性能杀手:某点挂了 50 万条边,一跳查询就拖慢整个集群;模型层面要拆(如加「年度」中间节点)。
- VID 设计错用自增数字,后期无法与业务数据对齐;VID 为空的行会被静默丢弃。
.env里TZ=UTC,日志时间差 8 小时,建议改成Asia/Shanghai。./logs默认不切割,跑久了能把盘写满,上线前要处理。- Studio 的 Host 不能填
127.0.0.1,要填容器服务名或局域网 IP。 - 别照企业版文档写开源版语句——企业版 v5 是 GQL,语法不通用。
十一、什么时候不该选它
如果只是几千个点、做简单分类检索,或者核心需求是语义相似度而不是关系推理,那关系库 + 向量库就够了。
图数据库的价值开关是:你的问题里有「几跳关系」和「路径」——比如「这家企业通过哪些展会接触过哪些行业」「某环节异常向上游传导影响哪些供应商」。没有这类问题,上图谱是给自己加运维负担。
十二、GraphRAG 组合模式
图数据库与向量库不是二选一,标准做法是:
- 向量检索定位相关实体
- 图上多跳取关联子图
- 子图 + 原文一起喂给大模型
比纯向量 RAG 强的地方是可解释:答案能沿着路径讲清楚「为什么」。
示例分工:RagFlow 存原文与向量,负责「文本在哪」;NebulaGraph 存实体关系,负责「关系是什么」;Postgres 存业务数据。三者用业务主键关联(企业用统一社会信用代码),节点带
doc_ref字段实现溯源跳转。