我想为存储在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-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
我从 docker 设置了一个 Redis 主/从/哨兵,这是我的 docker-compose.yml
redis-master:
image: redis:3
ports:
- 6380:6379
redis-slave:
image: redis:3
ports:
- 6381:6379
command: redis-server --slaveof redis-master 6379
deploy:
replicas: 2
redis-sentinel:
image: mengli/redis-sentinel
ports:
- 26379:26379
deploy:
replicas: 3
environment:
- MASTER_HOST=redis-mater
- SENTINEL_PORT=26379
- SENTINEL_QUORUM=2
Run Code Online (Sandbox Code Playgroud)
我想用docker连接Redis,我用的是spring-data-redis,这是我的配置:
redis:
sentinel:
master: mymaster
nodes: 127.0.0.1:26379
Run Code Online (Sandbox Code Playgroud)
但是在连接Redis时,发现ip地址为10.0.0.*,是docker中的ip地址,所以抛出了连接异常。
Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
Run Code Online (Sandbox Code Playgroud)
请告诉我如何将 Redis 与 docker 中的哨兵连接起来。谢谢
我正在开发Spring Boot + Redis示例。我从链接中获取了参考:https : //www.baeldung.com/spring-data-redis-tutorial。在这个例子中,我开发了存储库方法Student findByNameAndGender(String name, Gender gender);,甚至是Student findByName(String name);,但是在这两种情况下我都没有得到任何结果。?
任何快速帮助?Redis 查询 -
redis 127.0.0.1:6379> KEYS *
1) "Student"
2) "Student:bb4df14a-7f42-4fc3-b608-fc4b7d45109e"
3) "Student:69affaa4-e56c-49e3-9ef4-1cd7509d299b"
redis 127.0.0.1:6379>
Run Code Online (Sandbox Code Playgroud)
学生.java
@Data
@AllArgsConstructor
@Builder
@NoArgsConstructor
@RedisHash("Student")
public class Student {
public enum Gender {
MALE, FEMALE
}
private String id;
private String name;
private Gender gender;
private int grade;
}
Run Code Online (Sandbox Code Playgroud)
学生资料库.java
@Repository
public interface StudentRepository extends CrudRepository<Student, String>{
Student findByNameAndGender(String name, Gender gender);
}
Run Code Online (Sandbox Code Playgroud)
RedisConfig.java …
在 Spring Boot 2.1 中,我使用 Java 配置在配置文件中定义 RedisCacheManager bean。一切正常,但我有时想禁用它,例如在测试中。Spring Boot 提供了spring.cache.type=NONE禁用缓存的功能,根据此文档。然而,这个属性将不起作用,因为我已经定义了一个 CacheManager,因此 Spring Boot 不会配置我想要的 NoOpCacheManager (有一个@ConditionalOnMissingBean(CacheManager.class)onNoOpCacheConfiguration的优先级低于RedisCacheConfiguration)。
在定义缓存时,无论提供者是什么(例如 Caffeine),我们通常将它们定义为 beans,然后由 Spring Boot 的自动配置将其解析为SimpleCacheManager. 例如
@Bean
public Cache myCache() {
return new CaffeineCache(
"my-cache",
Caffeine.newBuilder()
.maximumSize(10)
.build());
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,这对于 Redis 来说是不可能的,因为它的Cache实现RedisCache不是公开的。
我们喜欢做的另一件事是定义一个 bean CacheManagerCustomizer<?>,例如使用 Caffeine
@Bean
public CacheManagerCustomizer<CaffeineCacheManager> caffeineCacheManager() {
return cacheManager -> cacheManager
.setCaffeine(Caffeine.newBuilder()
.expireAfterWrite(1, TimeUnit.MINUTES));
}
Run Code Online (Sandbox Code Playgroud)
同样,这对于 Redis 来说是不可能的,因为它RedisCacheManager是不可变的 …
spring spring-test spring-data-redis spring-boot spring-cache
我有一个具有以下属性的 Spring Boot 应用程序:
spring.cache.type: redis
spring.redis.host: <hostname>
spring.redis.port: <hostport>
Run Code Online (Sandbox Code Playgroud)
现在,如果远程主机发生故障,应用程序也会因连接错误而失败。在这种情况下,我的缓存不是我的应用程序的核心,但它仅用于性能,我希望 spring 简单地绕过它并转到数据库检索其数据。
我发现这可以通过定义自定义 errorHandler 方法来实现,但为了做到这一点,我必须实现 CachingConfigurer bean...但这也迫使我重写每个方法(例如缓存管理器、缓存解析器、ecc. )。
@Configuration
public class CacheConfiguration implements CachingConfigurer{
@Override
public CacheManager cacheManager() {
// TODO Auto-generated method stub
return null;
}
@Override
public CacheResolver cacheResolver() {
// TODO Auto-generated method stub
return null;
}
...
@Override
public CacheErrorHandler errorHandler() {
// the only method I need, maybe
return null;
}
Run Code Online (Sandbox Code Playgroud)
我想避免这种情况......我只需要一种方法来告诉 spring“缓存崩溃了,但没关系:假装你根本没有缓存”
我有一个包含3个主节点的Redis集群,每个主节点都有相应的从节点。我想获取集群上的锁来执行一些写操作,然后释放锁。
据我所知,要连接到集群,我们通常连接到集群中的一个节点,并在该节点上执行所有操作,该节点又处理重定向到集群中其他节点的操作。
Redis集群是否可以获取锁?[PS我正在使用Redisson客户端]从Redisson客户端中Multilock和redlock( https://github.com/redisson/redisson/wiki/8.-Distributed-locks-and-synchronizers )下的示例中,它们正在获取锁在各个节点上。
Jedis 似乎还支持集群锁定(https://github.com/kaidul/jedis-lock)。
PS:我已经广泛阅读了这方面的内容,但我无法找到有关锁定集群的明确答案。非常感谢一些帮助。
distributed-computing redis distributed-lock spring-data-redis redis-cluster
在将多个线程与 spring-redis-data 一起使用时,我遇到了一个大问题,而且它很容易重现,以至于我认为我错过了一些微不足道的东西。
如果我在执行保存操作时查询 CrudRepository,有时(高达 60%)在 Redis 上找不到记录。
尽管可以在上面的链接中找到完整的代码,但以下是主要组件:
@Repository
public interface MyEntityRepository extends CrudRepository<MyEntity, Integer> {
}
Run Code Online (Sandbox Code Playgroud)
@RedisHash("my-entity")
public class MyEntity implements Serializable {
@Id
private int id1;
private double attribute1;
private String attribute2;
private String attribute3;
Run Code Online (Sandbox Code Playgroud)
@GetMapping( "/my-endpoint")
public ResponseEntity<?> myEndpoint () {
MyEntity myEntity = new MyEntity();
myEntity.setAttribute1(0.7);
myEntity.setAttribute2("attr2");
myEntity.setAttribute3("attr3");
myEntity.setId1(1);
myEntityRepository.save(myEntity);//create it in redis
logger.info("STARTED");
for (int i = 0; i < …Run Code Online (Sandbox Code Playgroud) 我们使用spring-data-redis抽象spring-cache并lettuce作为我们的 redis 客户端。此外,我们在某些方法上使用多线程和异步执行。
示例工作流程如下所示:
Main-Method A(主线程)--> 调用 Method B ( @Async),这是一个代理方法,能够在另一个线程中异步运行逻辑。--> 方法 B 调用方法 C,即@Cacheable。注释@Cacheable处理对我们的 redis 缓存的读/写。
有什么问题?
Lettuceis Netty-based ,其工作依赖于DirectMemory. 由于@Async我们程序的性质,我们有多个线程同时使用LettuceConnection(因此)。Netty
Netty根据设计,所有线程都将使用共享DirectMemory. 由于明显太小,当访问的线程太多时,MaxDirectMemorySize我们会得到一个。OutOfDirectMemoryErrorNetty
例子:
io.lettuce.core.RedisException: io.netty.handler.codec.EncoderException: io.netty.util.internal.OutOfDirectMemoryError: failed to allocate 8388352 byte(s) of direct memory (used: 4746467, max: 10485760)
到目前为止我们发现了什么?
我们使用https://docs.cloudfoundry.org/buildpacks/java/并MaxDirectMemorySize使用https://github.com/cloudfoundry/java-buildpack-memory-calculator进行计算。
这导致了MaxDirectMemorySize=10M. 计算出的实际可用内存为 4GB …
我正在尝试监听 Redis 流并在消息到达时对其进行处理。我正在使用异步命令,我希望消息被推送而不是被拉取。所以我认为不需要 while 循环。但下面的代码似乎不起作用。
public static void main(String[] args) throws InterruptedException {
RedisClient redisClient = RedisClient
.create("redis://localhost:6379/");
StatefulRedisConnection<String, String> connection
= redisClient.connect();
RedisAsyncCommands commands = connection.async();
commands.xgroupCreate(StreamOffset.latest("my-stream"), "G1", new XGroupCreateArgs());
commands
.xreadgroup(Consumer.from("G1", "c1"), StreamOffset.lastConsumed("my-stream"))
.thenAccept(System.out::println);
Thread.currentThread().join();
}
Run Code Online (Sandbox Code Playgroud)
它只打印程序启动时流中的所有内容,而不打印程序运行时添加的消息。是否应该为新添加到流中的每条消息调用回调?
java lettuce spring-data-redis spring-data-redis-reactive redis-streams
redis ×6
java ×5
lettuce ×2
spring ×2
spring-boot ×2
spring-cache ×2
asynchronous ×1
concurrency ×1
docker ×1
jedis ×1
reddison ×1
spring-data ×1
spring-test ×1