非ACID RethinkDB或MongoDB如何为不相等的查询维护二级索引

时间:2013-08-10 15:25:26

标签: mongodb transactions indexing acid rethinkdb

这更多是'内部运作'未定问题:

noSQL数据库如何不支持* A * CID(意味着他们无法在单个事务中更新/插入然后回滚多个对象的数据) - 更新二级索引?

我的理解是 - 为了使二级索引保持同步(否则它将变得陈旧) - 这必须在同一事务中发生。

此外,如果索引可能驻留在与数据不同的主机上 - 则需要存在分布式锁定和/或两阶段提交以使此类更新以原子方式工作。

但是如果这些数据库不支持多对象事务(这意味着它们不对多个主机上的数据进行两阶段提交),它们使用什么方法来保证驻留在B树结构中的二级索引与数据分开是不是陈旧?

3 个答案:

答案 0 :(得分:22)

这是一个很好的问题。

RethinkDB始终将二级索引存储在与该表的主索引/数据相同的主机上。即使在连接的情况下,RethinkDB也会将查询带入数据,因此二级索引,主索引和数据始终位于同一节点上。因此,不需要分布式锁定协议,例如两阶段提交。

RethinkDB支持一组有限的事务功能 - 单文档事务。原子地记录对单个文档的更改。相关的二级索引更改也会记录为该事务的一部分,因此要么记录整个更改,要么根本不记录任何内容。

扩展有限的事务功能以在单个分片中支持多个文档会很容易,但是跨分片很难做到(因为你提出的分布式锁定原因),所以我们决定不实现事务对于多个文件。

希望这有帮助。

答案 1 :(得分:3)

这是MongoDB的答案。

我不太清楚你的逻辑是什么。更新辅助索引与能够回滚多语句事务(例如多次更新)无关。

MongoDB每个文档都有转码,这对更新索引很重要。如果需要,可以使用期刊撤销这些操作。

  

这必须在同一笔交易中发生。

是的,就像RDBMS一样。您应用的索引越多,写入速度就越慢,在我看来,您知道原因。

在发生写入时,MongoDB将使用适用于特定索引的字段更新适用于该集合的所有索引。

  

此外,如果索引可能驻留在与数据不同的主机上

我不确定MongoDB是否允许这样做,我相信它有一个JIRA;但是,我目前找不到JIRA。

  

然后需要存在分布式锁定和/或两阶段提交以使这种更新以原子方式工作。

最有可能。允许这个功能......好吧,我们只是说创建一个毛球。

即使在分片设置中,每个范围的索引都驻留在分片本身上,而不是在配置服务器上。

  

但是如果这些数据库不支持多对象事务(这意味着它们不会跨多个主机对数据进行两阶段提交)

这不是两阶段提交的意思。我相信你需要了解两阶段提交的内容:http://docs.mongodb.org/manual/tutorial/perform-two-phase-commits/

我想如果你在讨论一个覆盖多个碎片的交易,那么,嗯,好吧。

  

他们使用什么方法来保证驻留在B树结构中的二级索引与数据分离不是陈旧的?

Agan我不确定为什么多文档事务会影响索引是否陈旧,而不是文档分组。例外情况是一个唯一索引,但也适用于单个文档更新;请注意,它的独特性在分片设置中有点毛茸茸,无法保证。

在您正在创建的索引中,通常每个文档前缀键一个条目,无论它是文档上的多键索引,那么您可以创建多个索引,但是,每个对象都可以完成索引更新,而不是通过多文档交易,我不确定你在这里的逻辑是什么,这就是我的答案。

答案 2 :(得分:3)

RethinkDB始终将二级索引数据存储在与其索引的数据相同的计算机上。这允许它在同一事务中更新。 Rethink承诺使用单个文档操作成为ACIDy,并认为文档的索引是文档本身的一部分。