gpt4 book ai didi

MongoDB 并发瓶颈

转载 作者:IT老高 更新时间:2023-10-28 13:23:39 25 4
gpt4 key购买 nike

太长;没读

问题是关于我在 MongoDB 上遇到的并发瓶颈。如果我进行一次查询,则需要 1 个单位的时间才能返回;如果我进行 2 个并发查询,都需要 2 个单位的时间才能返回;通常,如果我进行 n 个并发查询,所有这些查询都需要 n 个单位的时间才能返回。我的问题是关于在面对并发查询时可以采取哪些措施来改善 Mongo 的响应时间。

设置

我在运行 MongoDB 2.6.7 服务器的 AWS 上有一个 m3.medium 实例。 m3.medium 具有 1 个 vCPU(Xeon E5-2670 v2 的 1 个核心)、3.75GB 和 4GB SSD。

我有一个数据库,其中包含一个名为 user_products 的集合.此集合中的文档具有以下结构:

{ user: <int>, product: <int> }

有 1000 个用户和 1000 个产品,每个用户-产品对都有一个文档,总计一百万个文档。

该集合有一个索引 { user: 1, product: 1 }我下面的结果都是 indexOnly。

考试

测试是在运行 MongoDB 的同一台机器上执行的。我正在使用 benchRun Mongo 提供的函数。在测试期间,没有对 MongoDB 进行其他访问,测试仅包括读取操作。

对于每个测试,都会模拟多个并发客户端,每个客户端都尽可能多地进行单个查询,直到测试结束。每个测试运行 10 秒。并发性以 2 的幂进行测试,从 1 到 128 个并发客户端。

运行测试的命令:
mongo bench.js

这是完整的脚本(bench.js):
var
seconds = 10,
limit = 1000,
USER_COUNT = 1000,
concurrency,
savedTime,
res,
timediff,
ops,
results,
docsPerSecond,
latencyRatio,
currentLatency,
previousLatency;

ops = [
{
op : "find" ,
ns : "test_user_products.user_products" ,
query : {
user : { "#RAND_INT" : [ 0 , USER_COUNT - 1 ] }
},
limit: limit,
fields: { _id: 0, user: 1, product: 1 }
}
];

for (concurrency = 1; concurrency <= 128; concurrency *= 2) {

savedTime = new Date();

res = benchRun({
parallel: concurrency,
host: "localhost",
seconds: seconds,
ops: ops
});

timediff = new Date() - savedTime;

docsPerSecond = res.query * limit;
currentLatency = res.queryLatencyAverageMicros / 1000;

if (previousLatency) {
latencyRatio = currentLatency / previousLatency;
}

results = [
savedTime.getFullYear() + '-' + (savedTime.getMonth() + 1).toFixed(2) + '-' + savedTime.getDate().toFixed(2),
savedTime.getHours().toFixed(2) + ':' + savedTime.getMinutes().toFixed(2),
concurrency,
res.query,
currentLatency,
timediff / 1000,
seconds,
docsPerSecond,
latencyRatio
];

previousLatency = currentLatency;

print(results.join('\t'));
}

结果

结果总是这样(为了便于理解,省略了输出的某些列):
concurrency  queries/sec  avg latency (ms)  latency ratio
1 459.6 2.153609008 -
2 460.4 4.319577324 2.005738882
4 457.7 8.670418178 2.007237636
8 455.3 17.4266174 2.00989353
16 450.6 35.55693474 2.040380754
32 429 74.50149883 2.09527338
64 419.2 153.7325095 2.063482104
128 403.1 325.2151235 2.115460969

如果只有 1 个客户端处于事件状态,则它能够在 10 秒的测试中每秒执行大约 460 次查询。查询的平均响应时间约为 2 毫秒。

当2个客户端并发发送查询时,查询吞吐量维持在每秒460个左右,说明Mongo没有增加响应吞吐量。另一方面,平均延迟实际上翻了一番。

对于 4 个客户端,该模式仍在继续。相同的查询吞吐量,相对于运行 2 个客户端的平均延迟加倍。栏目 latency ratio是当前和先前测试的平均延迟之间的比率。看到它总是显示延迟加倍。

更新:更多 CPU 功率

我决定使用不同的实例类型进行测试,改变 vCPU 的数量和可用 RAM 的数量。目的是看看当您添加更多 CPU 能力时会发生什么。测试的实例类型:
Type        vCPUs  RAM(GB)
m3.medium 1 3.75
m3.large 2 7.5
m3.xlarge 4 15
m3.2xlarge 8 30

结果如下:

Queries per Second

Query Latency

m3.medium
concurrency  queries/sec  avg latency (ms)  latency ratio
1 459.6 2.153609008 -
2 460.4 4.319577324 2.005738882
4 457.7 8.670418178 2.007237636
8 455.3 17.4266174 2.00989353
16 450.6 35.55693474 2.040380754
32 429 74.50149883 2.09527338
64 419.2 153.7325095 2.063482104
128 403.1 325.2151235 2.115460969

m3.large
concurrency  queries/sec  avg latency (ms)  latency ratio
1 855.5 1.15582069 -
2 947 2.093453854 1.811227185
4 961 4.13864589 1.976946318
8 958.5 8.306435055 2.007041742
16 954.8 16.72530889 2.013536347
32 936.3 34.17121062 2.043083977
64 927.9 69.09198599 2.021935563
128 896.2 143.3052382 2.074122435

m3.xlarge
concurrency  queries/sec  avg latency (ms)  latency ratio
1 807.5 1.226082735 -
2 1529.9 1.294211452 1.055566166
4 1810.5 2.191730848 1.693487447
8 1816.5 4.368602642 1.993220402
16 1805.3 8.791969257 2.01253581
32 1770 17.97939718 2.044979532
64 1759.2 36.2891598 2.018374668
128 1720.7 74.56586511 2.054769676

m3.2xlarge
concurrency  queries/sec  avg latency (ms)  latency ratio
1 836.6 1.185045183 -
2 1585.3 1.250742872 1.055438974
4 2786.4 1.422254414 1.13712774
8 3524.3 2.250554777 1.58238551
16 3536.1 4.489283844 1.994745425
32 3490.7 9.121144097 2.031759277
64 3527 18.14225682 1.989033023
128 3492.9 36.9044113 2.034168718

开始xlarge 类型,我们开始看到它最终处理 2 个并发查询,同时保持查询延迟几乎相同(1.29 毫秒)。不过,它不会持续太久,而且对于 4 个客户端,它再次使平均延迟加倍。

2xlarge 类型,Mongo 能够保持处理多达 4 个并发客户端,而不会增加过多的平均延迟。之后,它再次开始翻倍。

问题是: 可以做些什么来改善 Mongo 对并发查询的响应时间? 我预计查询吞吐量会增加,但没想到平均延迟会增加一倍。它清楚地表明 Mongo 无法并行化到达的查询。

某处存在某种瓶颈限制了 Mongo,但它肯定无助于继续增加更多的 CPU 能力,因为成本会令人望而却步。我不认为内存在这里是一个问题,因为我的整个测试数据库很容易放在 RAM 中。还有什么我可以尝试的吗?

最佳答案

您正在使用具有 1 个核心的服务器,并且您正在使用 benchRun。来自 benchRun page :

This benchRun command is designed as a QA baseline performance measurement tool; it is not designed to be a "benchmark".



延迟与并发数的缩放令人怀疑是准确的。你确定计算正确吗?我可以相信 ops/sec/runner 保持不变,延迟/op 也保持不变,随着运行者数量的增加 - 然后如果你添加所有的延迟,你会看到像你这样的结果。

关于MongoDB 并发瓶颈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29493883/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com