使MongoDB更新/写入查询更快

时间:2016-03-15 17:42:30

标签: node.js mongodb mongoose

我正在寻找在MongoDB中为我正在开发的MeanJS Web应用程序存储实时数据的最有效方法。

我有以下示例架构:

    SomeModel: {
        name: {
            type: String,
            default: '',
            required: 'Please Enter Name',
            trim: true
        },
        data: {
            type: Schema.Types.Mixed,
            default: {}
        },
        data_keys: {
            type: Schema.Types.Mixed,
            default: {}
        },
        websocket_url: {
            type: String,
            default: '',
        },
        created: {
            type: Date,
            default: Date.now
        },
        user: {
            type: Schema.ObjectId,
            ref: 'User'
        }   
    }

“数据”字段可能包含这样的数据,但它取决于订阅的“模型”,每个模型的数据格式可能略有不同。

    data: {
        balance: {
            currentBalance: 100,
            availableBalance: 80,
            /* Additional Account Details */
        },
        orders: [{
            /* Some Array of Order Details */
        }],
        /* Additional Data Properties */
    }

对于每个'someModel'对象,我尝试连接到websocket服务器,订阅更新,然后将它们写入数据库。

我想尝试使用这样的东西:

    some_ws = new WebSocket(someModel.websocket_url);

    some_ws.on('message', function incoming(msg) {

        var message = JSON.parse(msg);

        try {       
            // Update 'someModel.data' in memory.
            Object.keys(message['data']).forEach(function(key) {
                someModel.data[key] = message['data'][key];
            });

            // Write out to Database.
            SomeModel
            .update({_id: someModel._id}, {data: someModel.data, data_keys: someModel.data_keys})
            .exec(function (err, nItems) {
                if(err) {
                    console.log("ERROR Saving SomeModel Data: %s", err);
                } else {
                    // console.log("Saved Data for: %s", someModel.name);
                }
            });


        } catch (exception) {
            console.log(clc.red("Exception Caught: %s"), util.inspect(exception));
            console.log(clc.cyan("DEBUG:: Message: %s"), util.inspect(message));
        }
    });

我发现我从websocket连接获得几乎连续的更新,并且'更新'查询正在减慢需要在应用程序前端发生的'读取查询'。

我希望能够在这个'someModel.data'对象中存储模型的'当前'数据,然后每分钟写一个'model_log'表,其中包含与之关联的数据的“快照”那个特定时间的模型:

例如:

    model_log schema: {
        model: {
            type: 'Schema.ObjectId',
            ref: 'SomeModel',
        },
        data: {
            /* Model Data */
        },
        timestamp: {
            type: Date,
            default: Date.now,
        }
    }

所以我可以这样做:model_log.find({'timestamp':{$ gte:startDate,$ lte:endDate}});

然后回来:

    [
        {
            model: ObjectId('someModelId'),
            data: {
                someData: someValues,
                otherData: otherValues,
            },
            timestamp: March 15, ‎2016‎ ‎12:‎00‎ ‎AM
        }, 
        {
            model: ObjectId('someModelId'),
            data: {
                someData: someNewValues,
                otherData: otherNewValues,
            },
            timestamp: March 15, 2016 12:01 AM,
        }, 
        ...
    ]

如何提高效率或更快地进行写入/更新操作?

谢谢,

1 个答案:

答案 0 :(得分:0)

选项很少:

  1. 使用集合分片分割负载

  2. 创建副本集,其中辅助服务器可以回复查询,主要负责提供数据和推送更改

  3. 使用有线老虎存储引擎将集合放入内存(我不确定我们是否可以在社区中进行)

  4. 使用SSD HDD减少写入延迟

  5. 切换到有线虎(因为我们这里有文件锁级别而不是收集锁级别)

  6. nr 3& 5可以在开发机器上进行分离测试