使用Redis进行用户查找表
我正在学习Redis,我正在使用一个简单的users
表。 我正在通过node_redis
与Redis进行node_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调用是asynchronous执行的。 所以每个getter都必须在成功callback中调用下一个getter,等等。一个非常长的嵌套callbackgetter的链。
这是我最初尝试的:
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()
方法的第三个参数(当前不存在)实际上应该是一个callbackhget()
,然后它应该调用hget()
userIdsList
项目等
hget()
的返回值是一个布尔值。 因此,我上面写的方法只返回一个数组: [true, true]
所以我的问题:
-
这是正确的方式来执行/构build一个完整的用户列表和查找?
-
如何改进以处理每个
hget()
需要callback的事实?
以这种方式迭代所有用户将需要与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脚本,但是由于要查找的用户密钥是dynamic生成的,并且群集要求服务器访问的所有密钥位于同一个redis实例上,所以不能很好地与redis群集配合使用。