MCPcopy Create free account
hub / github.com/Snapchat/KeyDB / clusterManagerGetAntiAffinityScore

Function clusterManagerGetAntiAffinityScore

src/redis-cli-cpphelper.cpp:370–439  ·  view source on GitHub ↗

Return the anti-affinity score, which is a measure of the amount of * violations of anti-affinity in the current cluster layout, that is, how * badly the masters and slaves are distributed in the different IP * addresses so that slaves of the same master are not in the master * host and are also in different hosts. * * The score is calculated as follows: * * SAME_AS_MASTER = 10000 * each r

Source from the content-addressed store, hash-verified

368 * so that the optimizer can try changing the configuration of the
369 * slaves violating the anti-affinity goals. */
370int clusterManagerGetAntiAffinityScore(clusterManagerNodeArray *ipnodes,
371 int ip_count, clusterManagerNode ***offending, int *offending_len)
372{
373 int score = 0, i, j;
374 int node_len = cluster_manager.nodes->len;
375 clusterManagerNode **offending_p = NULL;
376 if (offending != NULL) {
377 *offending = (clusterManagerNode**)zcalloc(node_len * sizeof(clusterManagerNode*), MALLOC_LOCAL);
378 offending_p = *offending;
379 }
380 /* For each set of nodes in the same host, split by
381 * related nodes (masters and slaves which are involved in
382 * replication of each other) */
383 for (i = 0; i < ip_count; i++) {
384 clusterManagerNodeArray *node_array = &(ipnodes[i]);
385 dict *related = dictCreate(&clusterManagerDictType, NULL);
386 char *ip = NULL;
387 for (j = 0; j < node_array->len; j++) {
388 clusterManagerNode *node = node_array->nodes[j];
389 if (node == NULL) continue;
390 if (!ip) ip = node->ip;
391 sds types;
392 /* We always use the Master ID as key. */
393 sds key = (!node->replicate ? node->name : node->replicate);
394 assert(key != NULL);
395 dictEntry *entry = dictFind(related, key);
396 if (entry) types = sdsdup((sds) dictGetVal(entry));
397 else types = sdsempty();
398 /* Master type 'm' is always set as the first character of the
399 * types string. */
400 if (node->replicate) types = sdscat(types, "s");
401 else {
402 sds s = sdscatsds(sdsnew("m"), types);
403 sdsfree(types);
404 types = s;
405 }
406 dictReplace(related, key, types);
407 }
408 /* Now it's trivial to check, for each related group having the
409 * same host, what is their local score. */
410 dictIterator *iter = dictGetIterator(related);
411 dictEntry *entry;
412 while ((entry = dictNext(iter)) != NULL) {
413 sds types = (sds) dictGetVal(entry);
414 sds name = (sds) dictGetKey(entry);
415 int typeslen = sdslen(types);
416 if (typeslen < 2) continue;
417 if (types[0] == 'm') score += (10000 * (typeslen - 1));
418 else score += (1 * typeslen);
419 if (offending == NULL) continue;
420 /* Populate the list of offending nodes. */
421 listIter li;
422 listNode *ln;
423 listRewind(cluster_manager.nodes, &li);
424 while ((ln = listNext(&li)) != NULL) {
425 clusterManagerNode *n = (clusterManagerNode*)ln->value;
426 if (n->replicate == NULL) continue;
427 if (!strcmp(n->replicate, name) && !strcmp(n->ip, ip)) {

Callers 1

Calls 15

zcallocFunction · 0.85
sdsdupFunction · 0.85
sdsemptyFunction · 0.85
sdscatFunction · 0.85
sdscatsdsFunction · 0.85
sdsnewFunction · 0.85
sdsfreeFunction · 0.85
sdslenFunction · 0.85
listRewindFunction · 0.85
listNextFunction · 0.85
dictCreateFunction · 0.70
dictFindFunction · 0.70

Tested by

no test coverage detected