This is the 12th day of my participation in the August More Text Challenge. For details, see:August is more challenging
preface
It is also a problem encountered today. Record some problems encountered in the newly built project using SpringRedisTemplate, and summarize the relevant knowledge.
Problem description
Two problems, 1. While on a self-test call stringRedisTemplate. OpsForValue () get (key) is very time consuming, has been stuck. 2. Serialization problems
The cause of the problem is actually a relatively low level of the problem, but also to some of the framework of the principle of understanding some deviation. In the business scenario, we use the Bloom filter to filter some urls, but the bloom filter needs to expire periodically (because the data volume is large and keeps increasing). Key: set to bloom:filter:202108 value: bloom:filter:202108 value: Bloom :filter:202108 Then take value as the name of the Bloom filter to determine whether the Bloom filter exists.
@Test
public void test(a) {
String key = "bloom:filter:202108";
stringRedisTemplate.opsForValue().set(key, key, 100l, TimeUnit.SECONDS);
String res = stringRedisTemplate.opsForValue().get(key);
RBloomFilter<String> filter = redisson.getBloomFilter(key);
filter.tryInit(100000000.0.001);
filter.add("iyixh");
System.out.println(filter.contains("123as"));
System.out.println(res);
}
Copy the code
Bloom :filter:202108; bloom:filter:202108}:config,
Bloom :filter:202108 the redis value of the bloom:filter:202108 key appears to be the size of the bloomFilter.
Bloom :filter:202108 {bloom:filter:202108}:config {bloom:filter:202108}:config
We know that the underlying data structure is a bitmap array, and we set the size to 168.23m, which is the C code at the bottom.
Therefore, when we set the cache key, we should not have the same name as the Bloom filter to prevent the underlying data structure from changing.
Talk about redisTemplate and stringRedisTemplate
Why do you need two templates? What’s the difference?
2.1. Comparison
stringRedisTemplate
- The StringRedisSerializer is used to store strings. The generic type StringRedisSerializer specifies a String. Error: can not cast into String: can not cast into String
- High visibility and easy maintenance. Consider using the StringRedisTemplate if you’re using string storage.
redisTemplate
- Can be used to store objects, but implement the Serializable interface.
- Stored as a binary array, the contents are not readable.
2.2 Serialization of redisTemplate
Spring-data-redis offers the following options:
- GenericToStringSerializer: any object can be generalized to a string and serialization
- With JacksonJsonRedisSerializer Jackson2JsonRedisSerializer: in fact is the same
- JacksonJsonRedisSerializer: serialized object to a json string
- JdkSerializationRedisSerializer: serialized Java objects
- StringRedisSerializer: simple string serializer
2.2.1 test
@Test
public void testSerial(a){
User user = new User();
user.setId(1001L);
user.setName("Test");
user.setAge(18);
List<Object> list = new ArrayList<>();
for(int i=0; i<200; i++){ list.add(user); } JdkSerializationRedisSerializer jdkSerialize =new JdkSerializationRedisSerializer();
GenericJackson2JsonRedisSerializer g = new GenericJackson2JsonRedisSerializer();
Jackson2JsonRedisSerializer jackson2 = new Jackson2JsonRedisSerializer(List.class);
Long j_s_start = System.currentTimeMillis();
byte[] bytesJ = jdkSerialize.serialize(list);
System.out.println("JdkSerializationRedisSerializer serialization time."+(System.currentTimeMillis()-j_s_start) + "Ms, serialized length:" + bytesJ.length);
Long j_d_start = System.currentTimeMillis();
jdkSerialize.deserialize(bytesJ);
System.out.println("JdkSerializationRedisSerializer deserialization time:"+(System.currentTimeMillis()-j_d_start));
Long g_s_start = System.currentTimeMillis();
byte[] bytesG = g.serialize(list);
System.out.println("GenericJackson2JsonRedisSerializer serialization time."+(System.currentTimeMillis()-g_s_start) + "Ms, serialized length:" + bytesG.length);
Long g_d_start = System.currentTimeMillis();
g.deserialize(bytesG);
System.out.println("GenericJackson2JsonRedisSerializer deserialization time:"+(System.currentTimeMillis()-g_d_start));
Long j2_s_start = System.currentTimeMillis();
byte[] bytesJ2 = jackson2.serialize(list);
System.out.println("Jackson2JsonRedisSerializer serialization time."+(System.currentTimeMillis()-j2_s_start) + "Ms, serialized length:" + bytesJ2.length);
Long j2_d_start = System.currentTimeMillis();
jackson2.deserialize(bytesJ2);
System.out.println("Jackson2JsonRedisSerializer deserialization time:"+(System.currentTimeMillis()-j2_d_start));
}
Copy the code
2.2.2 summarizes
- JdkSerializationRedisSerializer serialized minimum length, Jackson2JsonRedisSerializer highest efficiency.
- If efficiency and readability are taken into account, StringRedisSerializer is recommended to sacrifice some space for keys, so that keys can be kept concise and readable. The value can use Jackson2JsonRedisSerializer
- If space is sensitive and efficiency is not high, StringRedisSerializer is recommended for keys to keep them simple and readable. The value can use JdkSerializationRedisSerializer
The last
The process of architecture is actually a process of continuous comparison and selection, different application scenarios have different technology selection.