2013-08-17 45 views
1

我的问题听起来太笼统了,但我已经准备好给出任何缺失的数据。MongoDB writeConcern for production

我们做出类似社交网络的东西。为了使读取性能更好,以缓解主实例的生命,我们已经在我们的replicaSet设置

readPreference=secondaryPreferred 

。但有了这个,也不能保证你从那里读取之前将数据写入到辅助的情况下,所以我们必须设置

w=3 

选项。 到目前为止,似乎一切正常,但我本地副本集上的度量显示以下插入统计信息。

Inserting 300 objects: 
w=1 - 0.10s 
w=3 - 1.31s 
Insertion 5000 objects: 
w=1 - 0.6s 
w=3 - 14.6s 

问题是,这是预期的差异,还是我做错了什么?

回答

2

由于w = 3意味着您希望等待确认数据已成功复制到至少两个辅助数据库(除了来自主数据库(w = 1)的确认数据库之外),因此期望性能出现差异。

为了清楚起见,w = 1仅表示您希望初步确认操作已完成。如果发生重复键错误或网络错误等任何错误,都会作为确认的一部分进行报告。

http://docs.mongodb.org/manual/reference/write-concern/

请参考上面的链接,你可以看到有较低的写入担心,让你交易安全性较低的延迟。

如果您想要更高级别的耐用性或安全性,那么您可以使用j = 1等待确认您的操作已写入日志(允许从故障中恢复)。 w> N通过等待来自N个副本成员的确认来增加安全性,以确保您的操作已成功复制到其他成员。 所以要清楚,w> 1不需要指示驱动程序写入副本。如果您决定使用w = N,请注意,如果副本集成员失败并且低于N,您可能会陷入糟糕的境地。w =多数是更灵活的选项。

最后,你可能想重新评估你为什么要从辅助阅读。由于MongoDB使用异步复制,所以最终的结果是一致的。如果您期待一致的读取,那么从主文件读取更有意义。如果您从第二级读取的原因是为了扩展,您应该考虑分片,因为这是扩展的主要机制。在次级分配负载很少提高可伸缩性。操作被复制到副本,所以你不会从较低的写入负载获得很大收益。有时分配不同类型的工作负载是有意义的(可能导致更好的内存利用率)。例如,在辅助人员上运行MR工作可能是有意义的。副本集主要用于高可用性 - 容错功能提供自动故障切换和网络分区问题。

+0

感谢您的回复。实际上,在做这件事之前我们已经分解了数据库,没有任何误解,我们启用了w = N,原因有两个: 1.降低对主实例的读取请求数。 2.具有强大的,而不是最终的一致性。 根据你的回答,接管部分是,考虑从主节点读取操作是否需要很强的一致性。 :-) 谢谢。 – inteloid

+0

关于(2)的注意事项:请记住,由于异步复制,w = N不会改变次级服务最终一致的事实。如果您打算读取刚刚用w = N写入的相同数据,则只能获得一致的读取次数。如果这是您访问模式,请考虑findAndModify代替写入和读取序列。这将确保这个操作序列是原子的,并且将比两个单独的操作执行得更快。 –

+0

你的意思是,如果线程A插入一条记录并等待来自辅助节点的确认,另一个线程在从主节点读取时与从辅助节点读取时可能会得到不同的结果? 这对我们来说有些不错,我认为我们暂时可以接受它。 关于findAndModify,在webapp中使用它并不容易,因为它改变了代码的逻辑。 – inteloid