Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Reduce number of connections to one cluster node by shuffling nodes. #764

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 6 commits into from
Closed

Conversation

vstepanyuk
Copy link

No description provided.

@vstepanyuk
Copy link
Author

Now session handler all time tries to connect and get all nodes from first node that defined in session.save_path

@beberlei
Copy link

This is also necessary to make PHPRedis available during a network partition where the first node in the list is still available to the webserver, but does not have a connection to the majority of the cluster. This will take down the whole web application even though the cluster is still running.

@michael-grunder
Copy link
Member

Hey,

Thanks so much for the pull request, and sorry for the late response. I have pulled your code down and run it but I ran into a couple of issues.

shuffle operates on the array itself (a.k.a. takes a reference), which means that the way the code works now, it will modify the userland seed array in place (and the user will get it back with the reordered version).

More importantly, when I run it through the unit tests, it actually causes corruption if you call RedisCluster::__construct multiple times (again, this is to do with the weird reference thing in PHP).

The solution is to make a copy of the array, shuffle the copy, and then use the shuffled copy for construction. Something like this:

/* Helper method to shuffle a retrieved array */
int cluster_shuffle_array(INTERNAL_FUNCTION_PARAMETERS, zval **array) {
    zval *func, *copy, **args[1], *retval = NULL;

    /* Init function name */
    MAKE_STD_ZVAL(func);
    ZVAL_STRINGL(func, "shuffle", sizeof("shuffle")-1, 0);

    /* shuffle operates on the provided value, so copy the array */
    MAKE_STD_ZVAL(copy);
    *copy = **array;
    zval_copy_ctor(copy);
    args[0] = ©

    /* Call shuffle on our copy */
    if (call_user_function_ex(CG(function_table), NULL, func, &retval, 1, args, 0, NULL
                              TSRMLS_CC) == FAILURE)
    {
        efree(func);
        zval_dtor(copy);
        efree(copy);
        return 0;
    }

    /* Update pointer to copied and randomized array */
    *array = copy;

    /* cleanup */
    if (retval) efree(retval);
    efree(func);

    return 1;
}

I pulled the logic into a separate function because it became enough code that it probably shouldn't live in multiple places..

But here is where the Zend API makes it fun for us. You can't use INTERNAL_FUNCTION_PARAMETERS from within a session method.

What do you think about using fyshuffle inside of cluster_init_seeds?

Sorry about the wall of text!

@vstepanyuk
Copy link
Author

Hi, thx for comment. It's really good point to put it into cluster_init_seeds and just shuffle HashTable there

@vstepanyuk
Copy link
Author

I will try to do that

@michael-grunder
Copy link
Member

Awesome, thanks. There is already an fyshuffle in cluster_library.c

Let me know if you have any questions :)

@vstepanyuk vstepanyuk closed this Mar 30, 2016
@vstepanyuk
Copy link
Author

Created new pull request #777

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants