简体   繁体   English

mongodb 查询非常慢

[英]mongodb queries are very slow

I have a multi-threaded app that executes hundreds of transactions per second but after a while the performance drops and the queries are taking too long to execute.我有一个多线程应用程序,每秒执行数百个事务,但过了一段时间后,性能下降并且查询执行时间太长。 I have worked on optimising the connection with the following code to avoid errors, but this resulted in a poor performance.我一直在使用以下代码优化连接以避免错误,但这导致性能不佳。

My queries varies from inserts, delete and multi update;我的查询有插入、删除和多次更新; collections do not exceed 100,000 rows.集合不超过 100,000 行。

I have a cluster of 4 VMs for mongoldb each has 4 cores and 28GB of ram on Azure.我有一个 mongoldb 的 4 个 VM 集群,每个在 Azure 上都有 4 个内核和 28GB 的​​内存。 I built the cluster using bitnami production ( https://azure.microsoft.com/en-us/marketplace/partners/bitnami/production-mongodbdefault/ )我使用 bitnami 生产构建了集群( https://azure.microsoft.com/en-us/marketplace/partners/bitnami/production-mongodbdefault/

private static MongoClientOptions options = MongoClientOptions.builder()
.connectionsPerHost(1000)
.threadsAllowedToBlockForConnectionMultiplier(15)
.connectTimeout(60 * 1000)
.maxWaitTime(60 * 1000)
.socketTimeout(60 * 1000)
.connectTimeout(60 * 1000)
.build();

I am not using any indexes and here is my app flow:我没有使用任何索引,这是我的应用程序流程:

  1. am using the db tales for queuing and processing msgs.我正在使用 db tales 来排队和处理消息。 Each job is saved in a separate collection, with a document for each msg that looks like this (status is 'ready' for the msgs at this stage):每个作业都保存在一个单独的集合中,每个 msg 都有一个文档,看起来像这样(在此阶段状态为“准备好”消息):
{
"_id": ObjectId("57cd303743ffe80f3728fcf5"),
"_class": "com.mongodb.BasicDBObject",
"job_id": "57cd3031d9991f8639487013",
"priority": 1,
"title": "1",
"sender_id": "sender 1",
"account_id": "57c2d556d9991fbc15897275",
"schedule_date": ISODate("2016-09-05T08:43:00Z"),
"utf8": false,
"content": "text to be sent",
"number": "962799000001",
"status": "ready",
"user_id": "57c2d602d9991fbc1589727b",
"adv": true,
"number_of_sms_msgs": 1,
"uuid": "57cd3031d9991f8639487013_57cd303743ffe80f3728fcf5",
"msg_id": "1955559517"
}
  1. Then I am moving batches from each job according to their priorities from status 'ready' to 'queued' and add them to on-memory queue to be processed:然后,我根据每个作业的优先级将批次从“就绪”状态移动到“排队”,并将它们添加到要处理的内存队列中:
List<DBObject> batch = scaffoldingRepository.findPageNoSort(dataType, page, next_batch_size, query, null);
if (batch != null && batch.size() > 0) {    
    BasicDBList ids = new BasicDBList();
    for (final DBObject msg : batch) {
        msg.put("status", "queued");
        msg.put("uuid", job_id + "_" + msg.get("_id"));
        ids.add(new ObjectId(msg.get("_id").toString()));
    }
    BasicDBObject search = new BasicDBObject();
    search.put("_id", new BasicDBObject("$in", ids));
    BasicDBObject update = new BasicDBObject();
    update.put("$set", new BasicDBObject("status", "queued"));
    scaffoldingRepository.updateObjects(search, update, dataType);
}
  1. Then another thread sends the actual msgs from the on-memory queue and updates each msg's status separately (sent/failed);然后另一个线程从内存队列中发送实际的消息并分别更新每个消息的状态(发送/失败); I add an index for this msg in a separate table so I can find it once the sender send me back the final status.我在一个单独的表中为此 msg 添加了一个索引,这样一旦发件人将最终状态发回给我,我就可以找到它。
  2. Finally I get a final result from the sender about the msg (delivered/undelivered) and I update this msg accordingly, then remove the index from (job_index) collection in the previous step.最后,我从发件人那里得到了关于味精(已交付/未交付)的最终结果,我相应地更新了此味精,然后从上一步中的 (job_index) 集合中删除了索引。

========================== UPDATE: ====================== ==========================更新: ======================

I noticed that I got this error in Java logs:我注意到我在 Java 日志中收到此错误:

com.mongodb.MongoSocketReadTimeoutException: Timeout while receiving message
at com.mongodb.connection.InternalStreamConnection.translateReadException(InternalStreamConnection.java:475)
at com.mongodb.connection.InternalStreamConnection.receiveMessage(InternalStreamConnection.java:226)
at com.mongodb.connection.UsageTrackingInternalConnection.receiveMessage(UsageTrackingInternalConnection.java:105)
at com.mongodb.connection.DefaultConnectionPool$PooledConnection.receiveMessage(DefaultConnectionPool.java:438)
at com.mongodb.connection.WriteCommandProtocol.receiveMessage(WriteCommandProtocol.java:262)
at com.mongodb.connection.WriteCommandProtocol.execute(WriteCommandProtocol.java:104)
at com.mongodb.connection.UpdateCommandProtocol.execute(UpdateCommandProtocol.java:64)
at com.mongodb.connection.UpdateCommandProtocol.execute(UpdateCommandProtocol.java:37)
at com.mongodb.connection.DefaultServer$DefaultServerProtocolExecutor.execute(DefaultServer.java:168)
at com.mongodb.connection.DefaultServerConnection.executeProtocol(DefaultServerConnection.java:289)
at com.mongodb.connection.DefaultServerConnection.updateCommand(DefaultServerConnection.java:143)
at com.mongodb.operation.UpdateOperation.executeCommandProtocol(UpdateOperation.java:76)
at com.mongodb.operation.BaseWriteOperation$1.call(BaseWriteOperation.java:142)
at com.mongodb.operation.BaseWriteOperation$1.call(BaseWriteOperation.java:134)
at com.mongodb.operation.OperationHelper.withConnectionSource(OperationHelper.java:232)
at com.mongodb.operation.OperationHelper.withConnection(OperationHelper.java:223)
at com.mongodb.operation.BaseWriteOperation.execute(BaseWriteOperation.java:134)
at com.mongodb.operation.BaseWriteOperation.execute(BaseWriteOperation.java:61)
at com.mongodb.Mongo.execute(Mongo.java:827)
at com.mongodb.Mongo$2.execute(Mongo.java:810)
at com.mongodb.DBCollection.executeWriteOperation(DBCollection.java:333)
at com.mongodb.DBCollection.updateImpl(DBCollection.java:495)
at com.mongodb.DBCollection.update(DBCollection.java:455)
at com.mongodb.DBCollection.update(DBCollection.java:432)
at com.mongodb.DBCollection.update(DBCollection.java:522)
at com.mongodb.DBCollection.updateMulti(DBCollection.java:552)
at java.util.TimerThread.mainLoop(Timer.java:555)
at java.util.TimerThread.run(Timer.java:505)

And here is my Mongodb config:这是我的 Mongodb 配置:

# mongod.conf
# for documentation of all options, see:
#   http://docs.mongodb.org/manual/reference/configuration-options/

# Where and how to store data.
storage:
  dbPath: /opt/bitnami/mongodb/data/db
  journal:
    enabled: true
    #engine:
  mmapv1:
    smallFiles: true
#  wiredTiger:

# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /opt/bitnami/mongodb/logs/mongodb.log

# network interfaces
net:
  port: 27017
  bindIp: 0.0.0.0
  unixDomainSocket:
    enabled: true
    pathPrefix: /opt/bitnami/mongodb/tmp

# replica set options
replication: 
  replSetName: replicaset

# process management options
processManagement:
   fork: false
   pidFilePath: /opt/bitnami/mongodb/tmp/mongodb.pid

# set parameter options
setParameter:
   enableLocalhostAuthBypass: true

# security options
security:
  authorization: disabled
  #keyFile: replace_me

#profiling
#operationProfiling:
  #slowOpThresholdMs: 100
  #mode: slowOp

Few tips小贴士



-In MongoDB profiler did you check the slow running queries. - 在 MongoDB 分析器中,您是否检查了运行缓慢的查询。

-Did you try indexing the documents (use inputs from above step) - 您是否尝试索引文档(使用上述步骤的输入)

-Which version of MongoDB are you using and which is the storage engine. - 您使用的是哪个版本的 MongoDB,哪个是存储引擎。

-Have you done replication of the server. - 您是否已完成服务器的复制。 If yes, please revisit the write concern parthttps://docs.mongodb.com/manual/core/replica-set-write-concern/如果是,请重新访问写关注部分https://docs.mongodb.com/manual/core/replica-set-write-concern/

-Can you check whether mongodb in-memory implementation can help https://docs.mongodb.com/manual/core/inmemory/ - 你能检查一下 mongodb 内存实现是否可以帮助https://docs.mongodb.com/manual/core/inmemory/

-You can see few important tips here - https://docs.mongodb.com/manual/administration/analyzing-mongodb-performance/ - 你可以在这里看到一些重要的提示 - https://docs.mongodb.com/manual/administration/analyzing-mongodb-performance/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM