Dspace双写入RDBMS和SOLR与并发

时间:2016-03-31 03:44:15

标签: database solr dspace

我想知道dspace如何在支持并发性的同时管理数据库和solr中的索引。换句话说,如果2个人尝试同时写入同一个项目(例如更改元数据),dspace如何确保索引不会与数据库失去同步。

如果USER1与USER 2同时写入相同的元数据值,并且首先发生对USER 1的数据库的写入,则会发生这种情况,但随后写入数据库和USER2的索引,然后写入USER1 Happen的索引。

换句话说,USER1"写"将在索引中,而User2写入将在数据库中=不一致!!!

我想知道如何在dspace中避免这种情况,这是典型的双写问题。

使用dspace的事件系统,我不知道如何避免这种情况。

有谁知道?

enter image description here

1 个答案:

答案 0 :(得分:2)

在Solr中,DSpace不仅仅索引单个元数据更改(发生时)。它实际上重新索引Solr中的整个Item。

这意味着虽然并发性是数据库层中的一个问题(并且写入/更新在数据库中同步),但它不是Solr索引过程中的一个。

以下是您的示例中应该/应该发生的事情。

  1. 用户1和用户2同时编辑同一项目的标题。
  2. 编辑将在数据库级别进行同步,以便第一个进行编辑。我们假设用户1的编辑首先发生,然后是用户2的编辑。
  3. 用户1的编辑将触发Solr中的重新索引。用户2的编辑也是如此。这意味着同一项目将重新编制索引两次(一次用于 每个编辑)。这些重新索引与特定更新无关(因此第一个reindex不仅索引标题),而只是告诉Solr项目已更新,需要重新索引。
  4. 在第一个reindex上,将进行用户1的编辑,因此该项目将使用该标题编入索引
  5. 到第二次重新索引时,将进行用户2的编辑(因为重新索引在本质上比保存编辑到DB层的时间更长),因此将使用该更新的标题(重新)索引项目。
  6. 因此,这里的简单答案是DSpace不会重新索引单个修改(如果不与数据库编辑同步,则最终可能会失序)。相反,它会跟踪哪些对象已更新,并触发整个对象元数据的重新索引。虽然这可能看起来像“过度杀伤”,但Solr中单个对象的重新索引并不是所有过程密集型的,它确保对象的当前/最新元数据在Solr中被索引(在同时写入的情况下)。

    更新:根据要求(在下面的评论中),这里是DSpace如何更详细地执行重建索引(在Solr中)。

    1. DSpace有一个已定义的事件系统。它遵循本节dspace.cfg中的配置:https://github.com/DSpace/DSpace/blob/dspace-5_x/dspace/config/dspace.cfg#L732
    2. 默认情况下,在DSpace 5中,IndexEventConsumer执行索引的索引。默认情况下,此处已定义:https://github.com/DSpace/DSpace/blob/dspace-5_x/dspace/config/dspace.cfg#L732
    3. 在DSpace 5中,每当有人更改项目的元数据(或任何有关项目的内容)时,都会调用Item.update()方法将实际保存的更改保存回数据库层。
    4. 保存所有更改后(使用DatabaseManager.update()),Item.update()方法会生成new MODIFY event in the Event System
    5. 新的MODIFY事件被追加到LinkedList of events in the current Context
    6. Context is committed(保存更改时发生)时,它首先调用DB连接上的commit(结束事务)。然后,它将事件列表发送到Dispatcher(默认情况下在dspace.cfg中配置BasicDispatcher),然后在Solr中触发索引(通过已配置的IndexEventConsumer
    7. IndexEventConsumer将更新对象列表(在本例中为Item)传递给IndexingService(默认情况下为SolrServiceImpl)。
    8. 最后,SolrServiceImpl.indexContent()从数据库中读取最新的元数据值,并在Solr中对它们进行索引。
    9. 上面的逻辑仍然有点简化(因为它太复杂而无法遍历代码的每一步)。但是,这里的基本要点是每个Item.update()调用都被视为数据库事务。它还会触发添加MODIFY事件,该事件存储在用户的会话中(Context对象)。提交数据库事务后,IndexEventConsumer处理MODIFY事件,重新索引整个项目

      因此,在同步编辑的情况下,将生成两个MODIFY事件(每个编辑一个)。但是,在提交 last 数据库编辑之后才会触发 last MODIFY事件。因此,Solr索引应始终与数据库中的最新信息同步。