Redisの「Cannot assign requested address」のエラーが出たので対応

ローカルのRedisに大量データを入れていたところ、以下のエラーが発生しました。

Could not connect to Redis at 127.0.0.1:6379: Cannot assign requested address

Socketの状態を見てみたら以下の通り。28232 TIME-WAIT が問題でした。

$ ss -tan | awk ‘{print $1}’ | sort | uniq -c            

     1 ESTAB
     9 LISTEN
     1 State
 28232 TIME-WAIT

Linuxはデフォルトでephemeralポートのレンジとして以下が割当たっています。だいたい28000くらいなので、ここに引っかかっています。

$ sysctl -a | grep ip_local_port_range
net.ipv4.ip_local_port_range = 32768    60999

対策①

ephemeralポートのレンジを増やす

例えば以下のように設定するとephemeralポートとして割り当て可能なポートが増えます。

$ sysctl -a | grep ip_local_port_range
net.ipv4.ip_local_port_range = 32768    60999

対策②

または、net.ipv4.tcp_tw_reuse を有効化します。これにより既にTIME-WAITになっている同一のIP・同一のPortのクライアントからのSYNが来た場合にTIME-WAITのソケットを再利用します。

同一クライアントから多くの接続を張る場合には効果大きいと思います。逆に大量のクライアントから接続を張る場合(今回のケースでは少ないかもしれませんが・・)net.ipv4.tcp_tw_reuse はあまり効果無いことになります。

$ sysctl -a | grep net.ipv4.tcp_tw_reuse
net.ipv4.tcp_tw_reuse = 1

設定するとある程度までは TIME-WAIT の数増えますが、そこで止まるようになるはずです。

$ ss -tan | awk ‘{print $1}’ | sort | uniq -c

     6 ESTAB
     9 LISTEN
     1 State
 14114 TIME-WAIT

ここまで書いてみて気付いたのですが、他に書いてられる方いらっしゃいましたね。

kakakikikekeのブログ: Could not connect to Redis at 127.0.0.1:6379: Cannot assign requested address