[英]Spring boot caching with redis,key have \xac\xed\x00\x05t\x00\x06
I want to use Spring cache @Cacheable to manager cache.我想使用 Spring 缓存 @Cacheable 来管理缓存。 And the real cache is redis.
而真正的缓存是redis。
my code like that:我的代码是这样的:
@PostMapping("/post")
@CachePut(value = "abc", key = "#key")
public String putInRedis(@RequestParam String key, @RequestParam String value) {
saveInDB(key, value);
return value;
}
@GetMapping("/get")
@Cacheable(value = "abc", key = "#key")
public String queryRedis(@RequestParam String key) {
return findByKey(key);
}
After I have the post request which is在我收到帖子请求之后
localhost:8080/post?key=key&value=value
本地主机:8080/post?key=key&value=value
the redis server appear a weird key redis 服务器出现一个奇怪的key
127.0.0.1:6379> keys *
1) "abc:\xac\xed\x00\x05t\x00\x03key"
127.0.0.1:6379> GET "abc:\xac\xed\x00\x05t\x00\x03key"
"\xac\xed\x00\x05t\x00\x05value"
weird-redis-key-with-spring-data-jedis 奇怪的redis-key-with-spring-data-jedis
how to set @Cacheable's Serializer like StringRedisTemplate default:如何设置@Cacheable 的 Serializer 像 StringRedisTemplate 默认值:
public StringRedisTemplate() {
RedisSerializer<String> stringSerializer = new StringRedisSerializer();
setKeySerializer(stringSerializer);
setValueSerializer(stringSerializer);
setHashKeySerializer(stringSerializer);
setHashValueSerializer(stringSerializer);
}
my application.properties:我的 application.properties:
spring.redis.host=localhost
spring.redis.password=
spring.redis.port=6379
build.gradle构建.gradle
group 'io.freezhan'
version '1.0-SNAPSHOT'
buildscript {
repositories {
maven {
url 'https://plugins.gradle.org/m2/'
}
}
dependencies {
classpath 'org.springframework.boot:spring-boot-gradle-plugin:1.4.0.RELEASE'
}
}
task wrapper(type: Wrapper) {
gradleVersion = '2.13'
distributionUrl = "https://services.gradle.org/distributions/gradle-$gradleVersion-all.zip"
}
apply plugin: 'java'
apply plugin: 'spring-boot'
sourceCompatibility = 1.5
repositories {
mavenCentral()
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-web") {
exclude module: "spring-boot-starter-tomcat"
}
compile("org.springframework.boot:spring-boot-starter-data-redis")
compile("org.springframework.boot:spring-boot-starter-jetty")
compile("org.springframework.boot:spring-boot-starter-actuator")
compile 'org.projectlombok:lombok:1.16.10'
testCompile("junit:junit")
}
Create a redis template 创建一个Redis模板
private RedisTemplate<String, ?> createRedisTemplateForEntity() {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
redisTemplate.setConnectionFactory(getRedisConnectionFactory());
redisTemplate.setHashValueSerializer(new StringRedisSerializer());
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
Why is it creating a weird string as key? 为什么要创建一个奇怪的字符串作为键?
The key is created based on the argument attributes present in your method which is annotated as cacheable. 密钥是根据方法中存在的参数属性创建的,该属性被注释为可缓存。 This is how spring reads the cache value from redis.
这就是spring从redis读取缓存值的方式。
The caching - feature of Spring allows to use different cache - implementations. Spring的缓存功能允许使用不同的缓存实现。 One of them is Redis.
Redis是其中之一。 It can be used with the class
RedisCacheManager
. 它可以与类
RedisCacheManager
一起使用。 The Spring documentation says: Spring文档说:
If Redis is available and configured, the
RedisCacheManager
is auto-configured.如果Redis可用并已配置,则
RedisCacheManager
将自动配置。
This is the approach that I propose to influence the Redis - caching - integration: 这是我建议影响Redis(缓存)集成的方法:
Define the RedisCacheManager
as bean on your own. 自己将
RedisCacheManager
定义为bean。
Pass the RedisTemplate
to the constructor of RedisCacheManager
. 将
RedisTemplate
传递给RedisTemplate
的构造RedisCacheManager
。
I found an example for this on the Internet using a programmmatic configuration. 我在Internet上使用编程配置找到了一个示例 。 There is also an example using XML-based configuration.
还有一个使用基于XML的配置的示例 。
like mm759's answer: 就像mm759的答案:
Define the RedisCacheManager as bean on your own. 自己将RedisCacheManager定义为bean。
this code will solve my problem: 此代码将解决我的问题:
package io;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
* Created by freezhan on 16/9/5.
*/
@Configuration
public class CacheConfig {
@Autowired
private StringRedisTemplate redisTemplate;
@Bean
public CacheManager cacheManager() {
RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
return cacheManager;
}
}
and the redis store like this: 和redis存储是这样的:
Here are my two cents.这是我的两分钱。 🪙🏛️
🪙🏛️
TL;DR TL; 博士
Suppose you are looking for a solution to delete all those weird keys.假设您正在寻找一种解决方案来删除所有这些奇怪的键。 Don't waste time composing a one-line bash solution.
不要浪费时间编写单行 bash 解决方案。 This won't work,
redis-cli KEYS "user*" | xargs redis-cli DEL
这行不通,
redis-cli KEYS "user*" | xargs redis-cli DEL
redis-cli KEYS "user*" | xargs redis-cli DEL
(source: How do I remove keys? ). redis-cli KEYS "user*" | xargs redis-cli DEL
(来源: 如何删除密钥? )。 Your keys are in binary format piping them won't produce the expected results.您的密钥是二进制格式的管道,它们不会产生预期的结果。 Extend the functionality of the script that created the keys to delete them as well (Think Python, Java, Go, etc.).
扩展创建密钥的脚本的功能以删除它们(Think Python、Java、Go 等)。 Alternatively, delete all keys if you can afford it
redis-cli flushall
(source: How to atomically delete keys matching a pattern using Redis或者,如果您负担得起,则删除所有键
redis-cli flushall
(来源: 如何使用 Redis 原子地删除与模式匹配的键
In terms of having your keys as binary data, I am unsure what the benefits are (repeating, binary keys, not data).就将您的密钥作为二进制数据而言,我不确定有什么好处(重复,二进制密钥,而不是数据)。 Since, it might turn out that it's less space-efficient and time-efficient than expected, at least according to these posts, does-storing-plain-text-data-take-up-less-space-than-storing-the-equivalent-mess , are-binary-storage-methods-more-efficient-than-text-based-ones .
因为,结果可能证明它的空间效率和时间效率低于预期,至少根据这些帖子, do-storing-plain-text-data-take-up-less-space-than-storing-the-等效混乱, are-binary-storage-methods-more-efficient-than-text-based-ones 。 Of course, if you have converted your keys on purpose.
当然,如果您有意转换了密钥。
If you wish to have your keys in string format, on the Redis template, set the key serializer as a StringRedisSerializer
, as pointed out in the answer by @Rohith K .如果您希望将密钥设为字符串格式,请在 Redis 模板上将密钥序列化器设置为
StringRedisSerializer
,如@Rohith K的回答中所指出的。 This would enable you to delete keys by using the pattern matching command quoted above.这将使您能够使用上面引用的模式匹配命令来删除键。
redisTemplate.setKeySerializer(new StringRedisSerializer());
Finally, here are some more discussions about how those funny symbols, "\\xac\\xed\\x00\\x05t\\x00:"
, got prepended to your Redis keys:最后,这里有更多关于这些有趣的符号
"\\xac\\xed\\x00\\x05t\\x00:"
是如何添加到您的 Redis 键的讨论:
I hope this post saves you some time.我希望这篇文章可以为您节省一些时间。 Happy coding 🔥
快乐编码🔥
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.