KEYCLOAK-16802 Improve performance of removed expired sessions in Jpa…#7764
KEYCLOAK-16802 Improve performance of removed expired sessions in Jpa…#7764mposolda wants to merge 2 commits intokeycloak:mainfrom
Conversation
hmlnarik
left a comment
There was a problem hiding this comment.
Thank you @mposolda. I didn't go through the code much, just noted this comment which might be related to this work.
There was a problem hiding this comment.
The ID in case of map storage implementation needs to be a UUID. Can this be changed accordingly?
Disclaimer: Realm storage is right now being implemented, that's why the map storage tests did not catch this.
cc: @vramik
There was a problem hiding this comment.
@hmlnarik Thanks for the feedback! In this case, I rather changed this test to use realm names instead of realmId, so that test work for both JPA and mapStorage. Also I removed the method "id" from the RealmBuilder class, which I introduced in this PR (in the first version of this PR before you spot this).
…UserSessionPersisterProvider
d761c57 to
31c29a1
Compare
| @NamedQuery(name="deleteUserSessionsByUser", query="delete from PersistentUserSessionEntity sess where sess.userId = :userId"), | ||
| @NamedQuery(name="deleteExpiredUserSessions", query="delete from PersistentUserSessionEntity sess where sess.realmId = :realmId AND sess.offline = :offline AND sess.lastSessionRefresh < :lastSessionRefresh"), | ||
| @NamedQuery(name="deleteExpiredUserSessionsCrossRealm", query="delete from PersistentUserSessionEntity sess where" | ||
| + " sess.realmId in (select realm.id from RealmEntity realm where realm.offlineSessionIdleTimeout = :offlineSessionIdle)" |
There was a problem hiding this comment.
"nitpicking" just for consistency
| + " sess.realmId in (select realm.id from RealmEntity realm where realm.offlineSessionIdleTimeout = :offlineSessionIdle)" | |
| + " sess.realmId IN (select realm.id from RealmEntity realm where realm.offlineSessionIdleTimeout = :offlineSessionIdle)" |
4f2e41d to
b5ba4d0
Compare
|
@hmlnarik @martin-kanis @vramik I've added another commit with the alternative solution. I've used separate commit for it just to show the changes, but I can squash it afterwards. The previous approach did not perform well for the many offline sessions in the DB as the SQL with "NOT IN" looks like a bottleneck. Details of performance testing: The use-case was expiration of big number of offline sessions with many realms deployments. Test was with:
|
|
@mposolda Thank you for the performance statistics. It's good to see such an improvement. Your second test is performed with "NOT IN" variant or with the second commit which you pushed here? I'm wondering how much more the second commit performs better. |
|
@martin-kanis That is good point. The test (1) was done with the current Keycloak master, the test (2) was done with exactly what is available in this PR. I've tried to measure performance also with the "NOT IN" variant, but performance was very bad for the bigger amount of records and for 50K offlineUserSessions in the DB (which is not very big amount), it failed entirely with the transaction timeout. For example, there is also this warning in the PostgreSQL docs for usage of "NOT IN" and the performance limitations: https://wiki.postgresql.org/wiki/Don't_Do_This#Don.27t_use_NOT_IN . I've tried also the variant with "NOT EXISTS", but this doesn't work (at least) with MySQL when used in JPQL together with DELETE command. So finally ended with the version in the current PR, which seems to work with all databases and have better performance than current master. Similar approach is used also for The performance with this PR is significantly better than current master, at least in my test, which uses 10 different timeouts for various realms. It can be possibly worse than current master in case that you would have N realms with N completely different offlineIdleTimeouts in each realm, but as I mentioned above, IMO in reality, it is rather much more probable that count of different timeouts will be likely smaller (usually 1) in production environments like for example MAS SSO. |
|
@hmlnarik Thanks for pointing the comment from the other PR, I somehow missed it before. I've created https://issues.redhat.com/browse/KEYCLOAK-17111 for this. I see that before this PR, the InfinispanUserSessionProvider.removeExpired(realm) also ignored client-overriden timeouts, so https://issues.redhat.com/browse/KEYCLOAK-17111 is not a regression of https://issues.redhat.com/browse/KEYCLOAK-16755 . However it worth fixing, so I triaged and planned to be fixed. |
|
What's with this? Was this done? |
|
@eldarj Sorry, this is "on hold" for now due the team focus on the new store and this PR is related to the old store. I am not sure if we restore the work on this PR due the other priorities (and due testing this change is not so trivial as it requires further testing and performance verifications etc...) |
|
@mposolda I'm closing it for now but we can re-open anytime if the plans change. |
|
@pedroigor Sure, Thanks for closing this one. |
|
@pedroigor @mposolda I was doing some profiling and found kecloak spending a lot of time on this. Could this please be reopened ? |
…UserSessionPersisterProvider