我想为存储在Redis中的密钥设置一个ttl,我已按以下方式完成:
@Component
public class RedisBetgeniusMarketService implements BetgeniusMarketService {
private static final int DEFAULT_EVENTS_LIFE_TIME = 240;
@Value("${redis.events.lifetime}")
private long eventsLifeTime = DEFAULT_EVENTS_LIFE_TIME;
@Autowired
private RedisTemplate<String, Market> marketTemplate;
@Override
public Market findOne(Integer fixtureId, Long marketId) {
String key = buildKey(fixtureId, marketId);
return marketTemplate.boundValueOps(key).get();
}
@Override
public void save(Integer fixtureId, Market market) {
String key = buildKey(fixtureId, market.getId());
BoundValueOperations<String, Market> boundValueOperations = marketTemplate.boundValueOps(key);
boundValueOperations.expire(eventsLifeTime, TimeUnit.MINUTES);
boundValueOperations.set(market);
}
private String buildKey(Integer fixtureId, Long marketId) {
return "market:" + fixtureId + ":" + marketId;
} …Run Code Online (Sandbox Code Playgroud) 我在Spring Boot应用程序中遇到性能问题,当它与Redis通信时,我希望有专门知识的人能够对此有所了解.
什么,我试图做解释
总之,我的应用程序有2个嵌套的地图,我要保存到Redis的,并需要数据时回加载到应用程序列表中的3张地图.第一个嵌套映射中的数据相当大,具有几个级别的非原始数据类型(以及这些类型的列表).目前,我使用存储库和Redis Hashes,使用存储库A,B和C在Redis中构建数据,并在A中使用两种不同的方式查找主数据类型(MyClass).B和C包含引用的数据来自A中的值(带@Reference注释).
性能分析
使用的JProfiler,我发现,瓶颈是我的电话之间的某处a.findOne(),并阅读来自Redis的响应(从任何转换之前结束byte[]对MyClass已经发生).我查看了我的Redis服务器上的slowlog来检查任何缓慢和阻塞的操作,但没有找到.HGETALLRedis中的每个命令平均需要400μs(对于A中的完整哈希,包括在B和C中查找引用的哈希值).让我感到奇怪的是,a.findOne()对于一个单一实例,调用的时间需要5-20ms MyClass,具体取决于B和C中的哈希值有多大.当包括对B和C的引用时,单个实例总共具有约2500个哈希字段.如果在第一个嵌套映射上完成了大约900次,我必须等待10秒才能获得所有数据,这太长了.相比之下,另一个嵌套的嵌套映射(没有引用C(数据的最大部分))在Redis中定时为~10μs,在Java中定时为<1ms.
当Redis实例在与Spring Boot应用程序相同的2015 MacBook Pro上本地运行时,此分析是否看起来像是正常行为?我知道完整的findOne()方法完成比HGETALLRedis中的实际命令需要更长的时间,但我不明白为什么差异很大.如果有人能够对Jedis连接代码中引发的内容的性能有所了解,我会很感激.
Java中我的数据结构示例
@RedisHash("myClass")
public class MyClass {
@Id
private String id;
private Date date;
private Integer someValue;
@Reference
private Set<C> cs;
private someClass someObject;
private int somePrimitive;
private anotherClass anotherObject;
@Reference
private B b;
Run Code Online (Sandbox Code Playgroud)
C类摘录(为清晰起见,删除了一些基元):
@RedisHash("c")
public class C implements Comparable<BasketValue>, Serializable {
@Id
private String id;
private EnumClass someEnum; …Run Code Online (Sandbox Code Playgroud) 我的弹簧启动项目配置如下.
@SpringBootApplication
@EnableTransactionManagement
@EnableCaching
@EnableScheduling
@EnableAsync
public class Application {
String redisHost = "localhost";
int redisPort = 6379;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
JedisConnectionFactory jedisConnectionFactory() {
JedisConnectionFactory factory = new JedisConnectionFactory();
factory.setHostName(redisHost);
factory.setPort(redisPort);
factory.setUsePool(true);
return factory;
}
@Bean
RedisTemplate<Object, Object> redisTemplate() {
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<Object, Object>();
redisTemplate.setConnectionFactory(jedisConnectionFactory());
return redisTemplate;
}
@Bean
public CacheManager cacheManager() {
RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate());
return cacheManager;
}
}
Run Code Online (Sandbox Code Playgroud)
我也跟随maven对pom的依赖.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
Run Code Online (Sandbox Code Playgroud)
我在定义端口上的本地计算机上运行了一个单独的redis服务器.另外在我的服务类中,我有@Cacheable,@ CachePut等注释来支持缓存.
我可以毫无错误地启动Spring启动应用程序,并且CRUD操作也可以.但似乎它没有使用定义的redis缓存.我使用'redi …
在spring-data-redis中,我们如何配置可以从Spring启动应用程序或配置自动连接/注入的自定义转换器.
我从spring data redis文档中读到了@ReadingConverter和@WritingConverter.从该文档中,不清楚如何配置它们. https://github.com/spring-projects/spring-data-redis/blob/master/src/main/asciidoc/reference/redis-repositories.adoc#redis.repositories.indexes
有谁知道怎么做?
java distributed-caching redis spring-data spring-data-redis
我每 5 分钟运行一次批处理作业,并且我不希望其他节点运行相同的作业,因此我使用 Jedis 锁来锁定对象 5 分钟。这样,如果其他节点尝试运行相同的作业,它们将不会获得锁定。作业在获取锁后开始,当我尝试从 Redis 读取它时,出现以下异常:
'Caused by: redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
at redis.clients.util.Pool.getResource(Pool.java:53)
at redis.clients.jedis.JedisPool.getResource(JedisPool.java:226)
at redis.clients.jedis.JedisPool.getResource(JedisPool.java:16)
at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.fetchJedisConnector(JedisConnectionFactory.java:194)
... 40 more
Caused by: redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: Read timed out
at redis.clients.jedis.Connection.disconnect(Connection.java:224)
at redis.clients.jedis.BinaryClient.disconnect(BinaryClient.java:941)
at redis.clients.jedis.Connection.close(Connection.java:214)
at redis.clients.jedis.BinaryClient.close(BinaryClient.java:947)
at redis.clients.jedis.Jedis.close(Jedis.java:3412)
at redis.clients.jedis.JedisFactory.makeObject(JedisFactory.java:117)
at org.apache.commons.pool2.impl.GenericObjectPool.create(GenericObjectPool.java:836)
at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:434)
at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:361)
at redis.clients.util.Pool.getResource(Pool.java:49)'
Run Code Online (Sandbox Code Playgroud)
这就是我的代码
@Bean
public Jedis getJedis()
{
Jedis jedis = new Jedis(this.redisHost, nteger.valueOf(this.redisPort));
jedis.auth(this.redisPassword);
return jedis;
}
Run Code Online (Sandbox Code Playgroud)
spring-boot Application.properties 文件
# DATA REDIS …Run Code Online (Sandbox Code Playgroud) 我目前正在将 Redis (3.2.100) 与 Spring data redis (1.8.9) 和 Jedis 连接器一起使用。当我对现有实体使用 save() 函数时,Redis 会删除我的实体并重新创建该实体。
就我而言,我需要保留这个现有实体并且仅更新实体的属性。(我有另一个线程同时读取同一实体)
在Spring文档(https://docs.spring.io/spring-data/data-redis/docs/current/reference/html/#redis.repositories.partial-updates)中,我发现了部分更新功能。不幸的是,文档中的示例使用了 RedisTemplate 的 update() 方法。但这种方法不存在。
那么你使用过 Spring-data-redis 部分更新吗?
还有另一种方法可以更新实体redis而不需要删除之前吗?
谢谢
我正在使用Spring引导。为了将我的实体保存在关系数据库上,我配置了一个数据源和我的域类,例如:
@Entity
@Table(schema = "schema_name", name = "tb_name")
public class table_name extends DomainEntity<Long> {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "ID_TABLE_NAME", nullable = false, updatable = false, precision = 12)
@SequenceGenerator(name = "sqTableName", sequenceName = "SQ_TABLE_NAME", initialValue = 1, allocationSize = 1)
@GeneratedValue(generator = "sqTableName", strategy = GenerationType.SEQUENCE)
private Long id;
@NotNull
@ManyToOne
@JoinColumn(name = "ID_OTHER_COLUMN", referencedColumnName = "ID_OTHER_COLUMN", nullable = false)
private OtherObject obj;
Run Code Online (Sandbox Code Playgroud)
使用本教程: https: //www.baeldung.com/spring-data-redis-tutorial,我配置了我的域类 Student:
@RedisHash("Student")
public class Student implements Serializable …Run Code Online (Sandbox Code Playgroud) 我正在使用Spring Data Redis示例Spring Boot 2.0。在此示例中,我尝试将客户数据 + 学生数据保存在一起。我不太确定这里的数据建模是如何发生的,但假设它与 Mongo DB 相同(纯非关系)。
有人可以帮忙解决以下错误吗?很明显,预计会出现一些转换以看到数据。
错误:
org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [com.javasampleapproach.redis.model.Customer] to type [java.lang.String]
at org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:321)
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:194)
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:174)
at org.springframework.data.redis.serializer.GenericToStringSerializer$Converter.convert(GenericToStringSerializer.java:120)
at org.springframework.data.redis.serializer.GenericToStringSerializer.serialize(GenericToStringSerializer.java:88)
at org.springframework.data.redis.core.AbstractOperations.rawHashValue(AbstractOperations.java:184)
at org.springframework.data.redis.core.DefaultHashOperations.put(DefaultHashOperations.java:175)
at com.javasampleapproach.redis.repository.CustomerRepositoryImpl.save(CustomerRepositoryImpl.java:33)
at com.javasampleapproach.redis.repository.CustomerRepositoryImpl$$FastClassBySpringCGLIB$$88e26a2c.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:746)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
at com.javasampleapproach.redis.repository.CustomerRepositoryImpl$$EnhancerBySpringCGLIB$$7d20fd4e.save(<generated>)
at com.javasampleapproach.controller.WebController.save(WebController.java:31)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
at …Run Code Online (Sandbox Code Playgroud) 我在网上搜索了很多以获得@EnableRedisRepositories的更多实际用法,但我没有找到任何。即使在我的Spring Boot + Spring Data Redis示例中,我删除了@EnableRedisRepositories但仍然不明白它有什么区别,但我仍然可以看到数据持久保存到数据库中并正常检索。
有人可以澄清一下吗?
我浏览了这个注释,但不是很清楚..
用于激活 Redis 存储库的注释。如果没有通过{@link #value()}、{@link #basePackages()}或{@link #basePackageClasses()}配置基础包,它将触发对带注释的类的包的扫描。
我正在使用 Spring Session Redis Data(使用自动配置进行配置,到目前为止没有自定义),它默认用作FindByIndexNameSessionRepository实现SessionRepository。
但是,有时在 Redis 中(在会话已过期但未执行注销之后),前缀为 的密钥的spring:session:index:org.springframework.session.FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME:TTL 仍为 -1,这意味着 Redis 不会使该密钥过期。
为什么 Spring Session(Redis 数据)在会话过期时不清理这个键?我在文档中也找不到提及。
我已按照文档中所述将带有主体名称的属性存储到会话中,但这并不能解决此问题。有关详细信息,请参阅https://docs.spring.io/spring-session/reference/api.html#api-findbyindexnamesessionrepository。
使用的Redis版本:6.2.6(bitnami/redis的docker镜像:6.2.6)
相关依赖:
我不希望索引持久化的原因是,如果有很多用户至少登录过一次并且有一个密钥持久化到Redis(其作用类似于索引),那么Redis将不得不存储可能无法访问的数据很长一段时间(或根本没有)。
spring-security spring-data-redis spring-boot spring-session
redis ×8
spring-boot ×5
java ×4
jedis ×4
spring ×3
spring-data ×2
performance ×1
spring-cache ×1