跳到内容

内存存储后端

JanusGraph 附带一个内存存储后端,可以通过以下配置使用

storage.backend=inmemory

或者,可以在 Gremlin 控制台中直接打开一个内存中的 JanusGraph 图

graph = JanusGraphFactory.build().set('storage.backend', 'inmemory').open()

内存存储后端没有额外的配置选项。顾名思义,此后端将所有数据保存在内存中,特别是分配给运行 JanusGraph 实例的 Java 虚拟机堆空间中。

关闭图或终止托管 JanusGraph 图的进程将不可逆地从图中删除所有数据。此后端是特定 JanusGraph 图实例的本地后端,不能在多个 JanusGraph 图之间共享。

理想用例

快速测试

内存存储后端最初是为了简化测试(对于那些不需要持久性的测试)和图探索而开发的。自动化测试和临时原型设计仍然是它在 JanusGraph 项目中的主要目的。

生产

最初的仅用于测试的实现经过进一步演进,使用了更紧凑的内存表示,这使得它适用于某些场景下的生产用途,例如 JanusGraph 引擎嵌入到应用程序进程中,或按需动态生成,其中

  • 设置/配置/维护/启动的简易性很重要(只需从分发 jar 运行 JanusGraph,无需管理后端数据库集群等)
  • 由于主机进程意外死亡导致数据丢失是可接受的(后端提供了一种简单的机制来制作快速快照以处理预期的重新启动,并且数据始终可以在 Gremlin/Tinkerpop 级别导出到 GraphSON 等)
  • 图数据的大小使其可以在单个 JVM 进程中托管(即最多几十吉字节,除非您使用专门的 JVM 和硬件)
  • 需要更高的性能,但没有专业知识/资源来调整更复杂的后端。由于其纯内存的特性,内存后端在查询使用简单索引和图修改方面通常比基于磁盘的后端执行更快。但是,它没有专门针对性能进行优化,也不支持高级索引功能。

限制

  • 显然,可伸缩性仅限于单个 JVM 的堆大小,并且不提供透明的故障恢复能力
  • 后端仅提供存储级别锁定,而 JanusGraph 事务通常会更改多个存储(例如,顶点存储和索引存储)。这意味着在数据在并行事务中修改的场景中,应用程序级别应注意避免冲突更新。从高层次来看,这意味着您可以并行修改图的不相关部分,但应避免在并行事务中更改相同的顶点或其边。
  • 一旦提交开始,后端不保证干净的回滚。提交到内存数据结构中间失败的可能性很低,但这种情况可能会发生——例如,当一个大的堆接近饱和且 GC 暂停超过配置的后端超时时。
  • 后端使用的数据布局在某些场景下(有大量添加/删除操作)理论上可能容易出现碎片化,从而减少可以存储在指定大小堆中的有用数据量。后端提供了报告碎片化并在需要时对存储进行碎片整理的简单机制。但是,碎片化程度高到足以成为问题的场景预计很少见,通常根本不需要碎片整理。

替代方案

通常,除了上述用例之外,专门使用 100% 纯内存后端似乎没有太大意义。许多其他受支持的后端,基于成熟的键值数据库,可以进行调整以提供高性能和弹性,以及高级索引功能等(前提是您有资源和专业知识来托管和调整它们,或将它们用作服务)。
但是,有一些内存替代方案,例如(不完全列表,不分先后)

  • BerkeleyJE 后端配置为 je.log.memOnly 设置为 true(应注意避免将其用于连续写入操作的场景,即使数据的有效大小保持不变——连续写入操作可能导致日志不受控制地增长,从而导致 OOM)。后端具有转储/加载功能,并支持压缩。
  • 基于 Aerospike 的后端(不属于 Janugraph,但是一个独立项目)