Hi, everyone. Apologies in advance for my poor English.
I’m new to both Meteor and MongoDB. Any help would be greatly appreciated.
I am trying to implement a chat application.
First when the page is loaded, subscribe the latest 20 messages. Then every time when a user scrolls up, load 20 more older messages.
----- Problem -----
lies when a new message is added(inserted).
The CPU spikes up, and if the insertion occurs several times in a row within a short period of time, the CPU usage reaches almost full percentage. (without multi-core enabling in a multi core instance, ie. single-core, it reaches almost 50 percent, when using meteorhacks:cluster packages, it reaches almost 99 percent.)
This didn’t happen when there are only about 4,000 documents in Chats collection.
With only about 20,000 docs, the webserver CPU struggles a lot. MongoDB CPU is calm like a sleeping baby.
----- What I tried or looked into -----
- Created MongoDB index (boardId, chatRoomId, createdAt) and added ‘$hint’ to publication query for find: no noticeable difference
- Tried adding ‘{validate: false}’ to the insert query since I am using SimpleSchema: no noticeable difference. not sure if this is applied, despite no error or exception.
- Tried adding ‘{w: 0}’ to the insert query and also added &w=0 in the MONGO_URL variable: no noticeable difference. not sure meteor 1.1.0.3 even supports this. I searched for {w: 1} literal, a lot of meteor packages define DB writeConcern {w: 1} internally.
- ‘Chat messages’ have to be served in different ways: In the main chat room, as described above, there will be the latest 20 messages, and scroll back for more. There is a ‘Files’ tab and Searched Messages tab, these tabs serve all messages with the matching keywords. These are from the same collection with Chat messages, albeit separate pub/subs. I checked the CPU with all the other pub/subs commented out, but no improvement in CPU.
Any idea, please?
- specifications and code snippets are as follows:
----- Specifications and code snippets -----
-
Webserver: AWS EC2 m4.large
-
MongoDB Server: AWS EC2 m4.large
-
Meteor version: 1.3.x(updated from 1.1.0.3 as of June 18th, 2016, still the same)
-
Collection name: ‘Chats’ defined using SimpleSchema/attachSchema
-
Subscription: Using SubsManager
-
Subscription.get(‘chat’).subscribe(‘chats’, boardId, currentMsgCount, chatRoomId);
-
Publication:
Meteor.publish(‘chats’, function (boardId, currentCount, chatRoomId) {
check(boardId, String);if (!this.userId) {
return this.stop();
}var self = this;
var ready = false;
var cursor;if (!chatRoomId) {
var chatRoom = ChatRooms.findOne({‘boardId’: boardId});
chatRoomId = chatRoom ? chatRoom._id : ‘’;
}if (currentCount == null) {
cursor = Chats.find({$query: { boardId: boardId, chatRoomId: chatRoomId }, $hint: {boardId: 1, chatRoomId: 1, createdAt: -1}/, $orderBy: {createdAt: -1}/},
{limit: 20 });
} else {
var count = 20;
if (0 >= currentCount)
currentCount = count;cursor = Chats.find({$query: { boardId: boardId, chatRoomId: chatRoomId }, $hint: {boardId: 1, chatRoomId: 1, createdAt: -1}/*, $orderBy: {createdAt: -1}*/}, {skip: currentCount, limit: count });
}
var cursorHandle = cursor.observe({
added: function (doc) {
self.added(’_chats’, doc._id, doc);
},
removed: function (doc) {
self.removed(’_chats’, doc._id);
},
changed: function (doc) {
self.changed(’_chats’, doc._id, doc);
}
});self.onStop(function () {
cursorHandle.stop();
});ready = true;
self.ready();
}); -
Chat message insert:
Chats.insert({
localId: localId,
boardId: chatRoom.boardId,
contentType: chatContentType,
message: message,
userId: userId,
chatRoomId: chatRoomId});