问题描述
我能够从Redis添加并获取特定的用户对象,我正在添加对象,如下所示:
private static final String USER_PREFIX = ":USER:";
public void addUserToRedis(String serverName,User user) {
redistemplate.opsForHash().put(serverName + USER_PREFIX + user.getId(),Integer.toString(user.getId()),user);
}
如果userId为100,则可以通过键获取: SERVER1:USER:100
现在,我想以Map<String,List<User>>
的身份检索所有用户,
例如,通过此键 SERVER1:USER:
可以获取所有用户吗?或者我需要修改我的 addUserToRedis 方法?请建议我。
解决方法
我建议不要在生产环境中使用“ KEYS”命令,因为这会严重影响REDIS延迟(can even bring down the cluster if you have a large number of keys stored)
相反,您可能想使用与普通GET / SET不同的命令。
如果使用Sets或Hashes
127.0.0.1:6379> sadd server1 user1 user2
(integer) 2
127.0.0.1:6379> smembers server1
1) "user2"
2) "user1"
127.0.0.1:6379>
使用集,您可以简单地将用户添加到服务器密钥,并获取服务器上的整个用户列表。
如果您确实需要< server,list < users > >
的映射,则可以使用带有字符串化用户数据的哈希,然后在应用程序层将其转换为实际的User
POJO
127.0.0.1:6379> hset server2 user11 name
(integer) 1
127.0.0.1:6379> hset server2 user13 name
(integer) 1
127.0.0.1:6379> hgetall server2
1) "user11"
2) "name"
3) "user13"
4) "name"
127.0.0.1:6379>
还要注意,将这么大的数据保存到单个密钥中并不是理想的事情。
,最后,我想出了通配符搜索并避免使用KEYS的解决方案,这是我的完整方法:
public Map<String,User> getUserMapFromRedis(String serverName){
Map<String,User> users=new HashMap<>();
RedisConnection redisConnection = null;
try {
redisConnection = redisTemplate.getConnectionFactory().getConnection();
ScanOptions options = ScanOptions.scanOptions().match(serverName + USER_PREFIX+"*").build();
Cursor<byte[]> scan = redisConnection.scan(options);
while (scan.hasNext()) {
byte[] next = scan.next();
String key = new String(next,StandardCharsets.UTF_8);
String[] keyArray=key.split(":");
String userId=keyArray[2];
User user=//get User by userId From Redis
users.put(userId,user);
}
try {
scan.close();
} catch (IOException e) {
}
}finally {
redisConnection.close(); //Ensure closing this connection.
}
return users;
}
,
我不使用Java,但这是使用SCAN的方法
const Redis = require('ioredis')
const redis = new Redis()
async function main() {
const stream = redis.scanStream({
match: "*:user:*",count: 100,})
stream.on("data",(resultKeys) => {
for (let i = 0; i < resultKeys.length; i++) {
// console.log(resultKeys[i])
// do your things here
}
});
stream.on("end",() => {
console.log("all keys have been visited");
});
}
main()