<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hello!<div><br></div><div>I have a use case for an even, consistent balancing of a caching layer upstream cluster. I.e using the "Ketama algorithm"</div><div>Current consistent hashing implementation in ngx_http_upstream_hash is hard-coded to '160' vbuckets  and real world results show a 20% variance in balancing, which is not acceptable in our case.</div><div><br></div><div>Following is a patch (Thanks to agentzh) that will allow a configurable vbuckets configuration param. Default will remain the same = 160. </div><div>Please consider pushing this "upstream" . No pun intended ;)</div><div><br></div><div>Koby N</div><div><br></div><div><div>--- a/src/http/modules/ngx_http_upstream_hash_module.c<span style="white-space:pre-wrap">       </span>2015-07-15 00:46:06.000000000 +0800</div><div>+++ b/src/http/modules/ngx_http_upstream_hash_module.c<span style="white-space:pre-wrap">        </span>2015-10-11 22:26:47.952670175 +0800</div><div>@@ -23,6 +23,7 @@ typedef struct {</div><div> </div><div> </div><div> typedef struct {</div><div>+    ngx_uint_t                          npoints;</div><div>     ngx_http_complex_value_t            key;</div><div>     ngx_http_upstream_chash_points_t   *points;</div><div> } ngx_http_upstream_hash_srv_conf_t;</div><div>@@ -66,7 +67,7 @@ static char *ngx_http_upstream_hash(ngx_</div><div> static ngx_command_t  ngx_http_upstream_hash_commands[] = {</div><div> </div><div>     { ngx_string("hash"),</div><div>-      NGX_HTTP_UPS_CONF|NGX_CONF_TAKE12,</div><div>+      NGX_HTTP_UPS_CONF|NGX_CONF_TAKE123,</div><div>       ngx_http_upstream_hash,</div><div>       NGX_HTTP_SRV_CONF_OFFSET,</div><div>       0,</div><div>@@ -296,7 +297,10 @@ ngx_http_upstream_init_chash(ngx_conf_t</div><div>     us->peer.init = ngx_http_upstream_init_chash_peer;</div><div> </div><div>     peers = us->peer.data;</div><div>-    npoints = peers->total_weight * 160;</div><div>+</div><div>+    hcf = ngx_http_conf_upstream_srv_conf(us, ngx_http_upstream_hash_module);</div><div>+</div><div>+    npoints = peers->total_weight * hcf->npoints;</div><div> </div><div>     size = sizeof(ngx_http_upstream_chash_points_t)</div><div>            + sizeof(ngx_http_upstream_chash_point_t) * (npoints - 1);</div><div>@@ -355,7 +359,7 @@ ngx_http_upstream_init_chash(ngx_conf_t</div><div>         ngx_crc32_update(&base_hash, port, port_len);</div><div> </div><div>         prev_hash.value = 0;</div><div>-        npoints = peer->weight * 160;</div><div>+        npoints = peer->weight * hcf->npoints;</div><div> </div><div>         for (j = 0; j < npoints; j++) {</div><div>             hash = base_hash;</div><div>@@ -391,7 +395,6 @@ ngx_http_upstream_init_chash(ngx_conf_t</div><div> </div><div>     points->number = i + 1;</div><div> </div><div>-    hcf = ngx_http_conf_upstream_srv_conf(us, ngx_http_upstream_hash_module);</div><div>     hcf->points = points;</div><div> </div><div>     return NGX_OK;</div><div>@@ -657,6 +660,19 @@ ngx_http_upstream_hash(ngx_conf_t *cf, n</div><div>     } else if (ngx_strcmp(value[2].data, "consistent") == 0) {</div><div>         uscf->peer.init_upstream = ngx_http_upstream_init_chash;</div><div> </div><div>+        if (cf->args->nelts > 3) {</div><div>+            hcf->npoints = ngx_atoi(value[3].data, value[3].len);</div><div>+</div><div>+            if (hcf->npoints == (ngx_uint_t) NGX_ERROR) {</div><div>+                ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,</div><div>+                                   "invalid npoints parameter \"%V\"", &value[3]);</div><div>+                return NGX_CONF_ERROR;</div><div>+            }</div><div>+</div><div>+        } else {</div><div>+            hcf->npoints = 160;</div><div>+        }</div><div>+</div><div>     } else {</div><div>         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,</div><div>                            "invalid parameter \"%V\"", &value[2]);</div></div></div>
</blockquote></div><br></div></div>