Skip to content

Clustered Redis server memory leak because FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME key is not removed after session expired #2230

Closed
@sjzcao

Description

@sjzcao

Describe the bug
spring session is configured using redis cluster servers and redis server memory usage keep increase because "FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME" keys are not deleted after sessions are expired.

To Reproduce
redis_version:6.2.7
1/ prepare a local redis cluster. In my demo, there are 6 nodes. 3 master nodes and 3 slave nodes. (masters: localhost:7000/7001/7002, slaves: localhost:7003/7004/7005)
2/ a sample spring security project (refer sample part) and config springSessionRedisConnectionFactory by adding all 6 nodes (or one node, does not matter)
3/ start the spring security project and login page http://127.0.0.1:8080
4/ open redis-cli and monitor key

Expected behavior
After all sessions expired, the related index keys "FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME" should be deleted to release redis server memory.

Basic Observation
The root cause of the issue is seems that spring session only add del and expired event listener to one of the redis server, if the "sessions:expires" key is not created in the server to which the listener listen, spring session will miss the event and cause the index key (spring:session:index:org.springframework.session.FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME:user) not removed.

Here is an example, in my demo environment port 7000,7001 and 7002 are master nodes

127.0.0.1:7002> cluster nodes
e596fcc10a2c3184807b982928d70153c137aa8b 127.0.0.1:7005@17005 slave 612f43a2301914e956a3eb620c8fcce441497cb3 0 1674831918000 3 connected
9fedf79f9ac8e6bb9e67878fdf6d53c2ad1d0ea0 127.0.0.1:7001@17001 master - 0 1674831917010 2 connected 5461-10922
7114c805ae2826de3d9500706817ecd777dbd37c 127.0.0.1:7003@17003 slave 23c816af91f85713c7dbc9ff68d3eeed83cc46e7 0 1674831918000 1 connected
612f43a2301914e956a3eb620c8fcce441497cb3 127.0.0.1:7002@17002 myself,master - 0 1674831917000 3 connected 10923-16383
efc0e9063443b65e808aa3ea49c1f5bb30925d5d 127.0.0.1:7004@17004 slave 9fedf79f9ac8e6bb9e67878fdf6d53c2ad1d0ea0 0 1674831918516 2 connected
23c816af91f85713c7dbc9ff68d3eeed83cc46e7 127.0.0.1:7000@17000 master - 0 1674831918000 1 connected 0-5460

and spring session add event listener to 7001:

127.0.0.1:7001> pubsub channels
1) "__keyevent@0__:expired"
2) "__keyevent@0__:del"

after log in my demo page, the expires key added to 7002:

127.0.0.1:7002> keys *
1) "spring:session:index:org.springframework.session.FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME:user"
2) "spring:session:sessions:expires:1e9938ed-d74c-4143-bb87-66d4e3cab304"
3) "spring:session:sessions:20a65ccc-ce7c-408e-aa4b-a91e2f69cb6b"

When "spring:session:sessions:expires:1e9938ed-d74c-4143-bb87-66d4e3cab304" expired, spring session missed the event because the listener is only listening 7001.

Sample
https://github.com/sjzcao/spring-session-memory-issue.git

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions