Checking multiple caches before forwarding request to upstream

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Checking multiple caches before forwarding request to upstream

anish10dec
Hi,

We want to define multiple caches based on certain request headers (time
stamp) so that we can put files modified in last 10 days on SSDs, last 30
days on HDDs and so on. I understand that we could use map feature to pick a
cache dynamically which is good and works for us.

But when serving a file, we want to check in all the caches because file
modified in last 11 days could still be on SSDs, so we don't wan't to
unnecessarily pull it out from backend and put it on HDDs.

so net, net we want to check multiple caches before pulling from the
backend. Is there a way to do that? We can only define one proxy_cache in a
location block, so I figured if we some how use try files or error page
attribute to failover multiple blocks and check one cache in each block, we
could check multiple caches.

following is my simplified config:

server {
        listen       7800 ;
        server_name  localhost;
        resolver 8.8.8.8 ipv6=off;

        location / {

            set $served_by "cache";
            set $cache_key $request_uri;
            proxy_cache cache_recent;
            proxy_cache_key $cache_key;

            error_page 418 = @go-to-cloud-storage; return 418;
            #try_files /does-not-exist @go-to-cloud-storage;

        }

        location @go-to-cloud-storage  {
            set $served_by "cloud";

            proxy_cache cache_recent;
            proxy_cache_key $cache_key;

            proxy_set_header Host $host;
            proxy_pass https://$http_host$request_uri;
        }

    }

But in the above config,   @go-to-cloud-storage storage is always executed
even when object is in cache for the / block.

Thanks
Sachin

Posted at Nginx Forum: https://forum.nginx.org/read.php?2,273446,273446#msg-273446

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

Re: Checking multiple caches before forwarding request to upstream

Maxim Dounin
Hello!

On Thu, Apr 06, 2017 at 06:45:23AM -0400, [hidden email] wrote:

> Hi,
>
> We want to define multiple caches based on certain request headers (time
> stamp) so that we can put files modified in last 10 days on SSDs, last 30
> days on HDDs and so on. I understand that we could use map feature to pick a
> cache dynamically which is good and works for us.
>
> But when serving a file, we want to check in all the caches because file
> modified in last 11 days could still be on SSDs, so we don't wan't to
> unnecessarily pull it out from backend and put it on HDDs.
>
> so net, net we want to check multiple caches before pulling from the
> backend. Is there a way to do that? We can only define one proxy_cache in a
> location block, so I figured if we some how use try files or error page
> attribute to failover multiple blocks and check one cache in each block, we
> could check multiple caches.
>
> following is my simplified config:
>
> server {
>         listen       7800 ;
>         server_name  localhost;
>         resolver 8.8.8.8 ipv6=off;
>
>         location / {
>
>             set $served_by "cache";
>             set $cache_key $request_uri;
>             proxy_cache cache_recent;
>             proxy_cache_key $cache_key;
>
>             error_page 418 = @go-to-cloud-storage; return 418;
>             #try_files /does-not-exist @go-to-cloud-storage;
>
>         }
>
>         location @go-to-cloud-storage  {
>             set $served_by "cloud";
>
>             proxy_cache cache_recent;
>             proxy_cache_key $cache_key;
>
>             proxy_set_header Host $host;
>             proxy_pass https://$http_host$request_uri;
>         }
>
>     }
>
> But in the above config,   @go-to-cloud-storage storage is always executed
> even when object is in cache for the / block.

That's because you unconditionally return 418 before any other
processing.  Rewrite directives, including "return", are executed
when nginx searches for a configuration to use, see details here:

http://nginx.org/en/docs/http/ngx_http_rewrite_module.html

Moreover, proxy_cache only works when you proxy somewhere, and
there is no proxy_pass in your "location /".

To check multiple caches consider actual proxying instead, this
will allow you to naturally use multiple caching layers.

--
Maxim Dounin
http://nginx.org/
_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Checking multiple caches before forwarding request to upstream

anish10dec
Thanks, I guess actual proxying is the only way out. I will try it out.

Posted at Nginx Forum: https://forum.nginx.org/read.php?2,273446,273454#msg-273454

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

Re: Checking multiple caches before forwarding request to upstream

anish10dec
In reply to this post by Maxim Dounin
Hi Maxim,

I found one way to make this work using lua to set the cache name. It seems
to be working ok, all my tests passed.

""" Lua Script
local resty_md5 = require "resty.md5"
local str = require "resty.string"
local md5 = resty_md5:new();
local posix = require("posix")
local days_30 = 1000 * 60 * 60 * 24 * 30
local days_90 = days_30 * 3

file_exists = function(path)
        file_stat = posix.stat(path);
        if file_stat == nil or file_stat.type ~= 'regular' then
                ngx.log(ngx.ERR, "file does not exists: ", path)
                return false
        end
        ngx.log(ngx.ERR, "file exists: ", path)
        return true;
end

pick_cache = function(last_modified)
        local now = ngx.now()
        if now - last_modified < days_30 then
                return "cache_recent"
        elseif now - last_modified < days_90 then
                return "cache_midterm"
        else
                return "cache_longterm"
        end
end



md5:update(ngx.var.request_uri)
local digest = md5:final()
local md5_str = str.to_hex(digest)
ngx.log(ngx.ERR, "md5: ", md5_str)

local cache_dirs = {
        "../cache_recent",
        "../cache_midterm",
        "../cache_longterm",
}

local file_name = string.sub(md5_str, -1) .. "/" .. string.sub(md5_str, -3,
-2)   .. "/" .. md5_str

for cache_count = 1, #cache_dirs do
        if file_exists(cache_dirs[cache_count] .. '/' .. file_name) then
                cache_name = string.gsub(cache_dirs[cache_count], ".*/", "")
                return cache_name
        end
end

--return pick_cache(ngx.now() - 10) -- from request header
--return pick_cache(ngx.now() - days_30) --  from request header
return pick_cache(ngx.now() - days_90) --  from request header
"""

Nginx conf:
set_by_lua_file $cache_name conf/cache_picker.lua;
proxy_cache $cache_name;

Posted at Nginx Forum: https://forum.nginx.org/read.php?2,273446,273473#msg-273473

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