【问题标题】:MongoDB performing slow under loadMongoDB 在负载下执行缓慢
【发布时间】:2018-09-26 10:54:57
【问题描述】:

我们使用 8 核、32GB RAM 的 mongodb 3.4.14。我正在使用 Jmeter 执行负载测试,有 70 个线程我有可接受的输出。但随着负载的增加,SLA 呈指数级增长,吞吐量急剧下降。我尝试增加ulimit,下一步是分片,除此之外我还能做其他性能优化吗?

更新

@Jeet,以下是调查结果:

  1. 是否有很多聚合查询?你有什么样的集合结构,即

负载测试在单个聚合查询上运行,并且文档的结构也具有相同的字段集。修复文档大小会有所帮助吗?我该怎么做?

  1. 有很多嵌套数组吗?

答案:没有嵌套查询。

  1. 是单个实例还是副本集?尝试将具有读写功能的副本集放入不同的节点。

目前我们只想在单个节点上运行。

  1. 查询是否返回来自多个集合的数据?

不,只有 1 个集合。

  1. 检查您的实例在多少百分比的操作中出现页面错误?

在有 500 个用户的情况下,我看不到太多页面错误,只有 2 位数字。

  1. 在高锁定/队列期间检查您的日志以查找具有高 nscanned 或 scanAndOrder 的操作,并相应地编制索引。

如何查看?

  1. 检查您对 CPU 密集型运算符(如 $all、$push/$pop/$addToSet)的查询,以及对大型文档的更新,尤其是对具有大型数组(或大型子文档数组)的文档的更新。

是的,在上述负载下,CPU 已满且响应延迟。我们正在做一个 groupBy 然后按限制排序。

  1. 如果您的数据库写入繁重,请记住每个数据库一次只能写入一个 CPU(由于该线程持有写入锁)。考虑将部分数据移到自己的数据库中。

我们的数据库主要是读取量大,集合将每天填充一次。

除此之外,我还尝试通过将以下代码放入 for 循环中来做一个简单的测试:

Document findQuery = new Document("userId", "Sham");
FindIterable<Document> find = collection.find(findQuery);
MongoCursor<Document> iterator = find.iterator();

使用executor启动进程:

ExecutorService executorService = Executors.newFixedThreadPool(100);

即使这样,性能也很慢,需要 900 毫秒才能返回。

1 个请求 = 每个请求 150 毫秒

100 个请求 = 每个请求 900 毫秒

当我看到 500 个用户的统计数据如下:

insert query update delete getmore command dirty used flushes vsize   res qrw arw net_in net_out conn                time
    *0    *0     *0     *0       0     1|0  0.0% 0.0%       0  317M 28.0M 0|0 0|0   156b   45.1k    3 Oct 12 15:31:19.644
    *0    *0     *0     *0       0     1|0  0.0% 0.0%       0  317M 28.0M 0|0 0|0   156b   45.1k    3 Oct 12 15:31:20.650
    *0    *0     *0     *0       0     3|0  0.0% 0.0%       0  317M 28.0M 0|0 0|0   218b   46.1k    3 Oct 12 15:31:21.638
    *0    *0     *0     *0       0     2|0  0.0% 0.0%       0  317M 28.0M 0|0 0|0   158b   45.4k    3 Oct 12 15:31:22.638
    *0    *0     *0     *0       0     1|0  0.0% 0.0%       0  317M 28.0M 0|0 0|0   157b   45.4k    3 Oct 12 15:31:23.638
    *0   376     *0     *0       0   112|0  0.0% 0.0%       0  340M 30.0M 0|0 0|0  64.9k   23.6m   26 Oct 12 15:31:24.724
    *0    98     *0     *0       0   531|0  0.0% 0.0%       0  317M 27.0M 0|0 0|0   109k   6.38m    3 Oct 12 15:31:25.646
    *0    *0     *0     *0       0     2|0  0.0% 0.0%       0  317M 27.0M 0|0 0|0   215b   45.6k    3 Oct 12 15:31:26.646
    *0    *0     *0     *0       0     1|0  0.0% 0.0%       0  317M 27.0M 0|0 0|0   157b   45.1k    3 Oct 12 15:31:27.651
    *0    *0     *0     *0       0     2|0  0.0% 0.0%       0  317M 27.0M 0|0 0|0   159b   45.8k    3 Oct 12 15:31:28.642

【问题讨论】:

    标签: java mongodb performance


    【解决方案1】:

    这也取决于您发出的查询类型,请检查是否存在以下几点 -

    • 是否有很多聚合查询?什么样的收藏 你有结构吗,即
    • 有很多嵌套数组吗?
    • 它是一个 单实例还是副本集?尝试使用 read 放置一个副本集 并写入不同的节点。
    • 查询是否从 多个系列?
    • 检查您的实例在多少百分比的操作中出现页面错误?
    • 在高锁定/队列期间检查您的日志以查找具有高 nscanned 或 scanAndOrder 的操作,并相应地编制索引。
    • 检查您对 CPU 密集型运算符(如 $all、$push/$pop/$addToSet)的查询,以及对大型文档的更新,尤其是对具有大型数组(或大型子文档数组)的文档的更新。
    • 如果您的数据库写入繁重,请记住每个数据库一次只能写入一个 CPU(由于该线程持有写入锁)。考虑将部分数据移到自己的数据库中。

    随着时间的推移,这很少会降低性能。我在这里介绍了最常见的用例,但请check this post 获得更多见解。

    【讨论】:

    • 回答您的问题 1. 这是一个简单的groupby 子句。 2. 没有 3. 单实例 4. 没有。所以就第 3 点而言,需要有副本集,但在此之前我可以做任何其他类型的优化吗?
    • 我的应用程序阅读量很大,所以你有什么建议我可以做的调整吗?
    【解决方案2】:

    请检查您的硬件是否受到限制,磁盘是系统中最大的瓶颈。 查看硬件是否不受限制:

    top/htop => cpu percentage
    iostat -x 1 => sysstat tool to see disk r/w limits (%util)
    

    【讨论】:

    • 上面的 ^ 应该去评论了,但由于声誉较低,我无法添加相同的内容。
    猜你喜欢
    • 2016-01-12
    • 2018-07-19
    • 1970-01-01
    • 2016-06-03
    • 1970-01-01
    • 1970-01-01
    • 2017-12-01
    • 1970-01-01
    • 2018-09-16
    相关资源
    最近更新 更多