由于博客http://aphyr.com/posts/284-call-me-maybe-mongodb中提出的关于写作问题的问题,我正在从少数团队成员那里回避使用MongoDB进行项目。感谢是否有人可以确认问题是否在Mongo 2.6版本中得到解决。在并行注释中,如果我有一个带有2个辅助副本的主服务器,是否可以使用标记集确保其中一个辅助服务器是主服务器的镜像(意味着我在故障转移时没有数据丢失)?
答案 0 :(得分:4)
我想在这里回答这个问题,因为我实际上正在阅读这篇文章,因为我回答这个问题:
呃,还有什么应该做的?它也没有真正恢复,它将数据存储在二进制文件中供以后应用,你是说在第1,000,000个案例的1中你的网络自然会以这种方式死在你想要的副本集上要惩罚,因为MongoDB不知道该主要收到的写入是否仍然是最新的?“还原”肯定听起来不像我的线性化,
BAD MONGODB! SPANK YA HARD!
MongoDB的客户并不打算检查他们的写入是否成功
该帖子是在所有驱动程序转换为已确认的写入后编写的......
他们刚刚发送给他们并认为一切都很顺利。
值得注意的是,MongoDB中不再真正存在,它实际上已被删除。 Unacknowledged意味着2.6中的其他内容。
这与你期望的一样。
你做错了,你期待与此保持一致,这从来都不是未被承认的。 Unackowleged是关于向MongoDB发送快速,遗忘的写入。
写入损失42%
你不能说,我知道这是一个很好的计划,我会把所有的东西扔给/dev/null
并假设他们都应该坚持......
嗯,理论上。在我的测试中,它仅在5次运行中的1次中执行此操作。大多数情况下,它只会完全抛弃这些写入:没有回滚文件,没有任何东西。我真的不知道为什么。
您是否尝试过报告此问题?这可能会有所帮助......我个人没有这种经历。
如果旧的主要状态与新的主要状态无关,我们仍然可以得到相互冲突的写入。
再次未经确认的写入可能会导致这种情况。
主要/次要系统本身是不够的。
WTF!文档说明你应该有三个成员...尝试阅读它!
否则,新当选的初选可能与旧选举有所不同。
是的,还有什么可以做的?我的意思是我无法100%肯定地看待未来;你呢?
啊哈!但这与旧的“不安全”写作有关!我们应该使用Safe写关注!
您应该已经检查了应用程序对这些写入的说法,MongoDB会重新发送并重写应用程序。我认为这是一种非常理智的方法。
在考虑成功之前,我们需要确保复制品已收到我们的写作。
或者您可以尝试使用名为EXCEPTIONS的内容。
Mongo仍然放弃了两次“成功”的写作。
你再次检查了应用程序说的内容,这些写入很可能在选举期间返回给应用程序。
客户端看到“确定”消息并且...明智地假设写入正常。
边缘情况确实存在,有时他们很难不这样做,网络不可能像那样复杂。
我不介意亲自找到该bug的JIRA链接,所以我可以看到。
那些失败的写作可能永远不会,现在或未来的某个时间实现;可能会覆盖有效数据。
我的意思是你很容易从套装中失败但是wite成功了,因为在纳秒窗口内磁盘被提交但是服务器在它返回响应之前失败了,欢迎来到网络伙伴世界!
而且,不,他们会按照顺序发生,而你所说的就是它们,你只是在那个分裂的大脑时刻得到了切断。
正如第一条评论所解释的那样:
实际上,这可能发生在任何类型的集群中。事实上,即使在单一服务器故障中也会发生这种情况。它只是意味着存在数据提交的短暂时刻(到磁盘,到集群......任何已提交的定义)但是对此的确认尚未发送回客户端,此时服务器(或客户端)崩溃。因此,提交已经正确进行,您只是没有听说过。
第一条规则:网络不可靠。
然后我与每周报告其群集故障的Mongo用户交谈。
你呢?
喜欢季节性写作
你有什么废话网络。
例如,上限集合中的冲突似乎只是在设计之后丢弃了冲突点之外的集合中的所有数据。
我似乎无法找到参考,我需要在某些时候进行测试,我个人不会使用上限集合。甚至不排队。但是:
人们将上限集合用于分布式队列。想一想。
我的队列实际上可以处理丢失的写入。例如,我有一个云视频编码器,可以对我的视频网站(如YouTube)的所有视频进行编码,并从我的收藏中挑选出尚未编码的所有视频,将它们排队等待编码然后从中挑选并将视频发送到被编码。无论发生什么事,我的队列都会存活下来。
无论如何回到你的问题:
感谢是否有人可以确认是否在Mongo 2.6版本中解决了这些问题。
我不确定,因为我所能看到的只有一个问题,如果这是一个甚至可以在分布式网络设置中解决的问题,这是一个不存在的问题。
由于他并不关心引用错误,因此我很难说在他使用的测试中是否修复了错误。
在并行注释中,如果我有一个带有2个辅助副本的主服务器,是否可以使用标记集确保其中一个辅助服务器是主服务器的镜像(意味着我在故障转移时没有数据丢失)?
使用ACID数据库。问题解决了......好吧,甚至还不是MySQL和其他技术人员对这些问题不安全:
展示一些。
答案 1 :(得分:2)
除了借鉴@Sammaye的优秀分析外,我想补充一点,这个问题很容易解决:回读一下!正如我可能补充的那样,这种技术在MongoDB之前已有数十年了。
如果您的数据非常有价值,您必须绝对肯定它已经至少有一个辅助数据,您可以采取以下方法:
使用w > 1
或更好{w:"majority"}
的写作问题(顺便说一下:你可以 make this the default behaviour)
设置{fsync:true}
的写入关注选项{j:true}
而不是,这实际上使驱动程序等待,直到数据写入数据文件。
返回写入语句后,使用read preference set to secondary
查询数据。请注意,除非您将写入问题设置为' all' (当复制集的一个数据承载节点关闭时,这将导致写入操作期间失败),此读取操作仍然可以返回过时数据,因为它可能从未在多数池中的次要读取。等待并重复您认为适合您的用例。
如果您无法肯定地确认数据已写入所有数据承载节点,则抛出并处理异常。
使用这种技术,您可以确保将数据写入主数据库和至少一个辅助数据库,并且可以安全地假设数据写入写入关注设置中选择的节点数至少< / em>的。这是对集群的精细控制,但要承认Cassandra provides a similar mechanism并且很可能也是HBase。
这个程序不会很快。期望它与{w:'majority'},{j:true}
的写操作相比要慢几个数量级,这应该足以满足99.999%的用例。
对于极有价值的数据使用此过程(因为缩放的硬件要求会高得多)并且(几乎)无法再现。