全部產品
Search
文件中心

ApsaraDB for Redis:Cannot assign requested address報錯

更新時間:Jun 19, 2024

本文介紹當用戶端通過短串連訪問Redis執行個體時,報錯Cannot assign requested address的解決方案。

問題原因

該報錯通常出現在用戶端使用PHP-FPM與PhpRedis組合的架構中,這種架構在高並發情境時,處於TIME-WAIT狀態下的TCP串連數較多,用戶端無法分配出新的連接埠,則會出現Cannot assign requested address報錯。

解決方案

使用Pconnect替換Connect(推薦)

用長串連替代短串連,該方案可減少TCP串連,同時可以避免每次請求都會重建立立串連的問題,減少延時。

例如Connect串連程式碼範例如下:

$redis->connect('[$Hostname]', [$Port]);
$redis->auth('[$Inst_Password]');

參數說明:[$Hostname]、[$Port]和[$Inst_Password]分別為Redis執行個體的串連地址、連接埠號碼和密碼,如何查看請參見查看串連地址

使用Pconnect替換Connect,即使用Persistent Connection的方式串連,樣本如下:

$redis->pconnect('[$Hostname]', [$Port], 0, NULL, 0, 0, ['auth' => ['[$Inst_Password]']]);
// 若PhpRedis版本大於等於5.3.0,建議使用Pconnect初始化方式,避免斷連時出現no auth。
// timeout、persistent_id、retry_interval和read_timeout等參數根據業務實現情況修改。

修改用戶端所在ECS執行個體的tcp_max_tw_buckets核心參數

對於一些特定情境,例如業務代碼牽涉過多組件不易變更等,您可以使用此方案,快速實現高可用。

此方案將直接修改tcp_max_tw_buckets參數,但如果服務端因為重傳對應五元組仍然處於LAST-ACK狀態時,建立串連會失敗。因此,更推薦您使用Pconnect串連方式的方案。

  1. 登入用戶端所在ECS執行個體。

  2. 執行以下命令,查看ip_local_port_range和tcp_max_tw_buckets參數。

    sysctl net.ipv4.tcp_max_tw_buckets net.ipv4.ip_local_port_range

    預計返回樣本如下。

    net.ipv4.tcp_max_tw_buckets = 262144
    net.ipv4.ip_local_port_range = 32768  61000
  3. 執行以下命令,修改tcp_max_tw_buckets參數,確保tcp_max_tw_buckets的值比ip_local_port_range範圍的起始值小。

    例如本樣本中,ipv4.ip_local_port_range的範圍是32768~61000,需修改tcp_max_tw_buckets的值小於32768,樣本如下:

    sysctl -w net.ipv4.tcp_max_tw_buckets=10000

注意事項

由於tcp_tw_recycle已在Linux 4.12上被棄用,請忽略所有修改tcp_tw_recycle和tcp_tw_reuse的方案,這些方案對於使用了NAT或LVS的服務均不適用。

適用於