MongoDB以比独立节点更慢的方式对群集25进行分片

时间:2014-02-04 14:10:19

标签: performance mongodb replication sharding

我对这种情况感到困惑,并试图解决这个问题几天了。我在三个3成员副本集(rs0,rs1和rs2)上运行了3个碎片。到目前为止一切正常。数据分布在3个分片上,并克隆在副本集中。

但是:将数据导入到其中一个副本集中可以正常使用40k docs / s但是通过启用分片可以将整个过程减慢到仅1.5k docs / s。

我通过不同的方法填充数据:

  • 在mongo shell中生成一些随机数据(在我的mongos中运行)
  • 通过mongoimport导入JSON数据
  • 通过mongorestore从另一台服务器恢复MongoDB转储

所有这些都导致1.5k doc / s令人失望。 mongod是物理Xeon盒子,每个32GB,3个配置服务器是虚拟服务器(40 GB HDD,2 GB RAM,如果这很重要),mongos在我的app服务器上运行。顺便说一下,1.5k insert / s的值不依赖于分片键,专用分片键(单字段键和复合键)的相同行为以及_id字段上的散列分片键。

我尝试了很多,甚至重新安装了整个集群两次。问题是:这个设置的瓶颈是什么:

  • 在虚拟服务器上运行的配置服务器? - >由于配置服务器的资源消耗低,不应该有问题
  • mongos? - >在HAproxy后面的专用盒子上运行多个Mongos可能是另一种选择,尚未测试

2 个答案:

答案 0 :(得分:3)

让我们先做数学:你的文件有多大?请记住,根据您的写作关注,他们必须多次通过网络传输。

由于必须构建索引,您可能正在经历这种情况。

请试试这个:

  1. 禁用所有索引,但_id之外的<(无论如何不可能,iirc)
  2. 加载您的数据
  3. 重新启用指数。
  4. 启用分片和平衡(如果尚未完成)
  5. 无论如何,这是将数据导入共享群集的建议方式,并且应该大大加快导入速度。摆弄storage.syncPeriodSecsstorage.journal.commitIntervalMs的一些人(谨慎!)也可能会有所帮助。

    即使将数据存储在主分片上,也会发生延迟 。根据索引的大小,它们可能会大大减慢批量操作。您可能还想查看replication.secondaryIndexPrefetch配置选项。

    另一件事可能是你的oplog填充速度比复制速度快。问题在于:一旦创建,就无法增加它的大小。我不确定在独立模式下删除和重新创建它是否安全,然后重新共享副本集,但我对此表示怀疑。因此,安全选项是让实例实际保留副本集,使用更合适的oplog大小重新安装它,并将实例添加到副本集,就像它是第一次一样。如果您不关心数据,只需关闭副本集,调整配置文件中的oplog大小,删除数据目录并重新启动并重新初始化副本集。两次思考你的问题,这听起来对我来说是最好的选择,因为opllog并不参与独立模式,iirc。

    如果您仍然遇到相同的性能问题,我的赌注是磁盘或网络IO问题。

    您有一个相当标准的设置,您的mongos实例运行在与mongod不同的计算机上(无论是独立设备还是副本设备的主设备)。您可能想要检查一些事情:

    1. 解析运行mongos实例的计算机上主要和辅助分片名称的名称解析延迟。我无法计算为各种操作安装nscd改进性能的时间。
    2. mongos实例到主分片的网络延迟。假设您的AppServer和群集之间有防火墙,您可能希望与相应的管理员联系。
    3. 如果您使用的是外部身份验证,请尝试测量所需的时间。
    4. 使用某种隧道(例如stunnel或SSL / TLS等加密)时,请确保禁用名称解析。请注意,加密和解密可能需要相对很长时间。
    5. 测量mongod实例
    6. 上的随机磁盘IO

答案 1 :(得分:1)

我遇到了类似的性能问题。有助于解决性能问题的是我最终将mongod实例设置为与作为主要分片的mongos在同一主机上运行。

使用以下命令:

mongos> use admin
mongos> db.runCommand( { movePrimary: "mydb", to: "shard0003" } )  

进行此更改后(无需触及负载均衡器或调整任何其他内容),我可以使用我编写的加载程序加载相对较大的数据集(2500万行),整个过程大约需要15分钟而不是小时/天。