Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between the key and hash key parameters used in a Redis put() statement?

I have a Java Spring Boot app that uses Redis for storage. I have done a fair amount of web searching but I can't find an easy to digest text that explains in detail the ramifications of what values to use/choose for the key parameter vs. the hash key parameter in a Redis put(key, hash key, object) statement. I am using the Redis store to store a short-lived session management objects that are particular to a specific user ID, and that user ID is guaranteed to be unique. The object value is a JSON encoded string for a particular class object:

// String format template for storing objects of this class.
public static final String STORE_MULTI_SELECT_CHOICES = "%s:store:multi_select_choices"

// Store it in Redis for access during the next interaction with the user.
// The key is the hash key prefix for the MultiSelectChoices class, followed
//   by the user ID.
String key = String.format(MultiSelectChoices.STORE_MULTI_SELECT_CHOICES, userId)

// The hash key is just the user ID for now.
String hashKey = userId

// Serialize the multi-select session management object to a JSON string.
Gson gson = new Gson();
String jsonRedisValue = gson.toJson(multiSelect);
redisTemplate.opsForHash().put(key, hashKey, jsonRedisValue)

What is the difference between these two parameters and do you know of a document that explains the performance and value collision ramifications of different choices? Also, given the nature of my storage operation, do I need to worry about Redis shards or other expert level details or can I reasonably ignore them for now? The app once put in production, will face a high traffic load.

like image 481
Robert Oschler Avatar asked Sep 05 '17 19:09

Robert Oschler


1 Answers

basically in your scenario:

your key is: userid:store:multi_select_choices
your hashkey is: userid
and your options objects serialized into jsonRedisValue

in this case, you don't need to use:

redisTemplate.opsForHash().put(key, hashKey, jsonRedisValue)

instead you should use:

redisTemplate.opsForValue().put(key, jsonRedisValue)

here is a very good example for you to understand the scenario where opsForHash making sense:

first you must understand that hashes in redis is perfect representation for objects, so you don't need to serialize the object, but just store the object in the format of multiple key-value pairs, like for a userid=1000, the object has properties: username/password/age, you can simply store it on redis like this:

redisTemplate.opsForHash().put("userid:1000", "username", "Liu Yue")
redisTemplate.opsForHash().put("userid:1000", "password", "123456")
redisTemplate.opsForHash().put("userid:1000", "age", "32")

later on if you want to change the password, just do this:

redisTemplate.opsForHash().put("userid:1000", "password", "654321")

and the corresponding cmd using redis-cli:

HMSET userid:1000 username 'Liu Yue' password '123456' age 32
HGETALL userid:1000
1) "username"
2) "Liu Yue"
3) "password"
4) "123456"
5) "age"
6) "32"
HSET userid:1000 password '654321'
HGETALL userid:1000
1) "username"
2) "Liu Yue"
3) "password"
4) "654321"
5) "age"
6) "32"

I haven't explore too much the fundamental of how it implement hashes operation, but I think the difference between key and hashkey is quite obvious based on the documentation, key is just like the other redis key, normal string, hashkey is for the purpose of optimize the storage of the mutliple key-value pairs, so I guess there must be some kind of hash algorithm behind to ensure optimal memory storage and faster query and update.

and it's well documented here:

https://redis.io/topics/data-types

https://redis.io/topics/data-types-intro

like image 97
LIU YUE Avatar answered Oct 13 '22 10:10

LIU YUE