Topik ini menjelaskan solusi untuk error Cannot assign requested address yang terjadi ketika klien mengakses instans Tair (Redis OSS-compatible) melalui koneksi singkat.
Penyebab
Error ini umumnya terjadi pada arsitektur yang menggunakan kombinasi PHP-FPM dan PhpRedis. Dalam skenario konkurensi tinggi, banyak koneksi TCP memasuki status TIME-WAIT, sehingga mencegah klien mendapatkan port baru dan menyebabkan error Cannot assign requested address.
Solusi
Gunakan pconnect alih-alih connect (direkomendasikan)
Menggunakan pconnect alih-alih connect mengurangi jumlah koneksi TCP dan mencegah pembuatan ulang koneksi untuk setiap permintaan, sehingga mengurangi latensi.
Contoh berikut menunjukkan penggunaan koneksi connect:
$redis->connect('[$Hostname]', [$Port]);
$redis->auth('[$Inst_Password]');Deskripsi parameter: [$Hostname], [$Port], dan [$Inst_Password] masing-masing menunjukkan Titik akhir, nomor port, dan kata sandi dari instance Tair (Redis OSS-compatible). Untuk informasi lebih lanjut, lihat Lihat titik akhir.
Kode berikut memberikan contoh cara menghubungkan ke instans menggunakan pconnect, yang membuat koneksi persisten alih-alih koneksi singkat.
$redis->pconnect('[$Hostname]', [$Port], 0, NULL, 0, 0, ['auth' => ['[$Inst_Password]']]);
// Jika versi phpredis adalah 5.3.0 atau lebih baru, kami menyarankan Anda menggunakan pconnect untuk mencegah error NOAUTH saat pemutusan koneksi.
// Sesuaikan nilai parameter timeout, persistent_id, retry_interval, dan read_timeout sesuai kebutuhan.Ubah parameter kernel tcp_max_tw_buckets dari instance ECS yang menyimpan klien
Untuk skenario di mana kode bisnis Anda memiliki banyak komponen dan sulit dimodifikasi, solusi ini dapat digunakan untuk mencapai Ketersediaan tinggi (HA) secara cepat.
Pada solusi ini, nilai tcp_max_tw_buckets diubah secara langsung. Namun, jika server masih dalam keadaan LAST-ACK saat mengirim ulang paket yang berisi 5-tupel, koneksi gagal dibuat. Oleh karena itu, kami sarankan menggunakan solusi pconnect.
Masuk ke instance Elastic Compute Service (ECS) tempat klien ditempatkan.
Jalankan perintah berikut untuk melihat nilai parameter ip_local_port_range dan tcp_max_tw_buckets.
sysctl net.ipv4.tcp_max_tw_buckets net.ipv4.ip_local_port_rangeBerikut adalah contoh tanggapan:
net.ipv4.tcp_max_tw_buckets = 262144 net.ipv4.ip_local_port_range = 32768 61000Jalankan perintah berikut untuk menyetel tcp_max_tw_buckets ke nilai yang lebih kecil dari nilai awal rentang port yang ditentukan oleh ip_local_port_range.
Dalam contoh ini, ipv4.ip_local_port_range disetel ke rentang port dari 32.768 hingga 61.000. Anda harus menyetel tcp_max_tw_buckets ke nilai yang lebih kecil dari 32.768. Contoh perintah:
sysctl -w net.ipv4.tcp_max_tw_buckets=10000
Peringatan
Parameter tcp_tw_recycle telah dihapus sejak Linux 4.12. Oleh karena itu, solusi yang memerlukan modifikasi nilai tcp_tw_reuse dan tcp_tw_recycle tidak lagi berlaku untuk layanan yang menggunakan NAT atau Linux Virtual Server (LVS). Kami sarankan Anda tidak menggunakan solusi semacam itu.