【问题标题】:MongoDB sharded cluster 25 slower than standalone nodeMongoDB 分片集群比独立节点慢 25
【发布时间】:2014-02-28 13:23:52
【问题描述】:

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

但是:将数据导入其中一个副本集可以正常处理 40k 文档/秒,但启用分片会使整个过程减慢到仅 1.5k 文档/秒。

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

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

所有这些都只产生 1.5k 文档/秒,这令人失望。 mongod 是每个 32GB 的物理 Xeon 盒子,3 个配置服务器是虚拟服务器(40 GB HDD,2 GB RAM,如果重要的话),mongos 在我的应用服务器上运行。顺便说一句,1.5k inserts/s 的值不取决于分片键,专用分片键(单字段键和复合键)以及 _id 字段上的散列分片键的行为相同。

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

  • 在虚拟服务器上运行的配置服务器? -> 由于配置服务器的资源消耗低,应该不会有问题
  • 蒙古人? -> 在 HAproxy 后面的专用盒子上运行多个 Mongos 可能是一种替代方案,尚未测试过

【问题讨论】:

  • 尝试在此大规模批量更新期间停止平衡器,看看是否会加快速度。此外,如果可以并且数据允许,请尝试使用有针对性的分片技术,例如 Tag Aware Sharding
  • 当您将数据加载到单个服务器时,您可能正在使用大批量来分摊锁定、日志、网络开销等的成本。当您通过 mongos 加载时,mongos 需要将您的批次分解成更小的批次,然后进入每个分片。它这样做的方式是低效的(github.com/Tokutek/mongo/issues/912 解释更多)。如果这是您的问题,解决此问题的方法是确保应用程序中的每批文档都具有相同的分片键。
  • 好的,令人困惑的是:未通过 sh.shardCollection() 注册分片的集合默认存储在主分片中。因此它们不需要路由、负载平衡等。所以我创建了一个虚拟集合,没有将其指定为共享并将其填充到 mongos mongo shell 中。结果:与共享集合中相同的慢速数据插入。将相同数据导入其中一个副本集时速度仍然是 1/25。

标签: performance mongodb replication sharding


【解决方案1】:

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

使用以下命令:

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

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

【讨论】:

    【解决方案2】:

    让我们先算一下:您的文档有多大?请记住,根据您的写作问题,它们必须通过网络多次传输。

    您可能会因为必须构建索引而遇到这种情况。

    请试试这个:

    1. 禁用所有索引除了_id的索引(这无论如何都是不可能的,iirc)
    2. 加载您的数据
    3. 重新启用索引。
    4. 启用分片和平衡(如果尚未完成)

    无论如何,这是将数据导入共享集群的建议方法,应该会大大加快导入速度。一些(小心!)摆弄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 实例上测量随机磁盘 IO

    【讨论】:

    • 是否有选项或 sn-p 用于通过 syncpersiod/commitinterval/indexprefetch 设置检测延迟?我们正在尝试添加一种智能检测更好的建议和快速修复建议;但最困难的部分是将其识别为错误或延迟的来源。
    • 现在应该如何工作?即使有,测量本身也会减慢这个过程,使你的结果掺假。您可能更愿意看一下预拆分,这是更有希望的。并且在相同系统上的一个好的旧磁盘 IO 基准测试(如果不是螺丝的话,直到硬件的最后一个和平。)应该告诉你足够的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-27
    • 2021-02-12
    • 1970-01-01
    • 1970-01-01
    • 2019-02-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多