How can I solve the AWS MemoryDB "Moved <MemoryDB-Endpoint>" problem?

233 views Asked by At

I'm currently facing an issue with AWS MemoryDB for Redis and its integration within a Lambda function. Initially, the setup was functioning correctly, allowing both read and write operations within the MemoryDB cluster using the "ioredis" node dependency.

However, after approximately a day, attempting read and write operations via the Lambda function on MemoryDB resulted in failure. The error message captured in CloudWatch is accessible through this enter image description here

I've googled available resources but couldn't find relevant solutions specifically addressing MemoryDB and the "ioredis" node dependency.

Below is the code snippet from my Lambda function:

'use strict';

import Redis from "ioredis";
import dotenv from 'dotenv';
dotenv.config();

if (typeof redisClient === 'undefined') {
  var redisClient = new Redis({
    port: 6379,
    host: process.env.MEMORYDB_HOST,
    tls: {},
  });;
}

export const handler = async (event) => {
  
  let response = {
    message: "welcome"
  }
  
  let act_mode = ""
  let request_body = {};
  request_body = JSON.parse(event.body)
  let app_version = request_body.app_version
  await redisClient.set("current_app_version", app_version);
      
  let result = await redisClient.get("current_app_version") 
}

Someone recommended to add -c flag to the redis cli. But I do not use redis-cli command. I am using "ioredis" node dependency at Lambda function.

1

There are 1 answers

0
Quassnoi On

When working in clustering mode, Redis stores different keys on different nodes.

When a wrong node is asked about a key, Redis issues the redirection error (-MOVED) to notify the client that it has to connect to the correct node.

When you construct the ioredis client using Redis (the default constructor), the client doesn't process redirection errors correctly and throws them as exceptions.

You should construct the client using Cluster:

import { Cluster } from "ioredis";

const redisClient = new Cluster([{
    port: 6379,
    host: process.env.MEMORYDB_HOST
}], { redisOptions: { tls: {} } });

This way, the client does understand MOVED requests and creates additional connections as needed.

Note that the first argument to this constructor is an array of addresses, but you can use just one. As long as the client is able to connect to any node in the cluster, it will follow the redirects and discover the other nodes.

Providing all nodes in the constructor will create the connections in advance, so it can speed up your lambda's cold startup a little bit.