Cache tetangga di kernel Linux tidak sesederhana itu.
Ada perbedaan halus antara entri cache tetangga yang benar-benar keluar dari cache seluruhnya atau hanya ditandai sebagai basi/tidak valid. Di beberapa titik antara base_reachable_time /2 dan 3* base_reachable_time /2, entri akan tetap ada di cache, tetapi akan ditandai dengan status STALE. Anda seharusnya dapat melihat status dengan "ip -s neighbor show".
Ketika dalam keadaan STALE seperti di atas, jika saya melakukan ping 10.64.42.121, paket akan segera dikirim ke b8:20:00:00:00:00. Sedetik kemudian biasanya akan mengirim permintaan ARP untuk siapa yang memiliki 10.64.42.121 untuk memperbarui cache kembali ke keadaan DAPAT DIJANGKAU. NAMUN, untuk membuat masalah lebih membingungkan, kernel kadang-kadang akan mengubah nilai batas waktu berdasarkan umpan balik positif dari protokol tingkat yang lebih tinggi. Artinya, jika saya melakukan ping ke 10.64.42.121 dan dia membalas, maka kernel mungkin tidak akan repot mengirimkan permintaan ARP karena dianggap bahwa pong berarti bahwa entri cache ARP-nya valid. Jika entri dalam keadaan STALE, itu juga akan diperbarui oleh balasan ARP yang tidak diminta yang kebetulan dilihatnya.
Sekarang, untuk sebagian besar kasus, hanya entri yang berada dalam status STALE yang perlu Anda khawatirkan. Mengapa Anda memerlukan entri untuk dihapus seluruhnya dari cache? Kernel melakukan banyak upaya untuk tidak menghabiskan memori hanya dengan mengubah status entri cache alih-alih benar-benar menghapus dan menambahkannya ke cache setiap saat.
Jika Anda benar-benar bersikeras bahwa itu tidak hanya akan ditandai sebagai STALE, tetapi sebenarnya akan dihapus dari hashmap yang digunakan oleh cache tetangga, Anda harus berhati-hati terhadap beberapa hal. Pertama, jika entri belum digunakan dan basi selama gc_stale_time detik, itu harus memenuhi syarat untuk dihapus. Jika gc_stale_time lulus dan menandai entri sebagai oke untuk dihapus, itu akan dihapus ketika pengumpul sampah berjalan (biasanya setelah gc_interval detik).
Sekarang masalahnya adalah entri tetangga tidak akan dihapus jika sedang direferensikan . Hal utama yang akan membuat Anda bermasalah adalah referensi dari tabel perutean ipv4. Ada banyak hal pengumpulan sampah yang rumit, tetapi hal penting yang harus diperhatikan adalah bahwa pengumpul sampah untuk cache rute hanya kedaluwarsa entri setiap 5 menit (/proc/sys/net/ipv4/route/gc_timeout detik) pada banyak kernel. Ini berarti entri tetangga harus ditandai sebagai basi (mungkin 30 detik, bergantung pada base_reachable_time ), maka 5 menit harus berlalu sebelum cache rute berhenti mereferensikan entri (jika Anda beruntung), diikuti dengan beberapa kombinasi gc_stale_time dan gc_interval lewat sebelum benar-benar dibersihkan (jadi, secara keseluruhan, sekitar 5-10 menit akan berlalu).
Rangkuman:Anda dapat mencoba menurunkan /proc/sys/net/ipv4/route/gc_timeout ke nilai yang lebih pendek, tetapi ada banyak variabel dan sulit untuk mengontrol semuanya. Ada banyak upaya yang dilakukan untuk membuat semuanya bekerja dengan baik dengan tidak menghapus entri dalam cache terlalu dini (melainkan hanya menandainya sebagai STALE atau bahkan GAGAL).
gc_stale_time
adalah parameter yang tepat untuk men-tweak untuk mengusir entri STALE dari tabel ARP. Tapi masih ada lagi:
Pengumpulan sampah ARP dijalankan dalam neigh_periodic_work
berkala fungsi. Interval dapat disesuaikan melalui variabel /proc/sys gc_interval
.
Kemudian akan memeriksa bahwa setidaknya ada gc_thresh1
entri dalam tabel ARP. Ini akan menghindari konsumsi siklus CPU ekstra jika tabel terlalu kecil untuk melihat manfaat nyata dalam hal memori.
Dalam kasus Anda, saya menduga gc_thresh1
adalah variabel yang ingin Anda sesuaikan. menurunkannya akan memaksa GC untuk berjalan lebih sering. Ini mungkin berdampak negatif pada performa tergantung pada interval proses.
Catatan:gc_thresh3
adalah ambang keras. Tabel tidak akan pernah menyimpan entri lebih dari nilai ini. Tweak dengan hati-hati.