redis和watch + multi允许并发用户 [英] redis and watch + multi allows concurrent users

查看:108
本文介绍了redis和watch + multi允许并发用户的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用具有相同电子邮件地址的Web服务对用户注册进行负载测试,并且同时连接的前10个用户将始终注册.

I'm doing a load test on user signup with the same email address for a webservice and the first 10 users which connect simultaneously will always register.

我正在使用WATCH和MULTI,但这似乎没有任何作用.

I'm using WATCH and MULTI but that doesn't seem to work any way.

我正在调用save()来保存用户.

I'm calling save() to save the user.

this.insert = function(callback) {
    this.preInsert();

    created = new Date();
    updated = new Date();

    // Also with these uncommented it still doesn't work
    // Common.client.watch("u:" + this.username);
    // Common.client.watch("em:" + this.email);

    console.log(ID + " email is locked " + this.email);
    Common.client.multi()
    .set("u:" + this.username, ID)
    .hmset("u:" + ID, 
        {"username": this.username
        ,"password": this.password
        ,"email": this.email
        ,"payment_plan": payment_plan
        ,"created": created.getTime()
        ,"updated": updated.getTime()
        ,"avatar": this.avatar})
    .zadd("u:users", 0, ID)
    .sadd("u:emails", this.email)
    .set("u:"+ ID + ":stats", 0)
    .set("em:" + this.email, ID)
    .exec();

    this.postInsert();

    if (callback != null)
        callback(null, this);
}

this.save = function(callback) {
    // new user
    if (ID == -1) {
        var u = this;

        Common.client.watch("u:" + this.username);
        Common.client.exists("u:" + this.username, function(error, exists) {
            // This username already exists
            if (exists == 1) {
                Common.client.unwatch();
                if (callback != null)
                    callback({code: 100, message: "This username already exists"});
            }
            else {
                Common.client.watch("em:" + u.email);
                Common.client.get("em:" + u.email, function(err, emailExists) {
                    if (emailExists != null) {
                        Common.client.unwatch();
                        if (callback != null)
                            callback({code: 101, message: "This email is already in use"});
                    }
                    else {
                        Common.client.incr("u:nextID", function(error, id) {
                            if (error) callback(error);
                            else {
                                ID = id;
                                u.insert(callback);
                            } 
                        });
                    }
                });
            }
        });
    }
    // existing user
    else {
        var u = this;
        Common.client.get("em:" + this.email, function(err, emailExists) {
            if (emailExists != ID && emailExists) {
                if (callback != null) {
                    callback({code: 101, message: "This email is already in use " + ID + " " + emailExists});
                }
            }
            else {
                u.update(callback);
            }
        });
    }
}

输出几乎总是:

1 email is locked test@test.com
2 email is locked test@test.com
3 email is locked test@test.com
4 email is locked test@test.com
5 email is locked test@test.com
6 email is locked test@test.com
7 email is locked test@test.com
8 email is locked test@test.com
9 email is locked test@test.com
10 email is locked test@test.com

我做错了什么还是redis无法处理那么多的并发.这也是Common的定义:

Am I doing something wrong or redis can't handle that much concurrency. Also this is the definition of Common:

var Common = {
    client: redis.createClient(),
...
};

推荐答案

是的!经过一整夜的休息后,解决方案终于在淋浴时解决了.

YES! After a night's rest of course the solution came to me in the shower.

问题是我为整个应用程序使用了一个redis线程,并且所有连接都在该线程上注册了手表.当然,这并不表示密钥是由其他客户端修改的,因为没有其他客户端.

The problem was that I used a single redis thread for the whole app and all the connections registered the watch on that thread. Of course it didn't signal that the keys were modified by a different client because there was no other client.

这篇关于redis和watch + multi允许并发用户的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