跳到内容

删除

警告

索引删除是一个由多个步骤组成的手动过程。必须仔细按正确顺序执行这些步骤,以避免索引不一致。

概述

索引删除是一个多阶段过程。在第一阶段,一个 JanusGraph 实例通过将其状态设置为 DISABLED 来停用索引。此时,JanusGraph 停止使用该索引来回答查询并停止增量更新该索引。存储后端中与索引相关的数据仍然存在但被忽略。

第二阶段取决于索引是混合索引还是复合索引。所有复合索引都可以通过 JanusGraph 删除。与重新索引一样,删除可以通过 MapReduce 或 JanusGraphManagement 完成。但是,并非所有混合索引后端都允许自动删除。JanusGraph 未提供自动删除机制的索引后端(目前是 Lucene 和 Solr)必须在索引后端中手动删除。对于受支持的混合索引后端,删除过程类似于复合索引删除,不同之处在于 MapReduce 和 JanusGraphManagement 中的多线程都不是必需的。

丢弃索引会删除与索引关联的所有内容,除了其模式定义和 DISCARDED 状态。删除索引的此模式存根是第三步。

准备索引删除

如果索引当前已启用,则应首先禁用它。这是通过 ManagementSystem 完成的。

mgmt = graph.openManagement()
rindex = mgmt.getRelationIndex(mgmt.getRelationType("battled"), "battlesByTime")
mgmt.updateIndex(rindex, SchemaAction.DISABLE_INDEX).get()
gindex = mgmt.getGraphIndex("byName")
mgmt.updateIndex(gindex, SchemaAction.DISABLE_INDEX).get()
mgmt.commit()

一旦索引上所有键的状态更改为 DISABLED,索引就可以被删除了。ManagementSystem 中的一个实用程序可以自动化等待 DISABLED 步骤。

ManagementSystem.awaitGraphIndexStatus(graph, 'byName').status(SchemaStatus.DISABLED).call()

在复合索引被 DISABLED 后,可以选择两种执行框架进行删除:

  • MapReduce
  • ManagementSystem

MapReduce 上的索引删除支持大型、水平分布的数据库。ManagementSystem 上的索引删除会生成单机 OLAP 作业。这旨在方便和快速地处理那些足够小以至于一台机器可以处理的数据库。

索引删除需要:

  • 索引名称(字符串——用户在构建新索引时提供给 JanusGraph)
  • 索引类型(字符串——构建以顶点为中心的索引的边标签或属性键的名称)。这仅适用于以顶点为中心的索引——全局图索引留空。

在 MapReduce 上执行索引删除作业

信息

此方法适用于以下类型的索引:

  • 所有复合索引

与重新索引一样,在 MapReduce 上生成和运行索引删除作业的推荐方法是通过 MapReduceIndexManagement 类。以下是使用此类运行索引删除作业的步骤概述:

  • 打开一个 JanusGraph 实例
  • 如果索引尚未禁用,请通过 JanusGraphManagement 禁用它
  • 将图实例传递给 MapReduceIndexManagement 的构造函数
  • 调用 updateIndex(<index>, SchemaAction.DISCARD_INDEX)

带注释的代码示例将在下一小节中介绍。

MapReduce 示例

import org.janusgraph.graphdb.database.management.ManagementSystem

// Load the "Graph of the Gods" sample data
graph = JanusGraphFactory.open('conf/janusgraph-cql-es.properties')
g = graph.traversal()
GraphOfTheGodsFactory.load(graph)

g.V().has('name', 'jupiter')

// Disable the "name" composite index
m = graph.openManagement()
m.updateIndex(m.getGraphIndex('name'), SchemaAction.DISABLE_INDEX).get()
m.commit()
graph.tx().commit()

// Block until the SchemaStatus transitions from ENABLED to DISABLED
ManagementSystem.awaitGraphIndexStatus(graph, 'name').status(SchemaStatus.DISABLED).call()

// Delete the indexed data using MapReduceIndexJobs
m = graph.openManagement()
mr = new MapReduceIndexManagement(graph)
future = mr.updateIndex(m.getGraphIndex('name'), SchemaAction.DISCARD_INDEX)
m.commit()
graph.tx().commit()
future.get()

// Block until the SchemaStatus transitions from DISABLED to DISCARDED
ManagementSystem.awaitGraphIndexStatus(graph, 'name').status(SchemaStatus.DISCARDED).call()

// Index still shows up in management interface as DISCARDED -- it can now be dropped entirely
m = graph.openManagement()
m.updateIndex(m.getGraphIndex('name'), SchemaAction.DROP_INDEX).get()
m.commit()

// JanusGraph should issue a warning about this query requiring a full scan
g.V().has('name', 'jupiter')

在 ManagementSystem 上执行索引删除作业

信息

此方法适用于以下类型的索引:

  • 所有复合索引
  • 混合索引(仅限 Elasticsearch)

