[keycloak-dev] client query caches getting complicated

Bill Burke bburke at redhat.com
Wed Feb 17 15:56:04 EST 2016



On 2/17/2016 3:09 PM, Marek Posolda wrote:
> On 17/02/16 18:11, Bill Burke wrote:
>> Currently, adding or deleting a client, or updating a realm causes
>> invalidation/eviction of the realm and all clients in that realm. To
>> make matters worse, the next time the realm is accessed, it queries and
>> loads each client and its relationships.  Why do we do this?  When a
>> realm invalidation happens, the cache has no idea if the realm is just
>> being updated or removed entirely from the DB. With a realm removal, you
>> also need to evict the cache of all clients within the realm.  So, a
>> cached realm MUST have a list of all clients within it.  As a result,
>> the more clients that get added, keycloak gets slower and slower.
>> Eventually though the cache stabilizes after inserts/update/deletes
>> subside and we get back to normal performance, but you can see a nasty
>> blip for a little bit.
> We don't need to eagerly preload all clients when realm is loaded. 
> Infinispan has streaming/predicate API and we are using it in many 
> places (see InfinispanUserSessionProvider and all the stuff in package 
> org.keycloak.models.sessions.infinispan.stream ). So when entry is 
> invalidated, we can have cacheListener, which will query infinispan to 
> return all cached clients of the realm and remove them. I can see that 
> we already have listener. So possibly we can just change this line to 
> use predicate query: 
> https://github.com/keycloak/keycloak/blob/master/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/locking/LockingCacheRealmProviderFactory.java#L141
>
>

Lol, i was sort of kind of doing that doing cache.values().  This makes 
it much easier with much less refactoring.

> Other option is, that we can try to optimize eager preload and see if 
> we can reduce number of SQL queries at startup. For example, it seems 
> that CachedClient constructor sends SQL query to preload just realm 
> roles. And then each client sends another SQL query to preload his 
> client roles (method CachedClient.cacheRoles ). Couldn't we instead 
> send one SQL query to load all roles of realm (both realm and client 
> roles)? Maybe we can even send one big SQL query to load realm with 
> all it's objects :-) Possibly some FetchType.EAGER in Hibernate 
> entities could help here.
>

yeah, we should start looking into stuff like this.    We can at least 
reduce the number of sql calls for caching a client or realm 
individually.  I'm not sure how feasible it is though or how much better 
it is.  Realms and clients contain more than a few one to many 
relationships which would make the query result HUGE if I remember how 
joins work.

-- 
Bill Burke
JBoss, a division of Red Hat
http://bill.burkecentral.com

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/keycloak-dev/attachments/20160217/f3dc4d00/attachment.html 


More information about the keycloak-dev mailing list