Avani Khabiya
Avani Khabiya

Reputation: 1318

AWS elasticache - Redis: Unable to debug for Redis errors

We are implementing caching using AWS Elasticache with Redis and are using nodejs for connecting it with the Redis. Creating a sorted set and adding and getting elements to and from it. It is working fine on local machine, while not working on Staging. Here is the code,

const redis = require("redis")
const redisOption = {
    host: redis_host_url,
    port: redis_port
}
let client = redis.createClient(redisOption);
console.log(client);
client = promisify(client.zadd).bind(client);
console.log(client);
let response = await client("abc",1,"string_to_add");
console.log(response);

Getting response printed on local machine, but Lambda logs does not contain the last console. Client is:

RedisClient {
  _events: [Object: null prototype] { newListener: [Function] },
  _eventsCount: 1,
  _maxListeners: undefined,
  address: 'XXXXXXXXXX:6379',
  connection_options: { port: 6379, host: 'XXXXXXXXXX', family: 4 },
  connection_id: 0,
  connected: false,
  ready: false,
  should_buffer: false,
  command_queue:
   Denque {
     _head: 0,
     _tail: 0,
     _capacityMask: 3,
     _list: [ <4 empty items> ] },
  offline_queue:
   Denque {
     _head: 0,
     _tail: 0,
     _capacityMask: 3,
     _list: [ <4 empty items> ] },
  pipeline_queue:
   Denque {
     _head: 0,
     _tail: 0,
     _capacityMask: 3,
     _list: [ <4 empty items> ] },
  connect_timeout: 3600000,
  enable_offline_queue: true,
  retry_timer: null,
  retry_totaltime: 0,
  retry_delay: 200,
  retry_backoff: 1.7,
  attempts: 1,
  pub_sub_mode: 0,
  subscription_set: {},
  monitoring: false,
  message_buffers: false,
  closing: false,
  server_info: {},
  auth_pass: undefined,
  selected_db: undefined,
  fire_strings: true,
  pipeline: false,
  sub_commands_left: 0,
  times_connected: 0,
  buffers: false,
  options:
   { host: XXXXXXXXXX,
     port: 6379,
     socket_keepalive: true,
     socket_initial_delay: 0,
     return_buffers: false,
     detect_buffers: false },
  reply: 'ON',
  reply_parser:
   JavascriptRedisParser {
     optionReturnBuffers: false,
     optionStringNumbers: false,
     returnError: [Function: returnError],
     returnFatalError: [Function: returnFatalError],
     returnReply: [Function: returnReply],
     offset: 0,
     buffer: null,
     bigStrSize: 0,
     totalChunkSize: 0,
     bufferCache: [],
     arrayCache: [],
     arrayPos: [] },
  stream:
   Socket {
     connecting: true,
     _hadError: false,
     _handle:
      TCP {
        reading: false,
        onread: [Function: onStreamRead],
        onconnection: null,
        [Symbol(owner)]: [Circular] },
     _parent: null,
     _host: null,
     _readableState:
      ReadableState {
        objectMode: false,
        highWaterMark: 16384,
        buffer: BufferList { head: null, tail: null, length: 0 },
        length: 0,
        pipes: null,
        pipesCount: 0,
        flowing: true,
        ended: false,
        endEmitted: false,
        reading: false,
        sync: true,
        needReadable: false,
        emittedReadable: false,
        readableListening: false,
        resumeScheduled: true,
        paused: false,
        emitClose: false,
        autoDestroy: false,
        destroyed: false,
        defaultEncoding: 'utf8',
        awaitDrain: 0,
        readingMore: false,
        decoder: null,
        encoding: null },
     readable: false,
     _events:
      [Object: null prototype] {
        end: [Array],
        connect: [Function],
        data: [Function],
        error: [Function],
        close: [Function],
        drain: [Function] },
     _eventsCount: 6,
     _maxListeners: undefined,
     _writableState:
      WritableState {
        objectMode: false,
        highWaterMark: 16384,
        finalCalled: false,
        needDrain: false,
        ending: false,
        ended: false,
        finished: false,
        destroyed: false,
        decodeStrings: false,
        defaultEncoding: 'utf8',
        length: 0,
        writing: false,
        corked: 0,
        sync: true,
        bufferProcessing: false,
        onwrite: [Function: bound onwrite],
        writecb: null,
        writelen: 0,
        bufferedRequest: null,
        lastBufferedRequest: null,
        pendingcb: 0,
        prefinished: false,
        errorEmitted: false,
        emitClose: false,
        autoDestroy: false,
        bufferedRequestCount: 0,
        corkedRequestsFree: [Object] },
     writable: true,
     allowHalfOpen: false,
     _sockname: null,
     _pendingData: null,
     _pendingEncoding: '',
     server: null,
     _server: null,
     [Symbol(asyncId)]: 7,
     [Symbol(lastWriteQueueSize)]: 0,
     [Symbol(timeout)]: null,
     [Symbol(kBytesRead)]: 0,
     [Symbol(kBytesWritten)]: 0 } }

Even console after the promisify is working, and is printing:

[Function: bound zadd]

But the last console is not printing anything. I am not able to debug as, AWS Elasticache doesn't offer logs for Redis.

Upvotes: 0

Views: 1757

Answers (1)

0x4a6f4672
0x4a6f4672

Reputation: 28245

You need to define a bastion host in your AWS setup and locally in ~/.ssh/config

Host your-bastion-host
    HostName <IP_of_your_bastion_host_on_EC2>
    Port 22
    User ec2-user
    IdentityFile ~/.ssh/<your_key_file_for_bastion_host>.pem
    ForwardAgent yes
    AddKeysToAgent yes

Using a Bastion host and a VPC, you are able to connect to the AWS Elasticache service by SSH port forwarding...

ssh your-bastion-host -Cv -N -L 6390:ec-replication-group-xyz.amazonaws.com:6379

..and "redis-cli" tool (It makes sense to forward the Redis port 6379 to a different port locally if you already have a Redis server installed locally)

redis-cli -h localhost -p 6390 
info
monitor

Then you can use in "redis-cli" the monitor command to display every command processed by the Redis server and the info command to get the most important information and statistics about the Redis server.

Upvotes: 0

Related Questions