2 locations, 2 _different_ cache valid settings, but same cache & pass-through

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

2 locations, 2 _different_ cache valid settings, but same cache & pass-through

randyorbs
I'd like to setup a reverse proxy with cache that will allow me to...

1. expose two different locations...
location /foo {}
location /bar {}

2. resolve to the same pass-through...
location /foo {
   proxy_pass "http://myhost.io/go";
}
location /bar {
  proxy_pass "http://myhost.io/go";
}

3. use the same cache...
location /foo {
   proxy_pass "http://myhost.io/go";
   proxy_cache shared_cache;
}
location /bar {
   proxy_pass "http://myhost.io/go";
   proxy_cache shared_cache;  
}

4. use _different_ cache valid settings...
location /foo {
   proxy_pass "http://myhost.io/go";
   proxy_cache shared_cache;
   proxy_cache_valid any 5m;
}
location /bar {
   proxy_pass "http://myhost.io/go";
   proxy_cache shared_cache;
   proxy_cache_valid any 10m;
}

What I have found is that I can request /foo, then /bar and the /bar result will be an immediate HIT on the cache, which is good - the keys are the same and they are both aware of the cache. However, now that I've requested /bar any requests to /foo will result in cache HITs for 10 minutes instead of the 5 minutes I want. If I never hit /bar, then /foo will cache HIT for the correct 5 minutes.

Any thoughts on how I can use NGINX to configure my way into a solution for my unusual (?) use-case?


_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
Reply | Threaded
Open this post in threaded view
|

Re: 2 locations, 2 _different_ cache valid settings, but same cache & pass-through

Francis Daly
On Tue, Mar 24, 2020 at 11:15:59PM +0000, randyorbs wrote:

Hi there,

> 4. use _different_ cache valid settings...
> location /foo {
>    proxy_pass "http://myhost.io/go";
>    proxy_cache shared_cache;
>    proxy_cache_valid any 5m;
> }
> location /bar {
>    proxy_pass "http://myhost.io/go";
>    proxy_cache shared_cache;
>    proxy_cache_valid any 10m;
> }
>
> What I have found is that I can request /foo, then /bar and the /bar result will be an immediate HIT on the cache, which is good - the keys are the same and they are both aware of the cache. However, now that I've requested /bar any requests to /foo will result in cache HITs for 10 minutes instead of the 5 minutes I want. If I never hit /bar, then /foo will cache HIT for the correct 5 minutes.
>
> Any thoughts on how I can use NGINX to configure my way into a solution for my unusual (?) use-case?

The nginx cache file structure includes the validity period within the
stored object file.

The system does not care how the object file got there; it cares about
the file name and file contents.

So, "no".

(At least, not without writing your own special-case caching system.)

What is the thing that you want to achieve? Perhaps there is an alternate
way to get to the same desired end result.

        f
--
Francis Daly        [hidden email]
_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
Reply | Threaded
Open this post in threaded view
|

Re: 2 locations, 2 _different_ cache valid settings, but same cache & pass-through

randyorbs
> What is the thing that you want to achieve?

I have two clients, foo and bar. I charge foo to hit /foo and bar to hit /bar at different rates/costs. They've both agreed that the data can be stale, but how stale is different for each - 5 minutes for foo, 10 minutes for bar. Very often, foo and bar (though using different end-points) are making the exact same requests and getting the exact same responses.

I too get charged for hitting /myhost.io/go when my clients hit /foo and /bar.

I want to limit how often I hit /myhost.io/go to reduce costs, but also ensure I fulfill my "how stale is OK" agreements with my clients.

What I need is a cache of data that is aware that the validity of its data is dependent on who - foo or bar - is retrieving it. In practice, this means that requests from both foo and bar may be responded to with cache data from the other's previous request, but most likely the cache will be populated with responses to foo's requests to the benefit of bar, which is fine.

It would be great if I could config my way into a solution to my use-case using NGINX.

‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
On Friday, March 27, 2020 1:21 AM, Francis Daly <[hidden email]> wrote:

> On Tue, Mar 24, 2020 at 11:15:59PM +0000, randyorbs wrote:
>
> Hi there,
>
> > 4.  use different cache valid settings...
> >     location /foo {
> >     proxy_pass "http://myhost.io/go";
> >     proxy_cache shared_cache;
> >     proxy_cache_valid any 5m;
> >     }
> >     location /bar {
> >     proxy_pass "http://myhost.io/go";
> >     proxy_cache shared_cache;
> >     proxy_cache_valid any 10m;
> >     }
> >
> >
> > What I have found is that I can request /foo, then /bar and the /bar result will be an immediate HIT on the cache, which is good - the keys are the same and they are both aware of the cache. However, now that I've requested /bar any requests to /foo will result in cache HITs for 10 minutes instead of the 5 minutes I want. If I never hit /bar, then /foo will cache HIT for the correct 5 minutes.
> > Any thoughts on how I can use NGINX to configure my way into a solution for my unusual (?) use-case?
>
> The nginx cache file structure includes the validity period within the
> stored object file.
>
> The system does not care how the object file got there; it cares about
> the file name and file contents.
>
> So, "no".
>
> (At least, not without writing your own special-case caching system.)
>
> What is the thing that you want to achieve? Perhaps there is an alternate
> way to get to the same desired end result.
>
> f
>
> -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
> Francis Daly [hidden email]
>
> nginx mailing list
> [hidden email]
> http://mailman.nginx.org/mailman/listinfo/nginx


