После долгих суждений я зашел в тупик. Я пытаюсь настроить Redis-кластер из 3-х главных узлов и 3-х подчиненных устройств на одном t2.micro. Моя установка на моем локальном хосте отлично работает, но когда я пытаюсь запустить ее на EC2, я сталкиваюсь со странной проблемой, когда мой клиент (на отдельном t2.micro с использованием ioredis) может найти и подключиться, но затем многократно выдает много ошибок, например «ioredis» : ошибка подключения: Ошибка: подключите ECONNREFUSED ", если мой клиент находится в http. Если я переключаюсь на https, я получаю дополнительные разные ошибки тайм-аута и ошибки «вручную закрытые» (безуспешно пытались установить флаг TLS в параметрах кластера).
TL;DR
Мысли?? Почему я не могу создать кластер с publicIP (а не 127.0.0.1) с помощью redis-trib? Казалось бы, это решит мои проблемы или есть что-то очевидное, чего мне здесь не хватает, например, брандмауэр? ...
Если вы читаете это и испытываете трудности с Redis, приведенный ниже список может послужить хорошим обзором почти всех предлагаемых решений Redis на верхних страницах Google и stackoverflow. Используйте их хорошо!
Прочитав несколько похожих тем, я обнаружил, что ни одна из них не решила проблему. Вот что я пробовал;
- Проверил мои группы безопасности EC2, чтобы убедиться, что между моим redis t2.micro и клиентом t2.micro открыты правильные порты. Убедился, что порты redis + 10,000 (для шины) тоже были открыты.
- Проверил мой AWS vpc, интернет-шлюз, подсети и ACL, чтобы убедиться, что трафик может течь между двумя экземплярами.
- Запустил какой-то netstat, и похоже, что я могу подключиться к правильным портам, и что redis прослушивает правильные порты
- В файле redis.conf для каждого узла убедитесь, что поля protected-mode (установлено значение no), bind (закомментировано) и password (закомментировано) не препятствуют обмену данными. Сначала это было частью проблемы. В какой-то момент я отключил их все и все равно имел те же ошибки.
- Я удалил все старые файлы aof, dump.rdb, node.conf и запустил новые экземпляры. Я позаботился о том, чтобы у каждого узла была своя собственная папка (без совместного использования файлов node.conf).
- Я попытался подключить кластер Redis с помощью loopback 127.0.0.1 вот так:
./redis-trib.rb create --replicas 1 127.0.0.1:30010 127.0.0.1:30011 127.0.0.1:30012 127.0.0.1:30013 127.0.0.1:30014 127.0.0.1:30015
и все еще были ошибки от клиента. Итак, затем попробовал публичный адрес хоста aws для redis t2.micro, затем общедоступный IP-адрес, а затем частный IP-адрес. Когда я запускаю узлы (используя ps -ef, чтобы убедиться, что они работают в режиме демона), а затем пытаюсь ./redis-trib create --replicas 1 publicIP: 30010 ..etc, используя общедоступный IP-адрес, похоже, что он создаст кластер но затем зависает на «>>> создании кластера» до тех пор, пока не откажет и не сообщит, что не может подключиться к первому узлу. Это не позволит мне создать кластер с общедоступным IP вместо 127.0.0.1 (что, как я подозреваю, является проблемой, из-за которой мой клиент не может подключиться). Кажется, что другие люди успешно подключили его, но не в этом случае (я также пытался запустить redis-trib от своего клиента, и он подключился и сгенерировал aof и node.conf на redis t2.micro, но он также зависает и в конце концов говорит, что не может найти узлы ...)
- Как только у меня будет запущен кластер под 127.0.0.1, узлы будут связываться, и redis-cli возвращает PONG в мой пинг, но для установки ключа он дает «(ошибка) MOVED 16164 127.0.0.1:30012» и то же самое для ' получать'. Поэтому я попытался вручную установить publicIP, отправив «встречу кластера», как в этом примере: redis-cli перенаправлен на 127.0.0.1
По-прежнему никуда. Пока я устанавливал встречу, некоторые из 127.0.0.1 оставались или те, которые я установил с помощью publicIP, казалось, переключились обратно к тому времени, когда я закончил прохождение всех узлов.
Остается только подумать, не блокирует ли AWS где-нибудь порты. Я попытался открыть все порты для обоих экземпляров t2.micro и открыть их для всех, но это все равно не сработало. Я думал о том, чтобы изучить iptables на экземплярах EC2, но их не следует устанавливать, учитывая, что есть группы безопасности (и я не особо возился с iptables). Я думал, что это займет у меня час, и теперь я все еще сижу здесь и почесываю голову.
Некоторый потенциально полезный код:
Код кластера:
export var cluster = new Redis.Cluster([{
port: 30010,
host: '52.36.xxx.xxx'
}, {
port: 30011,
host: '52.36.xxx.xxx'
},{
port: 30012,
host: '52.36.xxx.xxx'
}]);
30010 nodes.conf
337e0c0152cc88590d73048a6f97120934d94da8 127.0.0.1:30010 myself,master - 0 0 1 connected 0-5460
8f7cf7a0016c372ebaaffd76b903e26e47f2a513 127.0.0.1:30014 slave 882fed6d144b6dea1531691deb323a3ae0b52936 0 1471601371978 5 connected
2c36b871bbdb6f8b98a2562ff315bf79ca524ec5 127.0.0.1:30013 slave 337e0c0152cc88590d73048a6f97120934d94da8 1471601372982 1471601368969 4 connected
265b166b7231a7c0a8017f4f7fad90261d59fb96 127.0.0.1:30015 slave 42e5b9b8ab9e1d2eefe1832e118085b4e44ae65d 0 1471601367966 6 connected
882fed6d144b6dea1531691deb323a3ae0b52936 127.0.0.1:30011 master - 0 1471601369972 2 connected 5461-10922
42e5b9b8ab9e1d2eefe1832e118085b4e44ae65d 127.0.0.1:30012 master - 0 1471601370977 3 connected 10923-16383
vars currentEpoch 6 lastVoteEpoch 0
127.0.0.1:30010> cluster nodes
337e0c0152cc88590d73048a6f97120934d94da8 127.0.0.1:30010 myself,master - 0 0 1 connected 0-5460
8f7cf7a0016c372ebaaffd76b903e26e47f2a513 127.0.0.1:30014 slave 882fed6d144b6dea1531691deb323a3ae0b52936 0 1471601610630 5 connected
2c36b871bbdb6f8b98a2562ff315bf79ca524ec5 127.0.0.1:30013 slave 337e0c0152cc88590d73048a6f97120934d94da8 0 1471601611632 4 connected
265b166b7231a7c0a8017f4f7fad90261d59fb96 127.0.0.1:30015 slave 42e5b9b8ab9e1d2eefe1832e118085b4e44ae65d 0 1471601609627 6 connected
882fed6d144b6dea1531691deb323a3ae0b52936 127.0.0.1:30011 master - 0 1471601612634 2 connected 5461-10922
42e5b9b8ab9e1d2eefe1832e118085b4e44ae65d 127.0.0.1:30012 master - 0 1471601607622 3 connected 10923-16383
Ошибки клиента: sudo DEBUG = ioredis: * node app.js
ioredis:redis status[127.0.0.1:30010]: close -> end +1ms
ioredis:redis status[127.0.0.1:30012]: wait -> connecting +0ms
ioredis:connection error: Error: connect ECONNREFUSED 127.0.0.1:30012 +0ms
ioredis:redis status[127.0.0.1:30012]: connecting -> close +0ms
ioredis:connection skip reconnecting because `retryStrategy` is not a function +0ms
ioredis:redis status[127.0.0.1:30012]: close -> end +0ms
ioredis:cluster status: connect -> close +0ms
ioredis:cluster status: close -> reconnecting +0ms
ioredis:delayqueue send 1 commands in failover queue +94ms
REDIS222 CONNECT error Error: Failed to refresh slots cache.
node error Error: timeout
at Object.exports.timeout (/home/ubuntu/main2/node_modules/ioredis/lib/utils/index.js:153:36)
at Cluster.getInfoFromNode (/home/ubuntu/main2/node_modules/ioredis/lib/cluster/index.js:552:32)
at tryNode (/home/ubuntu/main2/node_modules/ioredis/lib/cluster/index.js:347:11)
at Cluster.refreshSlotsCache (/home/ubuntu/main2/node_modules/ioredis/lib/cluster/index.js:362:3)
SSH для redis t2.micro и netstat. Кажется, слушает правильные порты (30010-30015
ubuntu@ip-xxx-xx-xx-xxx:~$ sudo netstat -ntlp | grep LISTEN
tcp 0 0 0.0.0.0:40013 0.0.0.0:* LISTEN 1328/redis-server *
tcp 0 0 0.0.0.0:40014 0.0.0.0:* LISTEN 1334/redis-server *
tcp 0 0 0.0.0.0:40015 0.0.0.0:* LISTEN 1336/redis-server *
tcp 0 0 0.0.0.0:30010 0.0.0.0:* LISTEN 1318/redis-server *
tcp 0 0 0.0.0.0:30011 0.0.0.0:* LISTEN 1322/redis-server *
tcp 0 0 0.0.0.0:30012 0.0.0.0:* LISTEN 1324/redis-server *
tcp 0 0 0.0.0.0:30013 0.0.0.0:* LISTEN 1328/redis-server *
tcp 0 0 0.0.0.0:30014 0.0.0.0:* LISTEN 1334/redis-server *
tcp 0 0 0.0.0.0:30015 0.0.0.0:* LISTEN 1336/redis-server *
tcp 0 0 0.0.0.0:40010 0.0.0.0:* LISTEN 1318/redis-server *
tcp 0 0 0.0.0.0:40011 0.0.0.0:* LISTEN
1322/redis-server *
tcp 0 0 0.0.0.0:40012 0.0.0.0:* LISTEN
SSH в клиент t2.micro и удаленно вызывает узлы кластера с удаленного сервера Redis, и он возвращает правильную настройку обратной связи:
ubuntu@ip-xxx-xx-xx-x:~/redis-3.2.2/src$ ./redis-cli -h 52.36.237.185 -p 30010 cluster nodes
337e0c0152cc88590d73048a6f97120934d94da8 127.0.0.1:30010 myself,master - 0 0 1 connected 0-5460
8f7cf7a0016c372ebaaffd76b903e26e47f2a513 127.0.0.1:30014 slave 882fed6d144b6dea1531691deb323a3ae0b52936 0 1471629274223 5 connected
2c36b871bbdb6f8b98a2562ff315bf79ca524ec5 127.0.0.1:30013 slave 337e0c0152cc88590d73048a6f97120934d94da8 0 1471629275225 4 connected
265b166b7231a7c0a8017f4f7fad90261d59fb96 127.0.0.1:30015 slave 42e5b9b8ab9e1d2eefe1832e118085b4e44ae65d 0 1471629272217 6 connected
882fed6d144b6dea1531691deb323a3ae0b52936 127.0.0.1:30011 master - 0 1471629276228 2 connected 5461-10922
42e5b9b8ab9e1d2eefe1832e118085b4e44ae65d 127.0.0.1:30012 master - 0 1471629277231 3 connected 10923-16383
-------------------------------------------------------
Мысли?? Почему я не могу создать кластер с publicIP (а не 127.0.0.1) с помощью redis-trib? Казалось бы, это решит мои проблемы или есть что-то очевидное, чего мне здесь не хватает, например, брандмауэр ...
................................ ОБНОВИТЬ
Я проверил redis-trib.rb локально на сервере redis, и он показал, что все в порядке:
ubuntu@ip-172-xx-xx-xxx:~/redis-3.2.2/src$ ./redis-trib.rb check 127.0.0.1:30010
>>> Performing Cluster Check (using node 127.0.0.1:30010)
...
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
Но когда я запускаю его со своего клиента на другом экземпляре, используя redis publicIP, я получаю:
ubuntu@ip-172-xx-xx-x:~/redis-3.2.2/src$ ./redis-trib.rb check redispublicIP:30010
[ERR] Sorry, can't connect to node 127.0.0.1:30014
[ERR] Sorry, can't connect to node 127.0.0.1:30013
[ERR] Sorry, can't connect to node 127.0.0.1:30015
[ERR] Sorry, can't connect to node 127.0.0.1:30011
[ERR] Sorry, can't connect to node 127.0.0.1:30012
>>> Performing Cluster Check (using node redispublicIP:30010)
M: 337e0c0152cc88590d73048a6f97120934d94da8 redispublicIP:30010
slots:0-5460 (5461 slots) master
0 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[ERR] Not all 16384 slots are covered by nodes.
Так что, похоже, мне нужно переключить 127.0.0.1. Это позволяет мне подключаться к одному узлу от клиента, если я использую порт publicIP:, но когда он пытается найти другие узлы, он должен думать, что они локальные.
Update2: похоже, что это моя проблема, но я дважды проверил, и пароли не установлены ни в одном из 6 файлов redis.conf: Получение ошибки подключения при использовании redis-trib.rb для создания кластера?
Update3: эта статья очень близка, но я не понимаю его решения: src / redis-trib.rb create 127.0.0.1:6379 127.0.0.1:6380 h2: p1 h2: p2 h3: p1 h3: p2
В частности, почему он объявляет хост и порты после h2: p1 h2: p2 h3: p1 h3: p2
Обновление 4:
Похоже, что это может быть проблема с экземплярами AWS t2.micro. Я отправил запрос в службу поддержки AWS: https://forums.aws.amazon.com/thread.jspa?messageID=647509
РЕШЕНО: как в клиенте, так и в команде redis-trib create использовался частный IP-адрес. Я пробовал использовать частный IP в конфигурации клиента, но ошибочно подумал, что пробовал использовать с ним redis-trib.
Для всех остальных: Урок: используйте частный IP-адрес экземпляра redis EC2. Спасибо за это видео, которое помогло мне понять: https://www.youtube.com/watch?v=s4YpCA2Y_-Q