0

I'm thinking through adding a lazy-loading cache to my API. Currently, REST objects are filtered out (scoped) based on the user's role, and additional constraints in the system. Users of the same role may have access to different objects based on constraints made by administrators, these are accounted for in the db filtering.

It's clear a simple implementation of lazy-loading wont work. Suppose there was a cache hit on the ID, I would still have to make another database call to check if the user is allowed access to the object. Pretty much defeats the purpose of the cache.

I could craft the cache key to include the user's id, but that would greatly increase the memory required. Is this a good strategy, or is there something better I should do?

// *****************************************
// function that returns a customer's record.
// Attempts to retrieve the record from the cache.
// If it is retrieved, the record is returned to the application.
// If the record is not retrieved from the cache, it is
//    retrieved from the database, 
//    added to the cache, and 
//    returned to the application
// *****************************************
get_customer(customer_id)

    customer_record = cache.get(customer_id)
    if (customer_record == null)
    
        customer_record = db.query("SELECT * FROM Customers WHERE id = {0}", customer_id)
        cache.set(customer_id, customer_record)
    
    return customer_record

Pseudocode taken from https://docs.aws.amazon.com/AmazonElastiCache/latest/mem-ug/Strategies.html

5
  • 1) Amazon uses wrong wording on the linked page. What they describe is * normal cache and has nothing to do with lazy loading. Also your code shows normal cache. It is not clear why are you talking about lazy loading.
    – mentallurg
    Apr 2, 2023 at 0:03
  • 2) Have you measured performance? What part of the response time takes the DB request, is it 90%, 50%, 10%?
    – mentallurg
    Apr 2, 2023 at 0:09
  • The AWS page refers to this as lazy loading and that's their lazy loading pseudo-code example. I haven't measured anything, I'm just thinking through how I would implemented it if needed.
    – Brady Dean
    Apr 2, 2023 at 20:38
  • The AWS uses wrong wording. Despite they have many good engineers, this particular text is wrong. The described caching has nothing to do with lazy loading.
    – mentallurg
    Apr 2, 2023 at 20:57
  • "Users of the same role may have access to different objects based on constraints made by administrators" -- this sounds just Broken. That is, you don't have RBAC at the role level of granularity, rather you have fine-grained user-based access control. BTW, if allowed access changes over time, be sure to verify your cache TTL performs expiry as you wish, or else include some coarse-grained timestamp in the cache identifier key. Choosing coarser granularity impacts the "time until no longer authorized" latency when an admin attempts to revoke access.
    – J_H
    May 4, 2023 at 0:22

1 Answer 1

1

TL;DR

Add a seperate cache for the role(s) a user has.


The core premise of a "normal" cache is that it is quicker to fetch the previously returned value (typically from memory) than it is to recalculate it (or fetch the value over the network).

For this to work correctly, you need to include any attributes that could change the result in the cache key - so for example if users with different roles sees different data, the users role(s) needs to be included in the cache key.

However there is an edge cases, if the role is only an access check:

  • Based on the role, the user may or may not get access to the data.
  • But if the access is sufficient, it is always the same data (no data changes based on the role).

Then you can simply cache the roles (required for access) with the data.

Your point about needing to hit the database anyway - simply to check which roles the user possesses revels the need for an additional cache - of user roles. Effectively each request now hits both caches - the first to look up the roles for the user and the second to fetch the data (given you now know the users roles).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.