$binary_remote_addr 是刚需,因其将 IPv4/IPv6 地址分别固定压缩为 4/16 字节二进制值,无字符串冗余与动态开销,单 key 占用约 12–16 字节(含结构头),较 $remote_addr 节省超 50% 内存。

用 $binary_remote_addr 配合合理 zone 大小,能在极低内存(如 1–2MB)下稳定支撑数万级活跃 IP 的全局限流,关键不在“压到多小”,而在于“算得准、存得紧、不浪费”。
为什么 binary_remote_addr 是刚需
它把 IPv4 地址固定压缩成 4 字节、IPv6 固定为 16 字节,无字符串长度波动、无编码开销、无指针管理。相比 $remote_addr(平均占 32–40 字节/条),单 key 内存占用直接压到约 12–16 字节(含结构头),实测节省超 50%。这不是配置技巧,是 Nginx 底层存储机制决定的硬性优化。
1MB 究竟能扛多少 IP?别信“1 万”这种粗估
真实容量取决于协议类型和管理开销:
- 纯 IPv4 场景:每个 IP 状态约占 44 字节(12 字节 key + 32 字节计数器/时间戳/哈希指针)
- 扣除约 18% 哈希桶与对齐开销后,1MB 可存约 2 万个 IPv4 地址
- 若混有 IPv6,按 16 字节 key 计,单条略增,但日常公网流量中 IPv6 占比通常<5%,影响有限
怎么配出“刚好够用”的最小 zone
按并发活跃 IP 数反推,不是看日志总量:
- 从 access.log 抽最近 5 分钟:
awk '{print $1}' access.log | sort -u | wc -l,结果乘以 0.4 得高频活跃 IP 估算值 - 例如统计出 8000 个去重 IP → 活跃量约 3200 个 → 所需内存 ≈ 3200 × 44 ≈ 140KB → 直接配
zone=api:2m(留冗余防哈希冲突) - 上线后观察 error.log:若频繁出现
limiting requests, excess:且 IP 状态快速消失,说明 zone 不足;若 RSS 内存几乎不动,说明配大了
配置示例:2MB zone 支撑 3 万+ IPv4 客户端
http {
limit_req_zone $binary_remote_addr zone=global:2m rate=10r/s;
}
server {
location /api/ {
limit_req zone=global burst=30 nodelay;
}
}
该配置在典型 x86 服务器上仅额外占用约 2.3MB 共享内存(含管理开销),实测可长期稳定跟踪超 2.8 万个 IPv4 地址的请求状态,无踢旧、无溢出。

















