我有一个运行在NodeJS上的应用程序,我正在尝试制作一个分布式应用程序。所有写请求都发送到Node应用程序,然后写到CouchDB A,然后写到CouchDBB。我们通过ELB(从2个DB中读取)读取数据。它工作正常。
但是我最近遇到了一个问题,我的CouchDB B崩溃了,而CouchDB B上升之后,现在两个实例之间存在文档_rev不匹配。
在没有任何停机时间的情况下解决上述情况的最佳方法是什么?
答案 0 :(得分:1)
如果您的CouchDB A和CouchDB B位于同一数据中心,那么@Flimzy的建议是在群集部署中使用CouchDB 2.0。您可以在群集中配置n
个CouchDB节点,并在群集上方配置一个负载均衡器,以将HTTP流量传递到任何“启动”的节点。
如果A和B在地理位置上分开,则可以使用CouchDB Replication从A-> B和B-> A中移动数据,这将使两个实例完全同步。 A和B可以是3个或更多CouchDB 2.0节点的群集,也可以是CouchDB 1.7的单个实例。
这些解决方案都不能“修复”同时以不同方式修改数据库的两个副本时出现的问题。这种“冲突”状态是CouchDB防止两次写入冲突时数据丢失的方法。您的应用可以选择一个获胜的修订版本或编写一个新版本来解决冲突。这不是故障情况,它可以帮助您的应用程序在分布式系统中的并发写入过程中从数据丢失中恢复。
您可以了解有关document conflicts in this blog post series的更多信息。
答案 1 :(得分:0)
如果两个1.6.x节点都使用标准复制来同步存储桶,那么关闭一个节点就不成问题。在上节点时,它会收到所有更新而不会发生冲突-因为无法进行更新,因此该节点已关闭。
如果在正常操作期间遇到冲突,那么很遗憾,没有通用的自动解决方法。但是,在大多数情况下,您可以找到一种策略来标记受影响的文档子树,该策略可以确定哪个子版本是最新的(或更重要的)。
要检测有冲突的文档,可以使用标准视图:如果存在相互冲突的修订,则由视图功能接收的文档具有_conflicts
属性。使用适当的视图,您可以检测冲突并合并文档。无论如何,无论您如何检测冲突,都需要外部代码来解决它们。
如果您有冲突的数据本质上是数字的,请考虑使用CRDT结构和标准的map / reduce以获得最终值。如果您的数据是文本格式的,则也可以尝试使用CRDT,但是要获得合理的性能,您需要使用以Erlang编写的reducer。
至于2.x。我不建议在您的案例中使用2.x(实际上,对于除实验之外的任何实际案例)。首先,使用2.x不会消除冲突,因此不能解决您的问题。此外,考虑到2.x,需要对跨节点的大量手动操作进行记录不足,并且无法进行重新平衡,因此,痛苦多于价值。
使用任何群集解决方案的BTW对于两个节点几乎没有意义。
对于上述CVE 12635和CouchDB 1.6.x:您可以使用此补丁https://markmail.org/message/kunbxk7ppzoehih6覆盖此漏洞。