Ioredis: using ioredis with AWS ElastiCache, Redlock and socket-io.redis

Created on 16 Feb 2017  路  3Comments  路  Source: luin/ioredis

Trying ioredis as it seems to have better features to handle MOVED errors (getting those with node_redis when my app moved to a cluster). But having trouble getting a cluster hello world test working with ioredis.

node v6.9.3,

package.json

json { "name": "Test", "version": "1.1.2", "dependencies": { "ioredis" : "3.0.0-0" }, "devDependencies": { "mocha": "3.2.0", "chai": "3.5.0" } }

mocha test

````json
var expect = require('chai').expect;
var should = require('chai').should()

var IORedis = require("ioredis");
var redisClient = IORedis.Cluster([{host:'host1'},{host:'host2'}]);

describe('Redis tests', function () {

it('should hmset', function (done) {
redisClient.hmset('hmkey' , {name1: "value1", name2: "value2"})
redisClient.set('key1' , 'value1', 'EX', 10)
done();
})
})
````

exception on running the above test

bash % node_modules/mocha/bin/mocha ioredisTest.js TypeError: this.resetOfflineQueue is not a function at Function.Cluster (/home/ec2-user/test/node_modules/ioredis/lib/cluster/index.js:78:8) at Object.<anonymous> (/home/ec2-user/test/ioredisTest.js:7:27) at Module._compile (module.js:570:32) at Object.Module._extensions..js (module.js:579:10) at Module.load (module.js:487:32) at tryModuleLoad (module.js:446:12) at Function.Module._load (module.js:438:3) at Module.require (module.js:497:17) at require (internal/module.js:20:19) at /home/ec2-user/test/node_modules/mocha/lib/mocha.js:222:27 at Array.forEach (native) at Mocha.loadFiles (/home/ec2-user/test/node_modules/mocha/lib/mocha.js:219:14) at Mocha.run (/home/ec2-user/test/node_modules/mocha/lib/mocha.js:487:10) at Object.<anonymous> (/home/ec2-user/test/node_modules/mocha/bin/_mocha:459:18) at Module._compile (module.js:570:32) at Object.Module._extensions..js (module.js:579:10) at Module.load (module.js:487:32) at tryModuleLoad (module.js:446:12) at Function.Module._load (module.js:438:3) at Module.runMain (module.js:604:10) at run (bootstrap_node.js:394:7) at startup (bootstrap_node.js:149:9) at bootstrap_node.js:509:3

Most helpful comment

preliminary testing indicates ioredis working for all 3 use cases. just passing the single AWS ElastiCache load balancer address to IORedis.Cluster and using the same in a single element client array in Redlock. For socke.io-redis created two non Cluster IORedis clients (with createClient) for pub/sub as socket.io-redis manages cluster behavior on its own.

All 3 comments

You missed the keyword new: new IORedis.Cluster({...})

Silly mistake on my side. Thanks for catching it as well as making this library available. My initial test works now. Do you know ioredis has been tested/used in these three scenarios and anything to watch out for or any other thoughts on such usage.

  1. AWS ElastiCache. I read a thread about a fix you made over a year ago related to failover with this. With the latest version of ioredis will it work out of the box with ElastiCache or any special configuration to be set when initializing? AWS gives a single end point for the full cluster. Can I just pass it to the IORedis.Cluster constructor or do I need to pass the individual node end points?
  2. socket.io-redis (https://github.com/socketio/socket.io-redis). Their docs say to pass node_redis handles for pub/sub clients. And it is working well so far with AWS ElastiCache for my use case. To avoid two redis libraries in my app I 'm thinking of passing in two ioredis handles for socket-io.redis pub/sub clients.
  3. redlock. On this I got this basic test working I will evaluate more. Without a cluster mode client handle it fails with MOVED errors.

````javascript
var expect = require('chai').expect;
var should = require('chai').should()

var IORedis = require("ioredis");
var Redlock = require('redlock');

var redisClient = new IORedis.Cluster([{host:'host1'},{host:'host2'}]);

var distributeRedisdLock = new Redlock(
// you should have one client for each redis node
// in your cluster
[redisClient],
{
// the expected clock drift; for more details
// see http://redis.io/topics/distlock
driftFactor: 0.01, // time in ms

// the max number of times Redlock will attempt
// to lock a resource before erroring
retryCount:  3,

// the time in ms between attempts
retryDelay:  200 // time in ms

}
);

distributeRedisdLock.on('clientError', function(err) {
console.log('A redlock error has occurred:', JSON.stringify(err));
});

describe('Redlock with IORedis tests', function () {

it('should test redlock', function (done) {

var ttl = 30000
var lockName = 'update-lock:'
// ONK-1325.
distributeRedisdLock.lock(lockName, ttl, function (err, lock) {
  if (err) {
    console.log(err.stack)
    console.log("unable to get lock")
    return done()
  }
  lock.unlock(function (lockReleaseErr) {
    if (lockReleaseErr) {
      console.log("lock release failed")
      console.log(lockReleaseErr.stack)
    }
    console.log("it worked")
    return done()
  })
})

})
})
````

preliminary testing indicates ioredis working for all 3 use cases. just passing the single AWS ElastiCache load balancer address to IORedis.Cluster and using the same in a single element client array in Redlock. For socke.io-redis created two non Cluster IORedis clients (with createClient) for pub/sub as socket.io-redis manages cluster behavior on its own.

Was this page helpful?
0 / 5 - 0 ratings