0

I am able to add and get a particular user object from Redis I am adding object like this:

 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); 
 }

If a userId is 100 I am able to get by key: SERVER1:USER:100
Now I want to retrieve all Users as Map<String,List<User>> ,
For example, get all users by this key SERVER1:USER:
Is it possible ? Or I need to modify my addUserToRedis method? Please suggest me.

asked Sep 21, 2020 at 10:19
2
  • 1
    You can do a wildcard search. "SERVER:USER:*". Check pattern search in redis Commented Sep 21, 2020 at 11:46
  • It's working with wildcard searches. Commented Sep 21, 2020 at 12:32

3 Answers 3

2

I would recommend not using the "KEYS" command in production as this can severely impact REDIS latencies (can even bring down the cluster if you have a large number of keys stored)
Instead, you would want to use a different command than plain GET/SET.

It would be better if you use a Sets or 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>

Using sets you can simply add your users to server keys and get the entire list of users on a server.

If you really need a map of < server, list < users > > you can use hashes with stringified user data and then convert it to actual User POJO at application layer

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>

Also do note that keeping this much big data into a single key is not an ideal thing to do.

answered Sep 21, 2020 at 17:32
Sign up to request clarification or add additional context in comments.

Comments

1

i dont use java but here's how to use 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()
answered Sep 22, 2020 at 10:14

Comments

1

Finally I came up with this solution with wildcard search and avoiding KEYS, and here is my complete method:

 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;
 }
answered Sep 21, 2020 at 15:43

5 Comments

KEYS would block redis server. if must, you can try using SCAN
@TuanAnhTran can you guide me that how to use with redisTemplate in this scenario, this will be very helpful
I dont use java but here's how to do it with nodejs stackoverflow.com/a/64007618/2688699
@TuanAnhTran I edited my answer to avoid using KEYS, now I am using SCAN. This one is fine?
yeah should be fine. you can test by creating few millions key and see for your self :)

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.