node.js - 使用 Redis 进行用户查找表

标签 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()的第三个参数(目前不存在)方法实际上应该是一个回调,然后应该为 userIdsList 中的下一个项目调用 hget(),等等。

hget()返回值 是一个 bool 值。结果,我上面写的方法只返回一个数组:[true, true]

所以我的问题:

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

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

最佳答案

以这种方式遍历所有用户需要的往返次数与 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);
    });
});

如果您的用户表由单个字段(用户名)组成,您可以使用单个哈希来存储所有用户。

设置:

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 集群一起使用,因为要查找的用户 key 是动态生成的,并且集群要求服务器访问的所有 key 都在同一个 redis 实例上.

关于node.js - 使用 Redis 进行用户查找表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27090388/

相关文章:

Node.js everyauth集群错误

javascript - Passport 未知认证策略

c# - 使用 StackExchange.Redis 时,如何在 RedisValue 之上维护 C# 原始类型

asp.net-mvc - 如何将客户类对象数据存储到 Redis 缓存中?

javascript - 在 node.js 中实时观看外部内容

node.js + express 3 + socket.io = 发送后无法设置 header

javascript - NodeJS中传递回调函数变成Object

java - 错误 : Logcat capture failed: spawn ENOENT

javascript - 处理并保持 node.js/express session

javascript - 如何在 Express 中使用 haml.js 呈现 HAML 模板