spring-projects / spring-session

Spring Session
https://spring.io/projects/spring-session
Apache License 2.0
1.86k stars 1.11k forks source link

redis keys not removed from PRINCIPLE_NAME_INDEX_NAME section when user session expires. (but removed when logout request comes) #1715

Open emre06ylmz opened 4 years ago

emre06ylmz commented 4 years ago

We use spring session with redis in our spring boot app. In our usecase, most of the users do not send logout request. If logout request comes from the user, spring removes the redis keys from PRINCIPLE_NAME_INDEX_NAME and the other sections. But, if logout request does not come, when user session expires, spring removes redis keys from all other sections except PRINCIPLE_NAME_INDEX_NAME.

After some time, number of user sessions in PRINCIPLE_NAME_INDEX_NAME section, will be pile up and some performance problems occours when spring read sessions from redis.

When we analyze the reqeust from dynatrace, we see HGETALL, QUIT, AUTH operations. (uploaded image) redis

To sum up, we need that spring removes redis keys from PRINCIPLE_NAME_INDEX_NAME section such as when logout request comes.

More information about the problem is below.

The Project we talk about, is designed as a library and our domain teams add and use it in their spring boot projects. I will share the versions of components. The problem is currently, if we send logout request the session key is removed from the redis. But if we do not send a logout request and wait for the expiration, the session key is not removed from the redis. In our applications most of the time there is no logout request so after some time redis operations slow down.

To sum up with the screen capture, user U039909 has 5 sessions, you can see right of the capture. if logout reqeust come, these sessions are removed from the index.But if there is no logout reqeust these session will exist in the PRINCIPLE_INDEX_NAME_PRICPLE. redis2

To be honest we do not want to use redis keyspace notificaitons because of some cases, for example application can be down while notification fired or redis could be restarted any time. Do you have any other suggestion except using key notificaitions?

project informations: spring boot : 2.0.0.RELEASE spring: 5.0.4.RELEASE

michal-kroliczek commented 3 years ago

It was reported quite time ago and there is no reply? :(

I reported the same https://github.com/spring-projects/spring-session/issues/1779 but I suspect it is related to redis cloud deployments - at least that is explainable but I am not expert and it would be nice to have confirmation.

eleftherias commented 3 years ago

Thanks for the information @michal-kroliczek and @emre06ylmz. Could either of your provide minimal sample that reproduces this issue? This will help us get to the bottom of this faster.

Binary00 commented 3 years ago

I'm having the same issue as well. We're using AWS Elasticache with RedisStaticMasterReplicaConfiguration as our configuration class to spread the request load across the cluster. In doing so a connection provider StaticMasterReplicaConnectionProvider is created that doesn't support Pub/Sub connections. I've observed that those principal index Redis entries only get cleaned up when a message is published from Redis, which won't work in these connection scenarios.

To reproduce:

@Bean
  @ConditionalOnProperty(value = "spring.session.store-type", havingValue = "redis")
  public LettuceConnectionFactory redisConnectionFactory(RedisProperties redisProperties,
                                                         @Value("${spring.redis.host}") String primaryHost,
                                                         @Value("${spring.redis.host}") String readerHost) {
    RedisStaticMasterReplicaConfiguration elastiCache = new RedisStaticMasterReplicaConfiguration(primaryHost);
    elastiCache.node(readerHost);
    LettuceClientConfiguration clientConfig = LettuceClientConfiguration
        .builder()
        .commandTimeout(redisProperties.getTimeout())
        .readFrom(ReadFrom.SLAVE_PREFERRED)
        .build();

    return new LettuceConnectionFactory(elastiCache, clientConfig);
  }

By adding the bean override above that cleanup stops working. Comment it out and use the default Spring Boot autoconfig, and it works. As the the posts above have mentioned that keyspace notifications are required for cleanup. Is there any other alternative?

Thanks