На Windows Server 2019, под WSL я по ошибке запустил redis-server
второй раз, и он не сообщил об ошибке привязки прослушивающего сокета. Вот вывод netstat
:
C:\Users\Administrator>netstat -ano | grep 6379 | grep LISTEN
TCP 0.0.0.0:6379 0.0.0.0:0 LISTENING 11080
TCP 127.0.0.1:6379 0.0.0.0:0 LISTENING 13292
TCP [::]:6379 [::]:0 LISTENING 11080
TCP [::1]:6379 [::]:0 LISTENING 13292
Два вопроса:
- Как это вообще возможно?
- Как выбрать, к какому экземпляру подключиться с помощью
redis-cli
?
Спасибо.
РЕДАКТИРОВАТЬ
Я запустил его в третий раз, просто чтобы проверить, и вот результат netstat
:
C:\Users\Administrator>netstat -ano | grep 6379 | grep LISTEN
TCP 0.0.0.0:6379 0.0.0.0:0 LISTENING 13916
TCP 0.0.0.0:6379 0.0.0.0:0 LISTENING 11080
TCP 127.0.0.1:6379 0.0.0.0:0 LISTENING 13292
TCP [::]:6379 [::]:0 LISTENING 11080
TCP [::]:6379 [::]:0 LISTENING 13916
TCP [::1]:6379 [::]:0 LISTENING 13292
решение1
Если розетка имеетSO_REUSEADDRЕсли флаг установлен, то несколько процессов смогут привязываться к данному порту.
"Использование SO_REUSEADDR
иSO_EXCLUSIVEADDRUSE
"
С использованием
SO_REUSEADDR
Опция
SO_REUSEADDR
сокета позволяет сокету принудительно привязываться к порту, используемому другим сокетом. Второй сокет вызывает setsockopt с параметром optname, установленным наSO_REUSEADDR
и параметром optval, установленным на логическое значение TRUE, перед вызовом bind на том же порту, что и исходный сокет.
Это позволяет службам распределять нагрузку между несколькими независимыми процессами и должно использоваться только в том случае, если служба способна правильно с этим справиться... Redis вполне может быть одной из служб, которые поддерживают это (и включают это по умолчанию).
Видетьnet.c
:
static int redisSetReuseAddr(redisContext *c) {
int on = 1;
if (setsockopt(c->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) {
__redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
redisNetClose(c);
return REDIS_ERR;
}
return REDIS_OK;
}
static int redisCreateSocket(redisContext *c, int type) {
redisFD s;
if ((s = socket(type, SOCK_STREAM, 0)) == REDIS_INVALID_FD) {
__redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
return REDIS_ERR;
}
c->fd = s;
if (type == AF_INET) {
if (redisSetReuseAddr(c) == REDIS_ERR) {
return REDIS_ERR;
}
}
return REDIS_OK;
}
Если вам необходимо определить, к какому серверу вы подключены, вы можете использовать команду RedisINFO server
, и ищите process_id
поле.
В качестве альтернативы вы можете использовать netstat -ano
в Windows ( netstat -tnp
в Linux) PID сервера для указанного клиентского порта (но не PID клиента).
Я не верю, что существует простой метод определения этой взаимосвязи на уровне ОС.
Если у вас есть несколько экземпляров сервера, использующих разные конфигурации и/или данные для каждого, то у вас есть ошибка конфигурации, котораятыследует исправить - то есть: не запускайте несколько служб одновременно или не используйте разные порты для каждой.
Это не входит в обязанности Redis, так же как и выбор порта прослушивания не входит в обязанности Redis.