redis / redis/node-redis

CreateCluster: Cannot read property 'master' of undefined when used with bitnami/redis-cluster

Open
#2,187 3 comments 5 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Bug stale
Dominant language
TypeScript
Stars
17.6k
Forks
2k
Avg merge
2d 3h
Merged PRs (30d)
40

Description

I am new to Redis and Node-redis. I have setup local redis using bitnami image. Below is a part of docker-compose.yml

  redis:
    image: bitnami/redis-cluster:7.0
    restart: always
    ports:
      - '6379:6379'
    expose:
      - 6379
    healthcheck:
      test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
      interval: 10s
      timeout: 5s
      retries: 5
    environment:
      ALLOW_EMPTY_PASSWORD: yes
      REDIS_CLUSTER_REPLICAS: 1
      REDIS_NODES: redis
      REDIS_CLUSTER_CREATOR: yes
      REDIS_CLUSTER_ANNOUNCE_IP: localhost
      REDIS_CLUSTER_DYNAMIC_IPS: no

Below is nodejs program to initialise redis cluster and add items to list.

  const registerEventHandlers = async (redisClient) => {
    redisClient.on("connect", () => console.log("Redis Client connected"));
    redisClient.on("ready", () => console.log("Redis Client is ready to use"));
    redisClient.on("reconnecting", () => console.log("Redis Client reconnecting"));
    redisClient.on("error", (err) => console.log(`Redis Client Error : ${err}`));
    redisClient.on("end", () => console.log("Redis Client is gracefully terminated"));
  };

    const redisClient = redis.createCluster{
      rootNodes: [
        {
          url: "redis://localhost:6379"
        }
      ],
      useReplicas: true,
      defaults: {
        socket: {
          connectTimeout: 5000,
          reconnectStrategy: (attempts) => attempts > 3 ? new Error("Max retry attempt has been reached") : 1000
        }
      }
    });
    await registerEventHandlers(redisClient);
    await redisClient.connect();
    
    // Fails with undefined master error
    const result = await redisClient.rPush(key, items); // items could be string or array of string e.g. ["test1", "test2"]

    // Fails with undefined length error
    const result = await redisClient.sendCommand(["LPOP", key, count.toString()]);

   // ignores the count and always returns only 1 item from the list
    const result = await redisClient.lPop(key, count);

This program work fine if we use createClient instead of createCluster to connect to bitnami redis cluster container. yeah lPop ignores the count and always returns/pops only 1 item from list. aport from that no errors/exceptions as such.

if createCluster is used, rPush, lPop fails with error **Cannot read property 'master' of undefined**: This error I can reproduce with my local docker-setup.

This exact same code works fine when used against production server (AWS ElastiCache Redis Cluster, Engine Version:6.2.6). So I strongly believe this could be due to my docker-compose setup.

Please suggest me if I am doing anything wrong or way to fix this issue.
Complete stack:

TypeError: Cannot read property 'master' of undefined
      at RedisClusterSlots.getSlotMaster (node_modules/@redis/client/dist/lib/cluster/cluster-slots.js:50:81)
      at RedisClusterSlots.getClient (node_modules/@redis/client/dist/lib/cluster/cluster-slots.js:58:25)
      at Commander._RedisCluster_execute (node_modules/@redis/client/dist/lib/cluster/index.js:102:73)
      at Commander.sendCommand (node_modules/@redis/client/dist/lib/cluster/index.js:65:98)
      at Commander.commandsExecutor (node_modules/@redis/client/dist/lib/cluster/index.js:62:75)
      at Commander.BaseClass.<computed> [as rPush] (node_modules/@redis/client/dist/lib/commander.js:8:29)

sendCommand also seems to fail in case of cluster. Fails against AWS redis server.

const result = await redisClient.sendCommand(["LPOP", key, count.toString()]);
                                    or
const result = await redisClient.sendCommand(["LPOP", key]);
Both fails with below error:

/home/ubuntu/redistest/node_modules/@redis/client/dist/lib/client/RESP2/encoder.js:6
    let strings = '*' + args.length + CRLF;
                             ^

TypeError: Cannot read properties of undefined (reading 'length')
    at encodeCommand (/home/ubuntu/redistest/node_modules/@redis/client/dist/lib/client/RESP2/encoder.js:6:30)
    at RedisCommandsQueue.getCommandToSend (/home/ubuntu/redistest/node_modules/@redis/client/dist/lib/client/commands-queue.js:187:45)
    at Commander._RedisClient_tick (/home/ubuntu/redistest/node_modules/@redis/client/dist/lib/client/index.js:434:76)
    at Commander._RedisClient_sendCommand (/home/ubuntu/redistest/node_modules/@redis/client/dist/lib/client/index.js:418:82)
    at Commander.sendCommand (/home/ubuntu/redistest/node_modules/@redis/client/dist/lib/client/index.js:173:100)
    at /home/ubuntu/redistest/node_modules/@redis/client/dist/lib/cluster/index.js:65:148
    at Commander._RedisCluster_execute (/home/ubuntu/redistest/node_modules/@redis/client/dist/lib/cluster/index.js:105:26)
    at Commander.sendCommand (/home/ubuntu/redistest/node_modules/@redis/client/dist/lib/cluster/index.js:65:98)
    at /home/ubuntu/redistest/app.js:27:33
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

Please help me to proceed in this case. Apologies if this is already being discussed, please point me to the same. Thanks for the support.

Environment:

MacOS 12.4, Tests against Bitnami Redis Cluster.

  • Node.js Version: v14.15.5
  • Redis Server Version: bitnami/redis-cluster:7.0
  • Node Redis Version: redis@4.2.0
  • Platform: Mac OS 12.4

Ubuntu 22.04 LTS, Tests against AWS ElastiCache Redis Cluster.

  • Node.js Version: v16.16.0
  • Redis Server Version: AWS ElastiCache Redis Cluster, Engine Version:6.2.6
  • Node Redis Version: redistest@1.0.0 /home/ubuntu/redistest
    └── redis@4.2.0
  • Platform: Ubuntu 22.04 LTS

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the cluster failures with the provided docker-compose setup and the example app.js calls. Read node_modules/@redis/client/dist/lib/cluster/cluster-slots.js and cluster/index.js, then trace the sendCommand path through client/RESP2/encoder.js. Done means the cluster commands no longer produce undefined slot or argument errors, with behavior checked against the reported Redis environments.

Written by the indexing model from the issue text.

Assessment

Tech stack
docker, javascript, node.js, redis
Domain
backend, databases, distributed-systems
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.