Skip to content
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

Predis, Sharding and Moved responses #259

Closed
Emdis opened this issue Jun 25, 2015 · 10 comments
Closed

Predis, Sharding and Moved responses #259

Emdis opened this issue Jun 25, 2015 · 10 comments

Comments

@Emdis
Copy link

Emdis commented Jun 25, 2015

Hi folks,

I’m working with your great Predis PHP library to connect to a Redis Cluster.
Everything works fine, I can connect to the nodes but when I set a testing key in the Cluster I get the following response:

MOVED 1033 X.X.X.X:6379

This is totally fine as I understand that using sharding we need to point to the right instance.

My question is on what to do next. Should I programmatically use the value returned by your library and try my command again or is there a automatic feature that can take care of that ?

Thanks a lot !!

@nrk
Copy link
Contributor

nrk commented Jun 30, 2015

It looks like you did not configure Predis to use redis-cluster but instead you are using it with the plain old client-side sharding logic (which is also the default behaviour). You should configure the client setting the option cluster with the value redis to let the client know it must play along with redis-cluster. Quick example:

$client = new Predis\Client([$node1, $node2, ...], ['cluster' => 'redis']);

Doing so will make it possible for the client to automatically handle -MOVED or -ASK responses coming from Redis nodes.

I'm closing this issue since I guess it is indeed only a mis-configuration of the client, but feel free to re-open it if you think there is actually more to that.

@nrk nrk closed this as completed Jun 30, 2015
@Emdis
Copy link
Author

Emdis commented Jul 1, 2015

Hi,

I have a Redis Cluster with 3 master nodes and 3 slave ones.
I'm using Predis version '1.0.1'
Here is my code below:

<?php
require "/opt/php/vendor/predis/autoload.php";
Predis\Autoloader::register();

try {

$parameters = array('tcp://X.X.X.X/?password=secret', 'tcp://Y.Y.Y.Y/?password=secret','tcp://Z.Z.Z.Z/?password=secret');

$options = array("cluster", "redis");
$redis = new Predis\Client(
        $parameters
        , $options);

    echo $redis->set('test','It works !') .PHP_EOL;
    echo "Successfully connected to Redis";

}
catch (Exception $e) {
    echo "Couldn't connect to Redis" .PHP_EOL;
    echo $e->getMessage() .PHP_EOL;
$pos =strpos((string)$e->getMessage(), 'MOVED');
        if ($pos === false)
        echo "Understood" .PHP_EOL;
else
        echo "Needs to relaunch with new server" .PHP_EOL;

$pattern = '/MOVED (\d+) ([\d\.]+)\:(\d+)/';
preg_match($pattern, (string)$e->getMessage(), $matches, PREG_OFFSET_CAPTURE);
$parameters = array((string)('tcp://' . $matches[2][0] . '/?password=secret'));
$redis = new Predis\Client(
        $parameters
        , $options));

echo $redis->set('test','It works !') .PHP_EOL;
?>

Here is what I'm getting when I launch my php code:

Couldn't connect to Redis
MOVED 15495 Z.Z.Z.Z:6379
Needs to relaunch with new server
OK


So I would like to know what I'm doing wrong for the client to automatically handle -MOVED or -ASK responses coming from Redis nodes please.

Thanks a lot !

@nrk
Copy link
Contributor

nrk commented Jul 8, 2015

The client options array must be a named array, you are passing the wrong values so that's why it's not working:

$options = array("cluster" => "redis");`

and not

$options = array("cluster", "redis");

@nrk nrk mentioned this issue Jul 8, 2015
@Emdis
Copy link
Author

Emdis commented Jul 8, 2015

Thanks a lot !

Unfortunately now I'm getting the following error:

NOAUTH Authentication required.

This is my current code

$parameters = array('tcp://X.X.X.X/?password=secret', 'tcp://Y.Y.Y.Y/?password=secret','tcp://Z.Z.Z.Z/?password=secret');

$options = array("cluster" => "redis");
$redis = new Predis\Client(
$parameters
, $options);

As you can see the password is in the URI itself so I'm thinking it should work but it doesn't ...
Do I have to set the password in a named array as well ? If so how can I do that with my cluster connection string ?

Thanks a lot !

@nrk
Copy link
Contributor

nrk commented Jul 23, 2015

If you set a password for the known nodes in $parameters this will work until you get a new node from Redis in a -MOVED or -ASK response at runtime. If you check the originating node of the -NOAUTH response you will notice that it comes from a node not included in the list specified by $parameters, otherwise I can't think of any other reason.

It is possible to apply a set of common parameters (in your case, the password) for the connections to new nodes returned by Redis in -MOVED or -ASK responses, the configuration is a bit convoluted though:

$parameters = [
    "tcp://127.0.0.1:7001?password=secret",
    "tcp://127.0.0.1:7002?password=secret"
];

$options = [
    // You can choose any name instead of "default_params",
    // as this is just a custom option.
    "default_params" => ['password' => 'secret'],
    "cluster" => function ($options) {
        $cluster = new Predis\Connection\Aggregate\RedisCluster($options->connections);
        $cluster->setDefaultParameters($options->default_params);

        return $cluster;
    },
];

$client = new Predis\Client($parameters, $options);

This aspect of the configuration may be improved in the future.

@chishiuanlu
Copy link

chishiuanlu commented Feb 8, 2018

Hi,
We are trying to use Predis as client to work with AWS ElastiCache Redis cluster and have had similar error.
Our cluster setup is with 2 shards and each shard has two nodes (one master and one read replicas.)
We haven't setup access control to the nodes.
We setup the config as:

$parameters' = [
    'tcp://clusterConfigEndpoint',
    'tcp://shard1Node1Endpoint?alias=master',
    'tcp://shard1Node2Endpoint',
    'tcp://shard2Node1Endpoint',
    'tcp://shard2Node2Endpoint',
];
$options = [
    'cluster' => 'redis'
];
$client = new Predis\Client($parameters, $options);

Some of the queries has worked fine but several queries from the application would get -MOVED error message.
We have tried taking out the cluster endpoint, not using alias and other combination, but didn't seem to fix the issue.
Could you please help to elaborate what could be the cause of it?
Thanks much.

@chishiuanlu
Copy link

After some testing, it seems like the pipeline command caused the issue.
Taking out usage of pipeline and use get, set... commands directly seems fix the issue so far.
Is it not proper to use pipeline with cluster mode?
Any suggestion would be really appreciated.

@vzverev78
Copy link

vzverev78 commented Oct 5, 2018

@sanarena
Copy link

sanarena commented Jan 29, 2021

I've finally managed to connect to redis cluster without getting MOVED issue when used connection string like this:

$redis = new Predis\Client(['tcp://hostname.example.org:6379'], ['cluster' => 'redis']);

Sharing here for next people who might come here looking for this.

@blessenabrahamnw18
Copy link

blessenabrahamnw18 commented Aug 16, 2023

'redis' => [
        'client' => 'predis',
        'options' => [
            'cluster' => 'redis',
            'parameters' => [
                'connections' => [
                    'tcp' => [
                        'type' => 'pooled',
                        'limit' => 10,
                    ],
                ],
            ],
        ],
        'clusters' => [
            'default' => [
                [
                    'connection' => [
                        'scheme' => 'tcp',
                        'host' => 'HOST,
                        'password' => 'PASSWORD',
                        'port' => 6379,
                    ],
                ],
            ],
        ],
    ], 
    
    Sharing here for next people who might come here looking for this.

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

No branches or pull requests

6 participants