Nginx – How to see / recalculate a hash based load balancing in nginx

load balancingnginx

in my setup I use Nginx as reverse proxy and load balancer in front of IIS, using the hash directive.

For hash key I am using cookie which contains the customer ID – by this I am grouping the users (the connections) by the Customer they are currently working for. (The app has N-Customers, each customer has N-Users, each User can work for different Customers, but at single point of time it work for one Customer). By this I am having better IIS internal cache usages, as the users forwarded to same backend are using normally the same data. The problem with hash directive is that it cannot guarantee that the clients are good distributed between the backends.

So here my questions about the hash load balancing:

  • can I somehow see, which hash on which backend is assigned?
  • can I reset / recalculate the already assigned keys on base the daily app usage? seems that also on restart / reload the hashes are kept.

Here is my config:

upstream backend_web { 
  hash $http_currentcustomerid;
  server 192.168.0.1:80 max_fails=1 fail_timeout=20s weight=9 ;
  server 192.168.0.2:80 max_fails=1 fail_timeout=20s weight=11 ;
  server 192.168.0.3:80 max_fails=1 fail_timeout=20s weight=4 ;
}

Thanks for any help in advance.

Best Answer

can I somehow see, which hash on which backend is assigned?

As far as I know, there is no way to see that in nginx. You can see the values in the upstream requests from nginx, and possible logging there.

Another alternative is to make a Perl script where you can use the Cache::Memcached library to generate hashes from User ID.

can I reset / recalculate the already assigned keys on base the daily app usage? seems that also on restart / reload the hashes are kept.

No. The hash function is always a mapping function from two values (hash key and number of upstreams) to output key, and the "to" value does not change unless the number of upstreams changes or "from" value changes.

This fact also means that the weight argument in your server directive does nothing. weight only applies when you use round-robin mode for upstream requests.

I don't know if there exists any way both to have consistent destination nodes according to the HTTP header value and distribution of requests according to some criteria. The two goals are contradictory.