redis-server, запущенный несколько раз, связывает несколько прослушивающих сокетов с одним и тем же портом?

redis-server, запущенный несколько раз, связывает несколько прослушивающих сокетов с одним и тем же портом?

На 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

Два вопроса:

  1. Как это вообще возможно?
  2. Как выбрать, к какому экземпляру подключиться с помощью 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.

Связанный контент