_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
Reply | Threaded
Open this post in threaded view
|

RE: 2 locations, 2 _different_ cache valid settings, but same cache & pass-through

Reinis Rozitis
> What I need is a cache of data that is aware that the validity of its data is
> dependent on who - foo or bar - is retrieving it. In practice, this means that
> requests from both foo and bar may be responded to with cache data from
> the other's previous request, but most likely the cache will be populated with
> responses to foo's requests to the benefit of bar, which is fine.
>
> I too get charged for hitting /myhost.io/go when my clients hit /foo and /bar.
>
> It would be great if I could config my way into a solution to my use-case
> using NGINX.

Just a quick idea (though maybe there is a more elegant way).

Depending on how do you charge your clients (like if it matters which client actually made the request to the origin) instead of using the same proxy_cache for both you could make 2 separate caches (one for the 5 min other for 10 min) and then chain them.

Something like:

location /foo {
    proxy_pass "http://myhost.io/go";
    proxy_cache 5min_shared_cache;
    proxy_cache_valid any 5m;
}

  location /bar {
     proxy_pass http://localhost/foo; // obviously you need to adjust/rewrite the uris
     proxy_cache 10min_shared_cache;
     proxy_cache_valid any 10m;
 }

So in case there is a request to /foo it will be forwarded to origin and cached for 5 mins,
if there is request to /bar - a subrequest will be made to /foo and if there is a cached object in the 5min cache you'll get the object without making request to origin and the object will be saved for 10 mins, but if there is no object in the 5 min cache a single request to origin will populate both caches.


There are some drawbacks of course - the /bar requests will always populate also the 5min /foo cache - so every object will be saved twice = extra disk space.

Also depending if you ignore or not the Expires (origin) headers the object in the 10min cache could end up actually older than 10 minutes (if you get the object from the 5min cache at 4:59 age (sadly nginx doesn't have Age header) and then add 10 mins to it. So it may or may not be a problem if you can adjust the times a bit - like add only ~7 minutes if the /foo responds with cache hit status)

Going the other way around (/foo -> /bar) could be possible but has extra complexity (like checking if the object is not too old etc) for example using LUA you could implement whole proxy and file store logic.
 
rr




_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
Reply | Threaded
Open this post in threaded view
|

RE: 2 locations, 2 _different_ cache valid settings, but same cache & pass-through

randyorbs
> Just a quick idea...

Thank you for the idea. I was able to quickly demo it out and play around with it a bit.

You mentioned /bar objects being older than desired with this idea, which I agree is a problem, but in another way.

If I reconfigure /bar to say 60 minutes, then that means /bar would not benefit from /foo's more frequent requests to http://myhost.io/go i.e. /bar will use its cache for 60 minutes, thus, missing out on all the fresh data /foo is seeing. I want both /foo and /bar to use the most recent data either has received.

I admit, my arbitrary choice of 5 and 10 minutes for my example was not ideal.

Thanks again.


‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
On Friday, March 27, 2020 4:03 PM, Reinis Rozitis <[hidden email]> wrote:

> > What I need is a cache of data that is aware that the validity of its data is
> > dependent on who - foo or bar - is retrieving it. In practice, this means that
> > requests from both foo and bar may be responded to with cache data from
> > the other's previous request, but most likely the cache will be populated with
> > responses to foo's requests to the benefit of bar, which is fine.
> > I too get charged for hitting /myhost.io/go when my clients hit /foo and /bar.
> > It would be great if I could config my way into a solution to my use-case
> > using NGINX.
>
> Just a quick idea (though maybe there is a more elegant way).
>
> Depending on how do you charge your clients (like if it matters which client actually made the request to the origin) instead of using the same proxy_cache for both you could make 2 separate caches (one for the 5 min other for 10 min) and then chain them.
>
> Something like:
>
> location /foo {
> proxy_pass "http://myhost.io/go";
> proxy_cache 5min_shared_cache;
> proxy_cache_valid any 5m;
> }
>
> location /bar {
> proxy_pass http://localhost/foo; // obviously you need to adjust/rewrite the uris
> proxy_cache 10min_shared_cache;
> proxy_cache_valid any 10m;
> }
>
> So in case there is a request to /foo it will be forwarded to origin and cached for 5 mins,
> if there is request to /bar - a subrequest will be made to /foo and if there is a cached object in the 5min cache you'll get the object without making request to origin and the object will be saved for 10 mins, but if there is no object in the 5 min cache a single request to origin will populate both caches.
>
> There are some drawbacks of course - the /bar requests will always populate also the 5min /foo cache - so every object will be saved twice = extra disk space.
>
> Also depending if you ignore or not the Expires (origin) headers the object in the 10min cache could end up actually older than 10 minutes (if you get the object from the 5min cache at 4:59 age (sadly nginx doesn't have Age header) and then add 10 mins to it. So it may or may not be a problem if you can adjust the times a bit - like add only ~7 minutes if the /foo responds with cache hit status)
>
> Going the other way around (/foo -> /bar) could be possible but has extra complexity (like checking if the object is not too old etc) for example using LUA you could implement whole proxy and file store logic.
>
> rr
>
> nginx mailing list
> [hidden email]
> http://mailman.nginx.org/mailman/listinfo/nginx


_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx