Vance Lucas
Vance Lucas

Reputation: 2838

Nginx caching with variable param order

I am generating a cache key with nginx based on the request URI and query params that checks memcache directly and then serves the page from PHP-FPM if a cache key is not found. My problem is that many URLs have query string options that come in in varying orders and thus generated two or more separate cache keys per response.

My cache setting is something like:

set $cache_key  "$uri?$args";

So URLs that come in like these with query string params in different orders end up generating multiple possible cache keys for the same type:

http://example.com/api/2.2/events.json?id=53&type=wedding&sort=title&limit=10
http://example.com/api/2.2/events.json?id=53&limit=10&type=wedding&sort=title
http://example.com/api/2.2/events.json?id=53&limit=10&sort=title&type=wedding

Ad nauseum for n! possibilities...

The end result is that memcache often fills up a lot faster than it should because I have a potential n!-1 duplicate copies of cached content simply because the query string parameters come in a different order. Is there a way I can order them alphabetically before setting the cache key to avoid this? Are there other ways to elegantly solve this issue?

Upvotes: 15

Views: 9041

Answers (2)

preinheimer
preinheimer

Reputation: 3722

Presumably you're generating the links yourself, rather than trying to re-order them in nginx, could you use an output re-writer to ensure they're in a consistent order at page generation?

Upvotes: 0

Sergei Lomakov
Sergei Lomakov

Reputation: 2061

if you know which parameters are important for cache key generation then you could specify their manually. Based on your example I wrote next example:

set $cache_key "$uri?id=$arg_id&type=$arg_type&sort=$arg_sort&limit=$arg_limit";

Or you could use embedded perl and write your own function that will generate cache key, please see examples here http://wiki.nginx.org/Configuration#Embedded_Perl_examples

Upvotes: 4

Related Questions