要在 ManagementSystem 上运行索引删除作业,请使用 SchemaAction.DISCARD_INDEX 参数调用 ManagementSystem.updateIndex。例如:

m = graph.openManagement()
m.updateIndex(m.getGraphIndex('indexName'), SchemaAction.DISCARD_INDEX).get()
m.commit()

与重新索引类似,ManagementSystem 使用本地线程池并发执行索引删除作业。并发级别等于可用处理器数量。如果要更改默认并发级别,可以添加如下参数:

// Use only one thread to execute index removal job
m.updateIndex(m.getGraphIndex('indexName'), SchemaAction.DISCARD_INDEX, 1).get()

ManagementSystem 示例

以下将一些索引的示例数据加载到由 BerkeleyDB 支持的 JanusGraph 数据库中,然后通过 ManagementSystem 禁用并删除索引。

import org.janusgraph.graphdb.database.management.ManagementSystem

// Load the "Graph of the Gods" sample data
graph = JanusGraphFactory.open('conf/janusgraph-cql-es.properties')
g = graph.traversal()
GraphOfTheGodsFactory.load(graph)

g.V().has('name', 'jupiter')

// Disable the "name" composite index
m = graph.openManagement()
m.updateIndex(m.getGraphIndex('name'), SchemaAction.DISABLE_INDEX).get()
m.commit()
graph.tx().commit()

// Block until the SchemaStatus transitions from ENABLED to DISABLED
ManagementSystem.awaitGraphIndexStatus(graph, 'name').status(SchemaStatus.DISABLED).call()

// Delete the index using JanusGraphManagement
m = graph.openManagement()
future = m.updateIndex(m.getGraphIndex('name'), SchemaAction.DISCARD_INDEX)
m.commit()
graph.tx().commit()
future.get()

// Block until the SchemaStatus transitions from DISABLED to DISCARDED
ManagementSystem.awaitGraphIndexStatus(graph, 'name').status(SchemaStatus.DISCARDED).call()

// Index still shows up in management interface as DISCARDED -- it can now be dropped entirely
m = graph.openManagement()
m.updateIndex(m.getGraphIndex('name'), SchemaAction.DROP_INDEX).get()
m.commit()

// JanusGraph should issue a warning about this query requiring a full scan
g.V().has('name', 'jupiter')

为混合索引执行手动索引删除

信息

此方法适用于以下类型的索引:

  • 无法由 JanusGraph 自动删除的混合索引

如果索引后端不支持自动删除,则在尝试执行 DISCARD_INDEX 时会收到异常。目前,这适用于除 Elasticsearch 之外的所有混合索引。对于这些索引后端,必须在索引后端中手动删除索引,而无需 JanusGraph 的帮助。为了通知 JanusGraph 索引已被手动删除,可以通过执行 MARK_DISCARDED 手动触发转换为 DISCARDED 状态。

m = graph.openManagement()
m.updateIndex(m.getGraphIndex('indexName'), SchemaAction.MARK_DISCARDED).get()
m.commit()

警告

此操作除了覆盖索引的状态外,不执行任何操作。索引后端中存储的任何数据仍将存在。

建议在实际接触后端并删除数据之前执行此步骤。这样,可以保证没有实例会并发地重新启用索引。一旦索引进入 DISCARDED 状态,所有索引数据都可以安全删除。

手动混合索引删除示例

import org.janusgraph.graphdb.database.management.ManagementSystem

// Load the "Graph of the Gods" sample data
graph = JanusGraphFactory.open('conf/janusgraph-cql-es.properties')
g = graph.traversal()
GraphOfTheGodsFactory.load(graph)

g.V().has("name", "jupiter")

// Disable the "name" composite index
m = graph.openManagement()
m.updateIndex(m.getGraphIndex("name"), SchemaAction.DISABLE_INDEX).get()
m.commit()
graph.tx().commit()

// Block until the SchemaStatus transitions from ENABLED to DISABLED
ManagementSystem.awaitGraphIndexStatus(graph, "name").status(SchemaStatus.DISABLED).call()

// Since JanusGraph is not capable of removing the index, we have to set the state manually.
m = graph.openManagement()
future = m.updateIndex(m.getGraphIndex("name"), SchemaAction.MARK_DISCARDED)
m.commit()
graph.tx().commit()
future.get()

// Block until the SchemaStatus transitions from DISABLED to DISCARDED
ManagementSystem.awaitGraphIndexStatus(graph, "name").status(SchemaStatus.DISCARDED).call()

/*
 * At this point, the index is marked as DISCARDED,
 * so it is ensured that no instance will ever be
 * able to use it again. You are now safe to manually
 * perform the necessary operations in your index
 * backend to remove the indexed data by hand.
 */

// Index still shows up in management interface as DISCARDED -- it can now be dropped entirely
m = graph.openManagement()
m.updateIndex(m.getGraphIndex("name"), SchemaAction.DROP_INDEX).get()
m.commit()

// JanusGraph should issue a warning about this query requiring a full scan
g.V().has("name", "jupiter")