sql >> Databasteknik >  >> NoSQL >> Redis

Hur ska jag ansluta till en Redis-instans från en AWS Lambda-funktion?

Jag har nu löst mitt eget problem, och jag hoppas att jag kan vara till hjälp för någon som upplever det här problemet i framtiden.

Det finns två viktiga överväganden när du ansluter till en databas som jag gjorde i koden ovan från en Lambda-funktion:

  1. När context.succeed() , context.fail() , eller context.done() anropas kan AWS frysa alla processer som inte har slutförts ännu. Det var detta som fick AWS att logga Connection closed vid det andra anropet till min API-slutpunkt – processen frystes precis innan Redis avslutade stängningen, tinades sedan vid nästa anrop, då den fortsatte precis där den slutade och rapporterade att anslutningen stängdes. Takeaway:om du vill stänga din databasanslutning, se till att den är helt stängd innan du kallar en av dessa metoder. Du kan göra detta genom att göra en återuppringning i en händelsehanterare som utlöses av att en anslutning stängs (.on('end') , i mitt fall).
  2. Om du delar upp din kod i separata filer och require dem överst i varje fil, precis som jag gjorde, kommer Amazon att cache så många av dessa moduler som möjligt i minnet. Om det orsakar problem, försök att flytta require() anropar inuti en funktion istället för överst i filen och exporterar sedan den funktionen. Dessa moduler kommer sedan att återimporteras när funktionen körs.

Här är min uppdaterade kod. Observera att jag också har lagt in min Redis-konfiguration i en separat fil, så att jag kan importera den till andra Lambda-funktioner utan att duplicera kod.

Händelsehanteraren

'use strict'

const lib = require('../lib/related')

module.exports.handler = function (event, context) {
  lib.respond(event, (err, res) => {
    if (err) {
      return context.fail(err)
    } else {
      return context.succeed(res)
    }
  })
}

Redis-konfiguration

module.exports = () => {
  const redis = require('redis')
  const jsonify = require('redis-jsonify')
  const redisOptions = {
    host: process.env.REDIS_URL,
    port: process.env.REDIS_PORT,
    password: process.env.REDIS_PASS
  }

  return jsonify(redis.createClient(redisOptions))
}

Funktionen

'use strict'

const rt = require('./ritetag')

module.exports.respond = function (event, callback) {
  const redis = require('./redis')()

  const tag = event.hashtag.replace(/^#/, '')
  const key = 'related:' + tag
  let error, response

  redis.on('end', () => {
    callback(error, response)
  })

  redis.on('ready', function () {
    redis.get(key, (err, res) => {
      if (err) {
        redis.quit(() => {
          error = err
        })
      } else {
        if (res) {
          // Tag is found in Redis, so send results directly.
          redis.quit(() => {
            response = res
          })
        } else {
          // Tag is not yet in Redis, so query Ritetag.
          rt.hashtagDirectory(tag, (err, res) => {
            if (err) {
              redis.quit(() => {
                error = err
              })
            } else {
              redis.set(key, res, (err) => {
                if (err) {
                  redis.quit(() => {
                    error = err
                  })
                } else {
                  redis.quit(() => {
                    response = res
                  })
                }
              })
            }
          })
        }
      }
    })
  })
}

Det här fungerar precis som det ska – och det går även fort.




  1. Redis auth-fel med Node.js och socket.io

  2. Har mongoDB problem med återanslutningen eller gör jag det fel?

  3. redis lua script kontra enstaka samtal

  4. MongoDB $substrBytes