2012-05-25 19 views
2

我最初很熟悉关系型数据存储。我正在研究NoSQL并试图了解它的用例。这是最近一直在困扰我的东西。你如何在NoSQL中做原子,多记录,相互依赖的操作?

如何使用典型的NoSQL产品执行以下操作?

  • 读取多个输入
  • 为他们计算新的值(每个输出依赖于所有输入)
  • 其他问题的值写入回

一个例子这一点,从过去的经验,如下。你有一个网页游戏与各种用户帐户。用户可以相互发起攻击,攻击公式是复杂的黑盒子游戏逻辑,它根据输入和随机性确定相互结果。您需要强制执行攻击以原子方式进行,并且输入反映的是一致的时间点,就像输出一样,关于游戏中执行的一系列攻击的序列化。

这一点很重要:

  • 所有输出一些复杂的方式,我们不能掰开依赖于所有输入(即我们不能仅仅将它转换为教科书的银行账户交易账簿的例子,我们不能只使用预写式日志记录等)
  • 换句话说,我们不是在做P1 + = $ 10,P2 = = $ 10
  • 更像,我们[为了论证]做[基本上像[P1,P2] =(sha1(P1 + P2),sha1(P1-P2))这样复杂/不可约的事物),我们想要P1和P2的值一致的快照[并不是说特定的行是一个很好的例子]
  • 输入将是记录的一小部分子集的任意选择,所以我们不能只使用复合记录
  • 外部观察者看到一个统一/一致的状态之前或之后所有的操作,但不在之间

我特别的例子是我们遇到的问题。我们实际上使用的是关系数据库,但我们并没有像我们应该使用的那样使用它的事务特性。结果,在线玩家反复攻击对方往往会产生不正确的结果,并为攻击者产生幻影资源。

在关系模型中,我会使用事务完成此操作。想想看,这可能是交易的教科书范例。

在NoSQL中如何实现这一点?

以下解答我看到的SO和其他地方,我认为不好的适合这个特定实例:

  • 忽视的竞争条件的可能性
  • 重新设计的游戏,所以这不是一个问题
  • 手动实现2PC,面包店算法等。使用数据存储
  • 使用外部锁定服务

...但如果你认为任何或所有这些是一个很好的解决方案,请让我知道如何和为什么。

我会很感激一些关于如何在实践中实现这种事情的指针。

谢谢!

+3

由于NoSQL包含大量不同的产品/技术,我认为根据您要使用哪种NoSQL解决方案,答案会有所不同。我不认为会有对所有现有NoSQL解决方案最好的答案。你有没有具体的NoSQL解决方案? –

+0

我一直在看几个,我发现他们彼此完全不同。但我注意到的一个共同点是,他们中没有一个似乎对这种操作提供普遍的支持。 如果一个具体的例子是必要的,让我们来问一下:你将如何在MongoDB中做到这一点?或者,你如何在CouchDB中做到这一点? – Ming

+1

请参阅一些NoSQL解决方案(如GT.M)提供的交易。所以使用事务的“关系模型”解决方案就可以在那里工作。现在您正在具体询问MongoDB或CouchDB,让我们来看看这些解决方案的专家应该说些什么。 –

回答

1

你需要了解MongoDB的关于这个话题的两两件事是:

  • 原子的单位是一个单一的文件。
  • 没有交易,但您可以模拟它们。

记住这一点,这种事情不是MongoDB的优势,你自己指出这一点,它本质上是一个交易。

但是,如果你尝试和其中的文件看起来像这样由攻击创建集合建模这个你可以开始:

{ 
    attacker: {user_document}, 
    attackee: {user_document}, 
    in_progress: boolean (true or false), 
    outcomes: [array of results based on calculation] 
} 

要开始使用findAndModify的攻击,你将查询的攻击集合使用upsert具有包含两个用户标识的查询文档。如果确实存在,它不会产生新的攻击。如果其中一个不存在,它将通过插入文档并将in_progress设置为true来开始攻击。把所有必要的用户细节放在那里。

然后,执行黑匣子计算并推送一系列需要对用户文档进行的更新,作为对结果数组进行攻击并将in_progress设置为false的结果。

完成后,将结果逐个应用于用户集合。

如果不存在更多结果,请删除攻击文档,以便可以开始新的攻击。

不确定在给定您的要求的情况下这样做是否完整,但希望这可以帮助您考虑如何完成此任务。