Recently I have been using spring-boot-starter-data-redis;
I use spring-boot-version:2.3.8.RELEASE;
application.yml
spring:
redis:
cluster:
nodes:
- 10.253.48.212:6379
- 10.253.48.212:6380
- 10.253.48.213:6379
- 10.253.48.213:6380
- 10.253.48.214:6379
- 10.253.48.214:6380
I set up Redis-Cluster according to the article; https://redis.io/topics/cluster-tutorial
The setup process was also recorded in additor;although the notes were in Chinese;
I follow the article spring-data-redis to use Redis-Client;
I wrote the code based on the [10.6. Working with Objects through RedisTemplate];
But there was a problem with redisTemplate and stringRedisTemplate;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {RedisApp.class})
public class RedisTest {
@Resource(name="stringRedisTemplate")
private ValueOperations<String, String> stringValueOperations;
@Resource(name="redisTemplate")
private ValueOperations<String, String> valueOperations;
@Test
public void test() {
stringValueOperations.set("name", "yufr-bigName");
valueOperations.set("name", "yufr");
System.out.println(stringValueOperations.get("name"));
System.out.println(valueOperations.get("name"));
}
}
result in idea-console:
yufr-bigName
yufr
result in redis-cluster-server:
10.253.48.214:6379> get name
"yufr-bigName"
why redisTemplate set-command does not work?
RedisSerializer serialize the key "name" to other key, so redisTemplate doesn't seem to work;
The key code is RedisSerializer;
byte[] rawKey(Object key) {
Assert.notNull(key, "non null key required");
if (keySerializer() == null && key instanceof byte[]) {
return (byte[]) key;
}
return keySerializer().serialize(key);
}
byte[] rawValue(Object value) {
if (valueSerializer() == null && value instanceof byte[]) {
return (byte[]) value;
}
return valueSerializer().serialize(value);
}
the defaultSerializer is JdkSerializationRedisSerializer
class RedisTemplate ... {
...
public void afterPropertiesSet() {
super.afterPropertiesSet();
boolean defaultUsed = false;
if (defaultSerializer == null) {
defaultSerializer = new JdkSerializationRedisSerializer(
classLoader != null ? classLoader : this.getClass().getClassLoader());
}
if (enableDefaultSerializer) {
if (keySerializer == null) {
keySerializer = defaultSerializer;
defaultUsed = true;
}
if (valueSerializer == null) {
valueSerializer = defaultSerializer;
defaultUsed = true;
}
...
}
}
}
the final serializer is org.springframework.core.serializer.DefaultSerializer
public void serialize(Object object, OutputStream outputStream) throws IOException {
if (!(object instanceof Serializable)) {
throw new IllegalArgumentException(getClass().getSimpleName() + " requires a Serializable payload " +
"but received an object of type [" + object.getClass().getName() + "]");
}
ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
objectOutputStream.writeObject(object);
objectOutputStream.flush();
}
so the string key "name" will be processed by objectOutputStream;
@Test
public void serialize() {
ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(out)) {
objectOutputStream.writeObject("name");
objectOutputStream.flush();
} catch (IOException ioException) {
}
// �� t name
System.out.println(new String(out.toByteArray()));
}
so that valueOperations.set("name", "yufr"); does not work!