Skip to content
This repository has been archived by the owner on Aug 17, 2023. It is now read-only.

connect ETIMEDOUT 172.17.0.6:7000 #19

Closed
sparachi opened this issue Oct 19, 2016 · 11 comments
Closed

connect ETIMEDOUT 172.17.0.6:7000 #19

sparachi opened this issue Oct 19, 2016 · 11 comments

Comments

@sparachi
Copy link

I wrote an node api using thunk-redis, and testing from POSTman. The data get or set works sometimes and sometimes it just hangs in there, and times out with the error message "connect ETIMEDOUT 172.17.0.6:7000"

I followed steps here in https://github.com/Grokzen/docker-redis-cluster to create a docker image with 7000 -> 7002 exposed for clients.

The documentation is not so helpful w.r.t cluster configuration. How do I debug and isolate the issue?

@zensh
Copy link
Member

zensh commented Oct 20, 2016

Could you connect redis with redis-cli ?

@sparachi
Copy link
Author

Yes I can connect to using cli. I can connect from the node app also, but the connection is not reliable. It hangs couple of times, and does not return anything.

@sparachi
Copy link
Author

sparachi commented Oct 25, 2016

@zensh any debugging help would be appreciated.

@zensh
Copy link
Member

zensh commented Oct 26, 2016

@sparachi I think that this option killed the client. cluster-node-timeout 5000 https://github.com/Grokzen/docker-redis-cluster/blob/master/docker-data/redis-conf/7000/redis.conf#L4

@sparachi
Copy link
Author

I have removed the entry in the redis.conf and restarted the docker container. But the issue still persists.

@zensh
Copy link
Member

zensh commented Oct 27, 2016

@sparachi I got the problem: redis internal IP and external IP are different.

when connect:

const cli = redis.createClient([
  "127.0.0.1:7000",
  "127.0.0.1:7001",
  "127.0.0.1:7002",
  "127.0.0.1:7003",
  "127.0.0.1:7004",
  "127.0.0.1:7005",
  "127.0.0.1:7006",
  "127.0.0.1:7007"
])

but cluster slots command give me:

[ [ 0, 5460, [ '172.17.0.2', 7000 ], [ '172.17.0.2', 7003 ] ],
  [ 10923, 16383, [ '172.17.0.2', 7002 ], [ '172.17.0.2', 7005 ] ],
  [ 5461, 10922, [ '172.17.0.2', 7001 ], [ '172.17.0.2', 7004 ] ] ]

that means:
If we send a command client.get("somekey") on connection 127.0.0.1:7000, redis cannot find the key on 7000, and respond a error (error) MOVED 9842 172.17.0.2:7001, then client try to connect to 172.17.0.2:7001, but it is internal IP!

You can try this with redis-cli, look like:

127.0.0.1:7000> get 1
(error) MOVED 9842 172.17.0.2:7001

@zensh
Copy link
Member

zensh commented Oct 27, 2016

I can resolve it with a new option IPMap

zensh added a commit that referenced this issue Oct 27, 2016
@sparachi
Copy link
Author

sparachi commented Oct 31, 2016

@zensh I still the see the same behavior. Below is my modified createClient method.

I exposed all the 6 ports
docker run -d --name redis-cluster -p 7000:7000 -p 7001:7001 -p 7002:7002 -p 7003:7003 -p 7004:7004 -p 7005:7005 redis-cluster

(Ideally I think I need to do writes on master i.e. 7000 - 7002, reads on slaves 7003-7005. But for now in dev I exposed all the 6 ports since all are running on the same instance of docker container)

let clusterNodes = [
'127.0.0.1:7000',
'127.0.0.1:7001',
'127.0.0.1:7002',
'127.0.0.1:7003',
'127.0.0.1:7004',
'127.0.0.1:7005'
];

let options = {
clusterMode: true,
noDelay: true,
usePromise: blueBird,
IPMap: {
'172.17.0.7:7000': '127.0.0.1:7000',
'172.17.0.7:7001': '127.0.0.1:7001',
'172.17.0.7:7002': '127.0.0.1:7002',
'172.17.0.7:7003': '127.0.0.1:7003',
'172.17.0.7:7004': '127.0.0.1:7004',
'172.17.0.7:7005': '127.0.0.1:7005'
}
};

let redisClient = redis.createClient(clusterNodes, options);

In my GET method I do this

return new Promise(function(resolve, reject) {
// id is the parameter passed to this method
let data = {};
data.key = JSON.parse(id);
console.log("value to query " + data.key);
redisClient.get(data.key).then(function (res) {
console.log('data get from redis:', res);
if(res){
data.response = res;
} else {
data.response = 'null';
}
return redisClient.quit();
})
.then(function (res) {
console.log('redis client quit:', res);
// redis client quit: OK
return resolve(data);
})
.catch(function (err) {
console.error(err);
return reject(err);
});
});

In my SET method I do this below

return new Promise(function(resolve, reject) {
let data = {"status": "success"};

  redisClient.set(dataReceived.key, dataReceived.value)
  .then(function (res) {
    console.log('data set to redis: ', res);
    return redisClient.get(dataReceived.key);
  })
  .then(function (res) {
    console.log('data get from redis:', res);
    return redisClient.quit();
  })
  .then(function (res) {
    console.log('redis client quit:', res);
    // redis client quit: OK
    return resolve(data);
  })
  .catch(function (err) {
    console.error(err);
    return reject(err);
  });

});

Even though if it works, I have some questions around the production setup.

  1. do I need to mention all the docker ip's, as well as EC2 host ip's when I createClient() in my node API. Since all my redis nodes dockerized, node api dockerized will be running in different EC2 instances and they will have dynamic IP's.
  2. did someone try this in production deployment as you know of

@zensh
Copy link
Member

zensh commented Oct 31, 2016

@sparachi Currently no way to announce different IP/port. redis/redis#2704

@sparachi
Copy link
Author

redis/redis#2527 (comment)
says it is implemented. I am confused here.

@zensh
Copy link
Member

zensh commented Nov 1, 2016

@sparachi

This proposal is implemented in Redis unstable branch. The first stable version of Redis to support that will be 4.0, released as RC1 15th of October 2016. Anyone testing this support with success in testing environments? Feedbacks appreciated.

@zensh zensh closed this as completed Oct 8, 2017
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants