Команды Redis на AWS из ECS зависают навсегда

У меня есть контейнер ECS, управляемый экземпляром Fargate и ElastiCache Redis. И ECS, и Redis развернуты в частном VPC. Я хочу подключиться к Redis из контейнера ECS. Кажется, что все подсети и группы безопасности настроены правильно, после отправки команды auth появляется событие «готово», однако все остальные команды (например, информация) зависают навсегда. Вот код (Node.js с ioredis), который запускается в контейнере:

const client = new IoRedis(process.env.REDIS_URL, {
  connectTimeout: 5000,
  enableOfflineQueue: false,
  enableReadyCheck: false,
});

setInterval(() => {
  client
    .info()
    .then(info => {
      console.log('info received', info);
    })
    .catch(err => {
      console.error('error received', err);
    });
}, 5000);

Вывод журнала:

12:14:00
{"name":"app","hostname":"ip-10-0-103-126.us-east-2.compute.internal","pid":1,"appName":"api","level":30,"msg":"Server listening on 5000","time":"2019-04-03T12:14:00.176Z","v":0}

12:14:00
2019-04-03T12:14:00.181Z ioredis:redis status[master.ab-cache.hp48ph.use2.cache.amazonaws.com:6379]: [empty] -> connecting

12:14:00
2019-04-03T12:14:00.263Z ioredis:redis status[10.0.31.100:6379]: connecting -> connect

12:14:00
2019-04-03T12:14:00.264Z ioredis:redis write command[10.0.31.100:6379]: 0 -> auth([ '**************************************************' ])

12:14:00
2019-04-03T12:14:00.265Z ioredis:redis status[10.0.31.100:6379]: connect -> ready

12:14:05
2019-04-03T12:14:05.185Z ioredis:redis write command[10.0.31.100:6379]: 0 -> info([])

12:14:10
2019-04-03T12:14:10.184Z ioredis:redis write command[10.0.31.100:6379]: 0 -> info([])

12:14:15
2019-04-03T12:14:15.190Z ioredis:redis write command[10.0.31.100:6379]: 0 -> info([])

12:14:20
2019-04-03T12:14:20.194Z ioredis:redis write command[10.0.31.100:6379]: 0 -> info([])

12:14:25
2019-04-03T12:14:25.195Z ioredis:redis write command[10.0.31.100:6379]: 0 -> info([])

12:14:30
2019-04-03T12:14:30.197Z ioredis:redis write command[10.0.31.100:6379]: 0 -> info([])

12:14:35
2019-04-03T12:14:35.200Z ioredis:redis write command[10.0.31.100:6379]: 0 -> info([])

12:14:40
2019-04-03T12:14:40.200Z ioredis:redis write command[10.0.31.100:6379]: 0 -> info([])

12:14:45
2019-04-03T12:14:45.202Z ioredis:redis write command[10.0.31.100:6379]: 0 -> info([])

12:14:50
2019-04-03T12:14:50.202Z ioredis:redis write command[10.0.31.100:6379]: 0 -> info([])

12:14:55
2019-04-03T12:14:55.203Z ioredis:redis write command[10.0.31.100:6379]: 0 -> info([])

12:15:00
2019-04-03T12:15:00.204Z ioredis:redis write command[10.0.31.100:6379]: 0 -> info([])

12:15:05
2019-04-03T12:15:05.205Z ioredis:redis write command[10.0.31.100:6379]: 0 -> info([])

12:15:10
2019-04-03T12:15:10.204Z ioredis:redis write command[10.0.31.100:6379]: 0 -> info([])

12:15:15
2019-04-03T12:15:15.205Z ioredis:redis write command[10.0.31.100:6379]: 0 -> info([])

12:15:20
2019-04-03T12:15:20.206Z ioredis:redis write command[10.0.31.100:6379]: 0 -> info([])

12:15:25
2019-04-03T12:15:25.206Z ioredis:redis write command[10.0.31.100:6379]: 0 -> info([])

12:15:30
2019-04-03T12:15:30.208Z ioredis:redis write command[10.0.31.100:6379]: 0 -> info([])

12:15:35
2019-04-03T12:15:35.207Z ioredis:redis write command[10.0.31.100:6379]: 0 -> info([])

12:15:40
2019-04-03T12:15:40.207Z ioredis:redis write command[10.0.31.100:6379]: 0 -> info([])

12:15:45
2019-04-03T12:15:45.207Z ioredis:redis write command[10.0.31.100:6379]: 0 -> info([])

Строки выше взяты из отладочной информации IoRedis. Кажется, что он подключается и аутентифицируется правильно, но дальнейшие команды зависают навсегда, не возвращая ответа (ни успеха, ни ошибки). Что здесь может быть не так?


Также протестировал его с упакованным "redis" (вместо "ioredis"):

console.log('creating redis client'); // tslint:disable-line
    const redisClient = redis.createClient(redisConfig.url, {
      connect_timeout: 5000,
      enable_offline_queue: false,
      no_ready_check: true,
    });

    redisClient.on('error', err => {
      console.error('redis error', err); // tslint:disable-line
    });

    setInterval(() => {
      console.log('sending redis command'); // tslint:disable-line
      redisClient.info((err, result) => {
        console.log('redis response', { err, result }); // tslint:disable-line
      });
    }, 10000);

Та же проблема - обратный вызов команды никогда не вызывается:

введите здесь описание изображения


person user606521    schedule 03.04.2019    source источник
comment
Какова была интенсивность использования ЦП на ваших инстансах EC2, которые постоянно зависали в ожидании ответа ElastiCache? Какая у вас была ОС на ваших инстансах? Я считаю, что у них есть драйверы Ubuntu для ElastiCache, которые заставляют экземпляры зависать со 100% загрузкой ЦП, когда что-то не так с ElastiCache, вместо того, чтобы генерировать исключение тайм-аута.   -  person Yevgeniy Afanasyev    schedule 09.03.2021


Ответы (1)


Это было вызвано параметром ElastiCache "transit_encryption_enabled". Для подключения к Redis требуется туннель. После отключения этого параметра все работает как положено.

https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/in-transit-encryption.html

person user606521    schedule 04.04.2019