Slater – 专为读密集型图设计的低内存图数据库

Hacker News Top 工具

摘要

Slater 是一款低内存图数据库,专为读密集型工作负载设计。它使用固定的缓存预算从磁盘提供大型图服务,仅需几百 MB 的 RAM 即可查询数亿节点和数十亿边,同时兼容标准 Bolt 协议并支持实时写入。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/07/21 21:40

Hikari-Systems/slater 源代码:https://github.com/Hikari-Systems/slater # Slater CI (https://github.com/Hikari-Systems/slater/actions/workflows/ci.yml) 发布版本 (https://github.com/Hikari-Systems/slater/releases/latest) 当前版本:v0.24.1 — 所有发布版本 (https://github.com/Hikari-Systems/slater/releases)。 > 一句话总结: Slater 服务于那些不适合内存的图——在低至几百 MB 的 RAM 中处理数亿节点和数十亿边——通过标准的 Bolt 协议,任何 neo4j 驱动程序都能直接使用,并同时提供与图相邻的磁盘原生向量搜索,同时还支持实时、持久化的写入,且不牺牲读取性能。常驻内存由你选择的缓存预算决定,而非图的大小。 — 快速导航 | | | | | |:–|:–|:–|:–| | 为什么要有 Slater | 读取与写入 | 你能得到什么 | 特性 | 使用 Docker 运行 | | 工作原理 | 可写层 | 存储后端 | 挂载 | 配置 | | ACL | 健康检查 | 实例操作 | 开发 | | 性能 | 许可证 | 📖 完整手册 | ## 为什么要有 Slater 图数据库将数据存储为事物(节点)以及它们之间的关系(边),并且关系是核心元素。当你需要查询的是连接关系而非行数据时——比如“这个账户的三跳范围内有谁?”、“这个构建背后的完整依赖链是什么?”、“哪些账户共享同一设备、地址和信用卡?”——这些在 SQL 中需要通过递归连接来处理的查询,在图数据库中则能自然地解决。 关于图数据库最常见的抱怨是它们无法扩展到内存无法容纳的数据规模。 许多图数据库(例如 neo4j、Memgraph、FalkorDB 等)会将整个图常驻内存:一个 40 GB 的图需要 40 GB 的内存——每个实例。如果你想要每个区域、每个租户或每个 Pod 都有一个副本?那账单就会成倍增长。而且超过一定大小后,它们根本无法加载:例如 Wikidata 图(9000 万节点 / 15 亿边)需要大约 64–128 GiB 内存,因此内存引擎根本无法打开它。 Slater 解决了这个问题。它从几百 MB 的 RAM 中为同样的 9000 万节点图提供服务,因为它按需从磁盘镜像中分页加载图,而不是常驻内存——这样图的大小和内存开销就解耦了。 Slater 采用了相反的方法。通过 slater-build 工具,你可以离线地将图一次性编译成内容寻址的磁盘镜像;然后任意数量的 Slater 服务器通过 Bolt 协议(因此你现有的 neo4j 驱动程序可以直接使用)为其提供服务,同时仅在内存中保留一个固定的缓存预算。 4 GB 的图和 400 GB 的图消耗相同的内存来提供服务——你可以轻松扩展出廉价、无状态的只读副本,让存储(而非堆内存)来持有图。这使得它非常适合用于 RAG 背后的知识图谱、推荐和身份图谱、依赖关系图——任何你想要廉价且频繁查询的大规模连接数据。磁盘原生的向量搜索紧邻图存在,因此同样的引擎也用作嵌入向量的检索层。 ### 读取与写入 Slater 是一个读写图数据库。你不需要为了更正一个属性、添加一个节点或撤回一条边而重新构建整个镜像——你直接通过 Bolt 协议写入变更,并使其持久化。关键在于,写入操作绝不会影响读取路径。 写入操作在不可变的核心图上累积到一个日志结构合并(LSM)层中:包括一个预写日志和一个内存表,数据会溢出到不可变的增量段中,并通过定期的合并操作折叠回新的核心图。 这带来的好处是: - 未写入的图上的读取成本与之前完全相同。 空的增量表只是一个可预测的分支,而非合并——无论可写层是否开启,读取路径逐字节都完全相同。 - 写入的读取成本与增量表的大小成正比,而非与图的大小成正比。 整个图的查询(如 count(*)、标签和关系类型的边际统计)即使在有写入操作时也仍然是元数据读取——增量表维护自己的计数器,因此即使核心图有 9160 万节点,且有五十万条待处理写入,count(*) 仍然能在几十毫秒内给出答案,而无需触及任何数据块。 - 确认即持久化。 单个写入器将队列清空,只有在 fsync 覆盖写入后才返回 SUCCESS。分批写入成本更低——一次 UNWIND 写入每个批次只提交一次 fsync,而不是每行一次。 - 业务键写入,支持两种语法。 MERGE / MATCH ... SET / DELETE(以及 CREATE / REMOVE、分离删除、关系写入)以节点的标识属性为键——或者等效的 ISO GQL 数据修改语句(INSERT / SET / REMOVE / DELETE),这些语句最终都归结到相同的路径上。可以更正、插入、更新和撤回节点和边,按照你数据原有的方式进行寻址。 可写层是可选的(delta.enabled);关闭后,Slater 仅提供纯不可变核心图,并拒绝写入。详见可写层。 > 关于名称的由来。 Slater 以《Archer》(一部很棒的剧)中的 CIA 特工命名,> 他坚持只用一个名字——“Just… Slater”——也是剧中我最喜欢的角色之一。> 参见角色百科页面 (https://archer.fandom.com/wiki/Slater)。 ### 你能得到什么 - 内存由你的缓存预算决定,而非图的大小——你可以随意扩展任意数量的只读副本;图永远不需要完全装入内存。 - 即插即用的图数据库——支持 Bolt 协议,因此任何标准的 neo4j 驱动程序(JS、Python、Go 等)都能直接使用。它使用 Cypher(以及部分 ISO GQL,包括读写);无需学习新东西。 - 实时、持久化的写入——不可变核心图上的可选 LSM 层:基于业务键的 MERGE / SET / DELETE 操作(节点和边),批量提交并由 fsync 保证持久化,通过合并操作折叠回新的核心图。读取不需要为写入付出代价。 - 通过文件交换实现部署——离线构建一个新的内容哈希,原子性地切换 current 指针,然后所有服务器自动加载新版本。每个数据块都有校验和,因此半复制镜像会被拒绝而非提供。 - 内置向量搜索——磁盘原生近似最近邻(余弦、L2 或点积 KNN)紧邻你的图,适合作为 RAG 流水线背后的检索层,且嵌入向量可以原地写入——添加或更改向量无需离线重建。 - 默认安全锁定——读取和写入权限独立,支持可选的静态加密、TLS Bolt、argon2id 哈希的 ACL,以及只读副本的只读容器根文件系统。 ## 特性 | 特性 | 对你意味着什么 | |—|—| | 受限且可预测的内存 | 常驻内存由你设置的三个缓存预算上限决定——它不会随着图的大小增长;你可以调整性能/内存的权衡,而不必为整个图进行资源配置。jemalloc 分配器在后台进行清除,在大量查询突发后将释放的内存返还给操作系统,因此常驻内存大小会回落到空闲时的基线水平,而不是保持在突发后的高水位。 | | 开箱即用的多租户 | 一台服务器可以托管多个图,并支持按用户分配读取权限——这种多数据库隔离通常只在图数据库的付费/企业版中提供。 | | 静态传输及传输中加密 | 每个数据块进行 XChaCha20-Poly1305 密封(密钥从不写入磁盘),加上可选的 TLS(bolt+s://)。默认符合 GDPR 要求。 | | 小巧、依赖少的安装包 | 基于 distroless glibc 基座的小型 stripped 二进制文件(无 shell/apt)——多架构(amd64/arm64)镜像大小约 22 MB,仅包含服务器的 slater:latest-lite 标签约 12 MB;纯 Rust 实现的 TLS,无需 OpenSSL。拉取即可运行。 | | 专为定期发布构建 | 离线构建图,以不可变方式提供服务,然后原子性地切换新版本,实现零停机——非常适合数据仓库/定期刷新的工作负载。 | | 高负载下的稳健性 | 服务器和离线构建器均使用 #![forbid(unsafe_code)] 编译——引擎中唯一的 unsafe 代码位于经过审计的 jemalloc 分配器 crate 中。核心图不可变,因此读取操作无需加锁,也从不等候写入器;单个写入器在写入路径上序列化变更。无 GC 暂停,无数据竞争。一个糟糕的查询不会导致服务器宕机。 | | 与你的 neo4j 工具兼容 | 支持 Bolt 5.4 / 4.4 / 4.1——可以使用标准 neo4j 驱动程序(JS、Python、Go、Java 等)、cypher-shell 或图浏览器,无需修改。 | | 丰富的 Cypher 查询能力 | 广泛的读取支持:MATCH/WHERE/WITH/UNIONCALL {...} 子查询、70 多个函数及聚合、时间和地理空间值、正则表达式。 | | 实时、持久化写入 | 不可变核心图上的可选单写入器 LSM 层(delta.enabled):基于业务键的 MERGE / SET / DELETE / CREATE / REMOVE 操作(节点和关系)、批量写入 UNWIND(每批一次 fsync),以及 CALL slater.consolidate()——组提交、fsync 持久化,并通过合并折叠回新的核心图。当增量表为空时,读取路径逐字节完全相同。 | | ISO GQL 读写支持 | 通过相同的 Bolt 连接支持 ISO GQL(ISO/IEC 39075)的子集——量化路径、路径限制器、最短路径选择器、标签/类型布尔表达式、FORCAST、可选的 GQL/CYPHER 方言前缀——并且当可写层开启时,GQL 的数据修改语句(INSERT / SET / REMOVE / [DETACH] DELETE)会归结到相同的持久化写入路径上。Cypher 和 GQL,读取和写入,同一个引擎。 | | 向量 + 图在同一个引擎中 | 磁盘原生的 ANN 向量搜索(Vamana + PQ;余弦 / L2 / 点积)用于嵌入向量/RAG,加上图算法(PageRank、BFS、中介中心性、WCC…)——即使有数百万个向量,内存也受限。嵌入向量可写入(类似 FreshDiskANN 的写入梯级):插入/更新/删除一个向量,KNN 立即可见,无需重建基础层即可折叠。 | | 网络存储安全 | 每个文件都有 BLAKE3 内容哈希值,打开时验证;损坏或半复制的镜像会被拒绝而非提供服务。专为 NFS/远程卷设计(无 mmap 隐患)。 | | 可插拔的存储后端 | 从本地文件系统、S3(兼容 S3 的)存储桶 Google Cloud Storage 存储桶提供相同代格式的数据——发布一次,扩展到无状态副本——并可在对象存储前使用可选的本地 SSD 缓存层。参见存储后端。 | 工作空间包含两个二进制文件: | 二进制文件 | 角色 | | — | — | | slater | 在线 Bolt 服务器(容器的 ENTRYPOINT):提供读取服务,并且在 delta.enabled 时提供单写入器持久化写入路径。 | | slater-build | 离线编译器:将原始的 Cypher 转储文件转换为不可变、内容哈希化的代目录。 | Slater 将批量构建服务分开:slater-build 离线完成繁重的工作——接收你的数据并编译成不可变的代——因此冷图永远不需要在服务的热路径上组装。在服务器内部,读取表面支持广泛的 Cypher 子集——模式匹配、WITH/UNION/CALL {...} 子查询、70 多个标量和聚合函数、时间和地理空间值、图算法(algo.*)以及磁盘原生向量 KNN(db.idx.vector.queryNodes)——而可写层的增量覆盖层位于该表面之下,当为空时零成本,因此读取从不承担写入端的开销。你可以通过两种方式更新图:通过 Bolt 实时写入(参见可写层),或者离线构建新的代并原子性地切换 current 指针,运行中的服务器通过其代保护机制(参见代保护)自动获取新版本。 ## 文档 完整的用户手册位于 docs/manual/——这是一个按功能逐一介绍的指南,解释每个能力的含义、存在的原因以及使用方法,并附带针对捆绑示例图的可操作实例。超过本概述的内容请从这里开始。 - 新手? 快速入门 分五步构建并服务一个图。 - 编写查询? 查询函数与表达式过程与算法向量搜索写入数据。 - 构建图? 构建图构建 CLI 参考。 - 运维 Slater? 部署存储配置参考安全性能调优。 ## 使用 Docker 运行 Slater 设计为以 Docker 部署方式运行——这是预期的使用方式。预构建的多架构镜像(linux/amd64 + linux/arm64)发布在 Docker Hub 上的 hikarisystems/slater (https://hub.docker.com/r/hikarisystems/slater),每次发布都会打上 :latest:vX.Y.Z 标签: sh docker pull hikarisystems/slater:latest Docker 命令使用方法、配置和运维指南位于 DOCKERHUB.md(并镜像到 Docker Hub 概览页面)——如果你是部署用途,请从这里开始。 简单来说: sh # 使用离线写入器构建图代: docker run --rm -v slater-data:/data -v "$PWD/dumps:/dumps:ro" \ --entrypoint /app/slater-build hikarisystems/slater:latest \ --input /dumps/people.cypher --graph people --data-dir /data # 通过 Bolt 7687 端口提供服务(只读,除非启用 `delta.enabled`): docker run -d --name slater -p 7687:7687 \ -v slater-data:/data:ro -v "$PWD/acl.json:/config/acl.json:ro" \ hikarisystems/slater:latest 如果要在本地构建镜像(例如用于开发): sh # 构建镜像(两个二进制文件)。 docker compose build # 提供服务(期望在 slater-data 卷或 /data 挂载点下有代目录)。 docker compose up slater # 使用离线写入器构建代(profile `build`): docker compose run --rm builder \ --input /dumps/people.cypher --graph people --data-dir /data 构建阶段安装了 cmakeclanglibclang-dev,用于 rustls 的 aws-lc-rs 后端;git(已在基础镜像中)是 hs-utils git+tag 依赖所必需的,.cargo/config.toml 通过 git CLI 获取此依赖。 以下部分介绍磁盘格式、配置、ACL 以及一个本地(非 Docker)实例操作。 ## 工作原理 slater-build slater (Bolt 服务器) dump.cypher ──────────▶ /data/<generation> ──────────▶ neo4j 驱动程序 (离线,原子操作) MANIFEST.json, *.blk, (bolt / bolt+s) range/*.isam, vector/*.{vamana,pq}, current → * 一个是一个不可变的目录:包含 MANIFEST.json(符号表、索引描述符、可选的加密头部)、列式块文件(node_props.blknode_labels.blkedge_props.blktopology.csr.blkvectors.f32.blk)、范围索引(range/.isam)、阈值以上的 ANN 索引(vector/..{vamana,pq})以及一个 current 文本指针。 * 每个数据块都经过 zstd 压缩并带有 BLAKE3 校验和;使用 --encrypt 时,每个数据块还会使用 XChaCha20-Poly1305 密封(静态 AEAD)。 * 服务器通过重新计算每个文件的哈希值并与清单比对来打开一个代,因此半复制/截断的镜像——即对数据目录(可能是远程/网络存储)的撕裂复制——会被拒绝而非提供服务。 * 读取通过三个有界缓存池进行——一个解压缩块 LRU、一个向量索引池(常驻 PQ 代码 + Vamana 块 LRU)和一个结果缓存。

相似文章

Show HN: HelixDB – 基于对象存储的图数据库

Hacker News Top

HelixDB 是一个用 Rust 构建的图-向量数据库,专为知识图谱和 AI 记忆设计,提供统一平台支持图、向量、键值、文档和关系型数据模型,并配有便于本地和云端部署的工具。

Fluree DB(GitHub 仓库)

TLDR AI

Fluree DB 是一个开源的时间图数据库,具有类似 Git 的分支、集成的向量/文本/地理搜索、细粒度的访问控制,并支持 SPARQL、JSON-LD 和 Open Cypher。它针对 AI 代理记忆进行了优化,在十亿级图上实现了高性能。

G-Long: 图增强内存管理用于高效长期对话代理

arXiv cs.CL

G-Long 提出了一种用于长期对话代理的图增强内存管理框架,利用微调的小型语言模型进行结构化三元组提取和关联检索,在响应生成和内存检索方面取得了最先进的性能,同时降低了计算开销。