我在使用spring redis数据的多线程时遇到了一个大问题,它很容易复制,我认为我遗漏了一些琐碎的东西。
如果我在执行保存操作时查询CrudRepository,它有时(高达60%)在Redis上找不到记录。
尽管可以在上面的链接中找到完整的代码,但这是主要组件:
@Repository
public interface MyEntityRepository extends CrudRepository<MyEntity, Integer> {
}
@RedisHash("my-entity")
public class MyEntity implements Serializable {
@Id
private int id1;
private double attribute1;
private String attribute2;
private String attribute3;
@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 < 100; i++){
new Thread(){
@Override
public void run() {
super.run();
myEntity.setAttribute1(Math.random());
myEntityRepository.save(myEntity); //updating the entity
Optional<MyEntity> optionalMyEntity = myEntityRepository.findById(1);
if (optionalMyEntity.isPresent()) {
logger.info("found");
}else{
logger.warning("NOT FOUND");
}
}
}.start();
}
return ResponseEntity.noContent().build();
}
2020-05-26 07:52:53.769 INFO 30655 --- [nio-8080-exec-2] my-controller-logger : STARTED
2020-05-26 07:52:53.795 INFO 30655 --- [ Thread-168] my-controller-logger : found
2020-05-26 07:52:53.798 WARN 30655 --- [ Thread-174] my-controller-logger : NOT FOUND
2020-05-26 07:52:53.798 WARN 30655 --- [ Thread-173] my-controller-logger : NOT FOUND
2020-05-26 07:52:53.806 INFO 30655 --- [ Thread-170] my-controller-logger : found
2020-05-26 07:52:53.806 WARN 30655 --- [ Thread-172] my-controller-logger : NOT FOUND
2020-05-26 07:52:53.812 WARN 30655 --- [ Thread-175] my-controller-logger : NOT FOUND
2020-05-26 07:52:53.814 WARN 30655 --- [ Thread-176] my-controller-logger : NOT FOUND
2020-05-26 07:52:53.819 WARN 30655 --- [ Thread-169] my-controller-logger : NOT FOUND
2020-05-26 07:52:53.826 INFO 30655 --- [ Thread-171] my-controller-logger : found
2020-05-26 07:52:53.829 INFO 30655 --- [ Thread-177] my-controller-logger : found
所以简单地说,有10个线程,其中6个没有在db中找到结果。
如上所述,将redis替换为Spring data redis至少包含9个操作。
因此,要替换redis中的值,它必须删除哈希、索引,然后再次添加新哈希和新索引,也许一个线程正在执行此操作,而其他线程试图通过索引查找值,而此索引尚未添加。
我认为spring data with data redis几乎不可能有这样的bug,所以我想知道我对data redis或redis有什么不理解。由于redis具有并发性,我认为可能会发生一些不同的事情,但在提供的示例中似乎是这样的。。。
提前感谢你们所有人
您有一个MyEntity
实例:
MyEntity myEntity = createEntity();
然后,您已经启动了10个线程,所有这些线程都在更新一个对象myEntity。设置 。
然后将其另存为myEntityRepository。保存(myEntity) ,不可能知道保存了什么值,因为所有线程都在竞争插入自己的值。
当你调用myEntityRepository时。保存时,它可能正在保存(再次)另一个线程写入myEntity的值。所以这个线程从来没有机会将它的价值写入回购协议,因此你不会找到它!
我没有穿过@RedisHash
,所以我可能错了,但我认为每次要保存记录时都需要创建一个新的实体对象。
与您的代码无关的另一个问题是无限线程创建(除非您不打算在生产中使用它)。
这张罚单也引发了同样的问题。
故意选择该行为是为了避免残留的哈希条目。删除哈希可以确保一致的状态,并避免不再是哈希一部分的其他条目。
Redis存储库操作不是原子的。
所以它不是原子的。
并在票证中建议,解决方案将使用ParalUpdate
。
下面是一个片段,例如
@Autowired
private RedisKeyValueTemplate redisKVTemplate;
...
// id is the @Id value of the entity
private void update(Integer id) {
PartialUpdate update = new PartialUpdate<MyEntity>(id, MyEntity.class)
.set("attribute1", Math.random());
redisKVTemplate.update(update);
}
参考:
使用spring-data-redis更新redis中的实体
我正在使用Spring data redis和jedis与aspectJ进行日志记录。但是得到以下错误。请帮助解决此错误。我在这上面花了很多时间,但无法解决它。 我使用的是Spring数据redis 1.4.1,jedis-2.6.1和Redis-2.8 错误详情:- 下面是使用spring data redis的redis Sentinel配置的Java配置文件 下面是用于日志记录的Aspect
我使用spring boot data redis连接到redis群集,使用版本2.1.3,配置如下: 但是,在操作过程中,始终会收到警告异常消息,如下所示: 这似乎是莴苣的问题,如何映射远程主机
我正在尝试将ElastiCache设置为与Java应用程序一起使用。我的设置基于以下文档:https://docs.aws.amazon.com/AmazonElastiCache/latest/UserGuide/BestPractices.html Java(8)应用程序运行的EC2实例位于专有网络中。我在VPC和非VPC中都尝试了ElastiCache实例。然而,我总是, 如果我自己在EC2
我们有一个关于Spring框架的项目。它包含具有以下配置的Spring Security性: 它可以在一个Apache Tomcat服务器上工作。如果我尝试从另一个浏览器登录,我以前的http会话将过期。 null 所有这些方法都不起作用。我还发现了这个问题:https://github.com/spring-projects/spring-session/issues/65,它是两年前实现的。有
问题内容: 我用作spring Web应用程序的数据存储,并用作与之交互的客户端。 我用来存储一个具有多个字段的对象。我可以使用method 一次将所有字段放入,但是我无法一次获取整个对象,而是使用method 来获取每个字段。 我想知道有什么办法可以像支持中的操作那样吗? 问题答案: DefaultRedisMap.entrySet()或BoundHashOperations.entries()
本文向大家介绍如何解决 Redis 的并发竞争 Key 问题?相关面试题,主要包含被问及如何解决 Redis 的并发竞争 Key 问题?时的应答技巧和注意事项,需要的朋友参考一下 所谓 Redis 的并发竞争 Key 的问题也就是多个系统同时对一个 key 进行操作,但是最后执行的顺序和我们期望的顺序不同,这样也就导致了结果的不同! 推荐一种方案:分布式锁(zookeeper 和 redis 都可