使用Redis进行用户查找表

时间:2014-11-23 15:08:17

标签: node.js express redis nosql

我正在学习Redis,而且我正在使用一个简单的users表。我通过node_redis与Redis进行了互动。

我将每个新用户存储为:

client = redis.createClient();
client.incr('user_count', function (err, reply) {
    var new_user_id = reply;
    client.lpush('user_ids', new_user_id);
    client.hset('user:' + new_user_id, 'username', req.param('username'), redis.print);
    client.quit();
    res.redirect('/');
});

所以在这一点上,我希望我的数据库看起来像:

user_ids
1
2

user:1 username 'Guy One'
user:2 username 'Guy Two'

这很好用。但我现在坚持的是生成完整的用户表。我遍历user_ids,并为每一个提取相应的user哈希条目。

这种方法除了看起来非常低效(每个用户密钥的单独查询)之外,由于node_redis异步执行getter调用,因此也存在问题。因此,每个getter必须在其成功回调中调用下一个getter等。非常长嵌套回调getter。

这是我最初尝试过的:

var usernamesList = new Array();
client.lrange('user_ids', 0, -1, function (err, reply) {
    var userIdsList = (reply == null || reply == undefined) ? new Array() : reply;
    for (var userId in userIdsList) {
        usernamesList.push(client.hget('user:' + userId, 'username'));
    }
    res.render('users', { usernames: usernamesList });
});

但如上所述,它不仅效率低下,而且无法正常工作,因为hget()方法的第三个参数(目前不存在)实际上应该是是一个回调,然后应该hget()调用userIdsList中的下一个项目等。

hget()返回值是一个布尔值。因此,我上面编写的方法只返回一个数组:[true, true]

所以我的问题:

  1. 这是执行/构建完整用户列表和查找的正确方法吗?

  2. 如何处理每个hget()需要回调的事实?

1 个答案:

答案 0 :(得分:1)

以这种方式迭代所有用户将需要与user_ids的长度一样多的往返行程。如果您不打算使用Redis群集,则可以使用MULTI/EXEC一次性发送所有这些命令,并将结果发回一次。

client.lrange('user_ids', 0, -1, function (err, users) {
    var userIds = users || [],
      pipeline = [];
    userIds.forEach(function (userId) {
      pipeline.hget('user:' + userId, 'username');
    });
    pipeline.exec(function (err, users) {
      res.render('users', { usernames: users);
    });
});

如果您的users表包含单个字段(用户名),则可以使用单个哈希来存储所有用户。

集:

client.incr('users_count', function (err, count) {
  client.hset('users', count, req.param('username'));
});

向上看:

client.hgetall('users', function (err, users) {
  res.render('users', users);
});

另一种方法是使用lua脚本,但由于要查找的用户密钥是动态生成的,因此无法与redis群集很好地协同工作,并且群集要求服务器访问的所有密钥都在同一个redis实例。