<div dir="ltr">Very thorough and detailed explanation, even if it was "simplified". Both you and <span style="font-size:12.8px;white-space:nowrap">Reinis have been a tremendous help. </span></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Jul 28, 2016 at 11:07 AM, Robert Paprocki <span dir="ltr"><<a href="mailto:rpaprocki@fearnothingproductions.net" target="_blank">rpaprocki@fearnothingproductions.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hello,<div class="gmail_extra"><br><div class="gmail_quote"><span class="">On Thu, Jul 28, 2016 at 7:32 AM, Brian Pugh <span dir="ltr"><<a href="mailto:project722@gmail.com" target="_blank">project722@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr">Yesterday once I got the traffic going to the backend servers from nginx I noticed that I was pinned to "backend3", which is last in the order. And since I am the one setting this up I am the only user. So I changed up my order just to see the effects of calculating a new hash. Instead of:<div><br></div><div><span style="font-size:12.8px">upstream backend {</span><br></div><div>backend1</div><div>backend2</div><div>backend3</div><div>}</div><div><br></div><div>I listed them in the order:</div><div><br></div><div><span style="font-size:12.8px">upstream backend {</span><br></div><div>backend2</div><div>backend3</div><div>backend1 </div><div>}</div><div><br></div><div>then restarted nginx. At that point my traffic was pinned to backend1. This seems a bit odd to me in that it seems to be always choosing the last server in the order. Any thoughts on what might be happening and why it did not pin me to backend1 the first time and backend2 the second time?</div></div></blockquote><div><br></div></span><div>This sounds exactly like what should be expected. To better understand, let's look at a simple example of how hash-based selection _might_ occur (I say "might" because this is not exactly how Nginx performs its hashing, I'm simplifying for examples' sake, but it's good enough). We'll make a few assumptions:<br><br>- The hash key in this example is your IP address (we'll use 127.0.0.1 for simplicity)</div><div>- We will assume each backend has the same weight</div><div>- Arrays are zero indexed</div><div>- Our upstream block looks like such:</div><span class=""><div><div><span style="font-size:12.8px">upstream backend {</span><br></div><div>backend1</div><div>backend2</div><div>backend3</div><div>}</div></div></span><div>- We will kindly remember this is a conceptual example and not how Nginx does things under the hood (but this is clear enough)</div><div><br></div><div>Let's say that the whole upstream definition creates an array of servers, so in your first example you'd have an array of:</div><div><br></div><div>upstreams = { "backend1", "backend2", "backend3" }</div><div><br></div><div>The key "127.0.0.1" is run through a mathematical hash function to create an integer, and it will create the same integer every single time its run. For our example, let's say that hash("127.0.0.1") equals the number 438653. In order to select which backend to use, we compute our hash value 438652, modulo the number of backends we have in our upstream (is essentially the remainder after division). So,</div><div><br></div><div>438653 % 3 = 2<br></div><div><br></div><div>So we get index 2 from our array. Remember that our conceptual array is zero-indexed, so we select upstreams[2], or the third element in our array, which is "backend3". Every time a backend is selected for the key "127.0.0.1", "backend3" will be used. because that's the result of looking up upstreams[2]. Now, let's change the upstream block to such:<span class=""><br><br><div><span style="font-size:12.8px">upstream backend {</span><br></div><div>backend2</div><div>backend3</div><div>backend1 </div><div>}</div></span></div><div><br></div><div>Assuming nothing else has changed, we run through the same process again. hash("127.0.0.1") is 438653, and 438653 % 3 is still 2. So, we look up upstreams[2] (the third element in our array, same as last time), and we get "backend1". Given this upstream configuration, we will get the same result every time. In this example, the order we define backends matters, and this can be used to explain your results perfectly. You shouldn't expect that your key will be hashed to the first backend in your upstream block, you should only expect that the same key will produce the same _relative_ result every time it is hashed.</div><div><br></div><div>(And again to note, Nginx does do things slightly differently, rr peers are defined as a linked list, not an array, and lookup is not strictly hashval % list length; this is a conceptual example _only_)</div></div></div></div>
<br>_______________________________________________<br>
nginx mailing list<br>
<a href="mailto:nginx@nginx.org">nginx@nginx.org</a><br>
<a href="http://mailman.nginx.org/mailman/listinfo/nginx" rel="noreferrer" target="_blank">http://mailman.nginx.org/mailman/listinfo/nginx</a><br></blockquote></div><br></div>