【问题标题】:Mongodb Performance issueMongodb性能问题
【发布时间】:2014-01-08 06:26:58
【问题描述】:

我正在使用 mongodb,我需要更新我的文档,说总共有 1000 个。我的文档具有如下基本结构:

{
People:[1,2,3,4],
Place:"Auckland"
Event:"Music Show"
}

我有 10,000 个线程在另一个 VM 中同时运行。每个线程查找这些文档(1000 个),查看这 1000 个文档是否与查询匹配,并在 People 数组中推送一个数字。假设如果线程 100 发现这 1000 个文档中的 500 个相关文档,那么它会将数字 100 推送到所有 500 个文档的 People 数组中。 为此,

我正在为每个线程(10000)使用命令

update.append("$push",new BasicDBObject("People",serial_number));
updateMulti(query,update);

我发现这些就地更新(多查询)的性能很差。 这是由于写锁造成的问题吗? 每个线程(10000)更新与查询相关的文档? - 所以似乎有很多“等待” 有没有更有效的方法来执行这些“推送”操作? “UpdateMulti”是解决这个问题的正确方法吗?

感谢您的好评 - 编辑和添加更多信息

一些设计背景:

是的,您对我们问题的理解是正确的。我们有 10000 个线程,每个线程代表一个“参与者”,一次使用 $push 更新多达 1000 个实体(基于适当的查询)。

反转模型会导致我们遇到一些损坏的用例(从我们的领域的角度来看),导致我们跨主要实体的“状态”(现在将分布在许多集合中)进行连接 - 例如:这些操作中的每一个都是该实体的状态更改 - E 具有状态 ( e1,e2,e3,e4,e5 ) - 因此 e1 到 e5 表示为一个聚合数组,该数组由代表外部应用程序操作的 10,000 个线程/进程更新。

我们需要接近实时的聚合,因为另一组“参与者”查看 e1 到 e5 的这些“状态”,然后通过另一个通道适当地响应“数组中的元素”。

在这种情况下,“理想”的设计策略应该是什么——加快写入速度。 分片会有所帮助吗 - 是否有一个“量级”启发式 - 我们应该分片的锁定百分比是多少等等。

【问题讨论】:

  • 需要澄清一下——这些州是事先知道的吗?换句话说,有多少个州——5 个?如果是这样,为什么它们必须是一个数组?您能否举一个“正在进行中”的文档示例以及其他参与者正在使用的查询类型?
  • C { a1="", /// 属性 a2="", a3="" C_s1=[a1,a2,a3,a4,....] // 状态 s1实体 C C_s2=[a5,a4,a11,a1,...] C_s3=[a1,a2,a3,a4,....] C_s4=[a1,a2,a3,a4,...] C_s5 =[a1,a2,a3,a4,....] } 这 5 个状态已经被编码为数组类型 - 所以任何进行多重更新的查询都将从“ai”的角度来看,因此对于给定的实例ai - 它可能需要在不同的状态下适当地更新多个 C - 即 C1 中的 s1 , C3 中的 s2 等......每隔几分钟。另一个演员只查看处于不同状态的ai,并与他们互动以引导他们通过状态机@Asya Kamsky

标签: performance mongodb insert updates


【解决方案1】:

由于您的架构设计,这是一个问题。

$push 多个文档的多个值是极其低效的,尤其是来自多个线程。写锁不是问题,而是您的设计造成了问题。此外,您的文档不断增长,这意味着更新没有“到位”,您的收藏很快就会变得支离破碎。

您的架构似乎是“颠倒的”。您有 10,000 个线程希望将代表人的数字(我假设有很多人)添加到少量文档(1000 个)中,这些文档将变得非常庞大。在我看来,如果你想在其他东西中嵌入一些东西,你可能会考虑代表人的集合,然后嵌入这些人所在的事件 - 至少你将每个人的数组大小限制为最多 1,000 ,并且更新将分布在更多的文档中,从而显着减少争用。

另一种选择是简单地记录出席的事件/人员,然后在以后对原始数据进行汇总,但是如果不确切知道您对此应用程序的要求是什么,很难知道哪种方式会产生最佳结果 -你选择的方式绝对不可能给你带来好的表现。

【讨论】:

  • 感谢您的出色回应 - 已编辑并在问题中添加了更多信息
  • C { a1="", /// 属性 a2="", a3="" C_s1=[a1,a2,a3,a4,....] // 状态 s1实体 C C_s2=[a5,a4,a11,a1,...] C_s3=[a1,a2,a3,a4,....] C_s4=[a1,a2,a3,a4,....] C_s5 =[a1,a2,a3,a4,....] } 这 5 个状态已经被编码为数组类型 - 所以任何进行多重更新的查询都将从“ai”的角度来看,因此对于给定的实例ai - 它可能需要在不同的状态下适当地更新多个 C - 即 C1 中的 s1 , C3 中的 s2 等......每隔几分钟。另一个参与者只查看处于各种状态的 AI,并与它们互动以引导它们通过状态机
猜你喜欢
  • 2012-11-07
  • 2011-06-30
  • 2019-10-16
  • 2012-08-18
  • 2013-09-09
  • 2011-04-01
  • 2021-07-06
  • 2019-04-13
  • 1970-01-01
相关资源
最近更新 更多