У меня большая проблема при использовании нескольких потоков с данными spring-redis, и это настолько легко воспроизвести, что я думаю, что упустил что-то тривиальное.
Прямо к делу
Если я запрашиваю CrudRepository при выполнении операций сохранения, он иногда (до 60%) не находит запись в Redis.
Среда
Код
Несмотря на полный код можно найти по ссылке выше, это основные компоненты:
CrudRepository
@Repository
public interface MyEntityRepository extends CrudRepository<MyEntity, Integer> {
}
Entity
@RedisHash("my-entity")
public class MyEntity implements Serializable {
@Id
private int id1;
private double attribute1;
private String attribute2;
private String attribute3;
Controller
@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
Как уже упоминалось здесь замена в redis данными spring redis содержит не менее 9 операций.
Первый вывод
* 104 4 * Итак, чтобы заменить значение в redis, он должен удалить ha sh, индексы, а затем снова добавить новый ha sh и новые индексы, возможно, поток находится в середине выполнения этих операций в то время как другой поток пытается найти значение по индексу, а этот индекс еще не добавлен.
Второй вывод
Я думаю, что почти невозможно, чтобы данные Spring с data-redis имели такую ошибку, поэтому мне интересно, что я не понимаю в data-redis или redis. Поскольку у Redis есть параллелизм, я думаю, что может происходить что-то другое, но в приведенном примере это похоже на то ...
Заранее спасибо всем вам