views:

600

answers:

1

I am using nginx and redis in my website. For several items on my site, I want to add tracking params to their urls so that when a user clicks on an item, I can collect statistics of user usage apart from serving the content user requested. I am looking for methods on how to capture this statistics in redis from nginx, i.e. without hitting the background application.

For eg., suppose I have several rows of tables on my page and each table hold items in row/column format. So, for an item in {table: 2, row: 1, column: 3} if the actual url is: www.mysite.com/news/dodi, then I want to embed the url: www.mysite.com/news/dodi/day=29?table=2&row=1&column=3. When the user clicks on it, nginx will hit redis to fetch the content and also update the appropriate statistics (here can be increment day-29, table-2, ...).

Any suggestion on how I achieve this without hitting the background app?

+1  A: 

For the tracking parameters, keep this type of work outside the scope of the users request. Don't make them pay the latency penalty for stats tracking. Cron a script that extracts the parameters from access.log and updates redis and/or database.

In terms of caching content, there is a recently released nginx redis module that works in much the same way as the memcached module. Only GET and SELECT are presently implemented. The assumption is that your application is populating the cache.

http://wiki.nginx.org/Nginx3rdPartyModules#HTTP_Redis_Module

Sample nginx.conf:

http
{
 ...
        server {
            location / {
                set $redis_db   "0";
                set $redis_key  "$uri?$args";
                redis_pass      127.0.0.1:6379;
                error_page      404 502 504 = @fallback;
             }

             location @fallback {
                 proxy_pass      backed;
             }
        }
}
Ryan Cox
Good point regarding Cron script and the Nginx's Redis module. A few questions: [1] How difficult is it to add SET/INCR to the NginxRedis module? [2] As per the above example, the content is fetched from redis. Since this queries the redis, can there be extra job added with this to increment a few redis keys? Is there some method to do this? Given redis is fast, the penalty on user for this added job will be in the order of microseconds -- hence not a perceptible latency overhead on user.
Ethan Collins
the whole module is ~600 lines of code. so adding additional commands shouldn't be a huge deal. That said, I've never written an nginx module.
Ryan Cox
Thanks Ryan. Can you also shed some light on query #2 above.
Ethan Collins
Not certain. You can dig around in the sourcecode to the module and see pretty clearly where the redis operations occur.
Ryan Cox