redis-server を複数回実行すると、同じポートに複数のリスニング ソケットがバインドされますか?

redis-server を複数回実行すると、同じポートに複数のリスニング ソケットがバインドされますか?

Windows Server 2019 の WSL で誤ってredis-server2 回目を実行しましたが、リスニング ソケットのバインドに失敗したことは報告されませんでした。出力は次のとおりです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

2つの質問:

  1. どうしてそんなことが可能なのでしょうか?
  2. を使用して接続するインスタンスを選択するにはどうすればよいですかredis-cli?

ありがとう。

編集

確認のために 3 回目に実行したところ、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_REUSEADDRSO_EXCLUSIVEADDRUSE

使用SO_REUSEADDR

ソケットSO_REUSEADDRオプションを使用すると、ソケットは別のソケットで使用されているポートに強制的にバインドできます。2 番目のソケットは、SO_REUSEADDR元のソケットと同じポートで bind を呼び出す前に、optname パラメータを に設定し、optval パラメータをブール値 TRUE に設定して setsockopt を呼び出します。

これは、サービスが複数の独立したプロセス間で負荷を分散できるようにするためのもので、サービスがこれを正しく処理できる場合にのみ使用する必要があります... Redis は、これをサポートしている (そしてデフォルトで有効になっている) サービスの 1 つである可能性があります。

見る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;
}

どのサーバーに接続したかを確認する必要がある場合は、Redisコマンドを使用できます。INFO serverprocess_idフィールドを探します。

あるいは、netstat -anoWindows ( netstat -tnpLinux の場合) で を使用して、特定のクライアント ポートのサーバー PID (クライアント PID ではない) を特定することもできます。

この関係を判断するための単純な OS レベルの方法は存在しないと思います。


複数のサーバーインスタンスがあり、それぞれが異なる設定やデータを使用している場合は、設定エラーが発生します。あなた修正する必要があります - つまり、一度に複数のサービスを実行したり、それぞれに異なるポートを使用したりしないでください。

これは Redis が担当するものではありません。リッスン ポートの選択が Redis が担当するものではないのと同じです。

関連情報