linux中调整arp缓存需协同配置gc_thresh1/2/3控制容量,base_reachable_time_ms、gc_stale_time、gc_interval协同控制老化,且必须按接口分别设置并用ip neigh show验证状态。

Linux 系统中调整 ARP 缓存表大小与老化时间,不能只改单个参数,必须协同配置多个内核参数,并按具体网络接口分别设置。直接改 gc_stale_time 常常无效,因为条目从 REACHABLE → STALE → FAILED/DELETED 是一个依赖四个关键参数的状态流转过程。
一、调整 ARP 缓存表大小(控制条目数量上限)
ARP 表不是无限增长的,内核通过三个阈值参数控制缓存容量和垃圾回收触发条件:
- gc_thresh1:最小条目数阈值(默认 128)。只有当前缓存条目数 ≥ 该值,垃圾回收器(GC)才会启动;设为 0 可确保 GC 始终工作
- gc_thresh2:软上限(默认 512)。超过此值后,GC 会在 5 秒内启动
- gc_thresh3:硬上限(默认 1024)。一旦达到,GC 立即运行,强制清理
临时修改(以 eth0 为例):
echo 512 > /proc/sys/net/ipv4/neigh/eth0/gc_thresh1
echo 2048 > /proc/sys/net/ipv4/neigh/eth0/gc_thresh2
echo 8192 > /proc/sys/net/ipv4/neigh/eth0/gc_thresh3
永久生效需写入 /etc/sysctl.conf:
net.ipv4.neigh.eth0.gc_thresh1 = 512
net.ipv4.neigh.eth0.gc_thresh2 = 2048
net.ipv4.neigh.eth0.gc_thresh3 = 8192
二、调整 ARP 老化时间(控制条目生命周期)
老化不是单一倒计时,而是分阶段状态迁移。真正影响“总存活时长”的是以下四个参数协同作用:
- base_reachable_time_ms:新建或通信后条目保持 REACHABLE 的基础时长(毫秒),默认 30000(30 秒)。实际值在 ±50% 范围内随机浮动,防全网同步刷新
- gc_stale_time:条目变为 STALE 后保留多久才进入待回收队列(秒),默认 60。它不等于总老化时间
- gc_interval:垃圾回收器扫描缓存的周期(秒),默认 30。若设太大,过期条目要等下一次扫描才清理
- gc_thresh1:再次强调——必须 ≤ 当前条目数,GC 才会运行。设为 0 是最稳妥做法
例如,想让 ARP 条目平均在 45 秒左右被清理,可设:
echo 20000 > /proc/sys/net/ipv4/neigh/eth0/base_reachable_time_ms
echo 25 > /proc/sys/net/ipv4/neigh/eth0/gc_stale_time
echo 10 > /proc/sys/net/ipv4/neigh/eth0/gc_interval
echo 0 > /proc/sys/net/ipv4/neigh/eth0/gc_thresh1
注意:单位要区分清楚——base_reachable_time_ms 是毫秒,其余多为秒。
三、验证是否生效(别信 arp -a)
arp -a 只显示 IP-MAC 映射,**不反映状态**。判断真实老化行为,必须用:
ip neigh show
输出中每行末尾的 REACHABLE、STALE、FAILED 才是内核当前认定的状态。可配合定时观察:
watch -n 2 'ip neigh show | grep "192.168.1."'
看到某条目从 REACHABLE → STALE → 消失,且耗时接近你设定的组合值,说明配置已起效。
四、操作注意事项
- 参数按接口隔离:修改
/proc/sys/net/ipv4/neigh/eth0/才对 eth0 生效;改default只影响新创建的接口,已有接口不受影响 - 查接口名用:
ip link show | awk -F': ' '/: / && !/lo$/ {print $2}' | sed 's/://' - 永久配置后,务必执行:
sysctl -p加载 - 避免只调
gc_stale_time:常见问题“设了 30 秒,STALE 条目却卡十几分钟”就是因gc_thresh1过高或gc_interval太长导致 GC 未触发











