Skip to content

Spring Session Redis is not clearing expired index to sessions in Redis #2166

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
git-syl opened this issue Sep 22, 2022 · 8 comments
Closed
Assignees
Labels

Comments

@git-syl
Copy link

git-syl commented Sep 22, 2022

Describe the bug
I integrated Spring Session into my project.
I found that the Spring Boot (Servlet container) and spring boot WebFlux (reactor project )integrated Spring sessions at the same time, which caused the redis key to not expire.

spring:session:index:org.springframework.session.FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME:
spring:session:index:org.springframework.session.FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME:
spring:session:index:org.springframework.session.FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME:
...
In Redis many keys failed to clean, resulting in memory overflow.

And My Spring Boot (Servlet container) Application with some WARN :
2022-09-22 17:11:33.171 WARN 23620 --- [nerContainer-49] o.s.s.d.r.RedisIndexedSessionRepository : Unable to publish SessionDestroyedEvent for session 727ae15d-7f42-4f8d-b229-f8385ac54b06

To Reproduce

spring boot 2.6.11
spring-session-data-redis 2.6.3

Steps to reproduce the behavior:

STEP-01 : Login and get token, in login project , it is Spring Boot applicaiton (Servlet container)
STEP-02 : Access RESTFUL api in reactor project immediately.
STEP-03 : Wait abount 30 seconds and view logs. Or look`t the data in Redis
test code like :

@Test
void test(){

 String XAuthToken = login(userName);

    for (int i = 0; i < 10; i++) {
            new Thread(new HttpClientPost( XAuthToken)).start();
        }
}

Expected behavior

Automatically clean keys (spring:session:index:org.springframework.session.FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME:),
when the session expires.

Sample

https://github.com/sunyl-git/sunyl-git-spring-reactor-session-issue-report-sample

In my limited experience with Spring, Thanks in advance!

@git-syl git-syl added status: waiting-for-triage An issue we've not yet triaged type: bug A general bug labels Sep 22, 2022
@baozi-2019
Copy link

I have the same problem, do you have a solution?

@git-syl
Copy link
Author

git-syl commented Apr 15, 2023

I have the same problem, do you have a solution?

@baozi-2019
从反应式项目中禁用spring session redis。
自己写个token拦截器,从Redis查询并验证当前登录信息,然后手动设置到SpringSecurityContext里面。

disabled spring session redis is in Reactor project.
Add an token interceptor that queries from redis and binds it to the spring security context.

@git-syl git-syl changed the title Spring Session Redis Data is not clearing index to sessions in Redis Spring Session Redis is not clearing expired index to sessions in Redis Apr 15, 2023
@marcusdacoregio
Copy link
Contributor

marcusdacoregio commented Oct 16, 2023

Hi, @git-syl. Thanks for the report.

I'm confused, we do not have an indexed Redis implementation for Reactive, therefore it is not possible to have a spring:session:index:org.springframework.session.FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME created by Spring Session Redis. Can you elaborate more on that?

Your sample has too many things going on, can you make it minimal?

@marcusdacoregio marcusdacoregio added status: waiting-for-feedback We need additional information before we can continue and removed status: waiting-for-triage An issue we've not yet triaged labels Oct 16, 2023
@marcusdacoregio marcusdacoregio self-assigned this Oct 16, 2023
@spring-projects-issues
Copy link

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

@spring-projects-issues spring-projects-issues added the status: feedback-reminder We've sent a reminder that we need additional information before we can continue label Oct 23, 2023
@git-syl
Copy link
Author

git-syl commented Oct 24, 2023

Hi, @git-syl. Thanks for the report.

I'm confused, we do not have an indexed Redis implementation for Reactive, therefore it is not possible to have a spring:session:index:org.springframework.session.FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME created by Spring Session Redis. Can you elaborate more on that?

Your sample has too many things going on, can you make it minimal?

Hi @marcusdacoregio ,Thank you for your response.
I have removed other unrelated dependencies from the project. To reproduce this issue, at least two projects need to be run- together. One is a login project based on servlet, and the other is a gateway project based on spring webflux. When accessing the interface of the reactor-project project, ReactiveRedisSessionRepository is triggered (located at: org\springframework\session\spring-session-data-redis\2.6.3\spring-session-data-redis-2.6.3.jar!\org\springframework\session\data\redis\ReactiveRedisSessionRepository.class).

I speculate that there is some code inside ReactiveRedisSessionRepository(spring-session-data-redis-2.6.3.jar) to renew the redisKey & Modifying the redisKey causes the login project to be unable to clear the redis key.
After calling the interface of the login project, immediately access the interface of the reactor-project. You can reproduce this result.
(run the SessionTest test case.
login\src\test\java\com\zhichanzaixian\trademarkapi\SessionTest.java)

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue status: feedback-reminder We've sent a reminder that we need additional information before we can continue labels Oct 24, 2023
@marcusdacoregio
Copy link
Contributor

Hello, @git-syl. Which Redis keys are you talking about? Is it the index key (which should not exist in the reactive implementation), or is it the session key? It is important to note that Redis may not remove all expired keys instantly. In addition to that, there was a bug on older versions of Spring Session Redis Reactive where it would fail to set the expiration time to a key.

@marcusdacoregio marcusdacoregio added status: waiting-for-feedback We need additional information before we can continue and removed status: feedback-provided Feedback has been provided labels Oct 24, 2023
@git-syl
Copy link
Author

git-syl commented Oct 24, 2023

Hello, @git-syl. Which Redis keys are you talking about? Is it the index key (which should not exist in the reactive implementation), or is it the session key? It is important to note that Redis may not remove all expired keys instantly. In addition to that, there was a bug on older versions of Spring Session Redis Reactive where it would fail to set the expiration time to a key.

It is the index key. After accessing the index key in this class, the index key will persist indefinitely and won't be automatically cleared.(Even if the project is set with spring.session.timeout=20s)
Its source code is located at :
ReactiveRedisSessionRepository

If I'm not mistaken, under normal circumstances, the index key spring:session:index:org.springframework.session.FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME:user_name should expire automatically.

Other servlet projects will receive a large number of failed clean-up logs, and the source code is located at:
RedisIndexedSessionRepository

Thank you very much in the end. I appreciate you mentioning issue #2464.
I plan to find some time to experiment with it, as it could possibly be the same issue

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Oct 24, 2023
@marcusdacoregio
Copy link
Contributor

I'm a bit confused because you mentioned Spring WebFlux apps and the problem is related to the index key which is created by an indexed session repository implementation, in that case, RedisIndexedSessionRepository, which is not available on the reactive side.

The Redis documentation for expire says:

Redis keys are expired in two ways: a passive way, and an active way.
A key is passively expired simply when some client tries to access it, and the key is found to be timed out.
Of course this is not enough as there are expired keys that will never be accessed again.

That means that even if the key is expired, it might not be instantly removed from the database. The RedisIndexedSessionRepository implementation depends on Redis events to be able to delete the indexes since they do not have an expiration time themselves. If your Redis instance is not configured to emit events, then those keys won't be cleaned up. More details on the documentation.

I'll close this since it appears that the behavior is expected, if you still think that this is a bug in Spring Session, please add a minimal, reproducible sample where we can debug the behavior consistently.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants