共享内存容量规划
API7 Gateway 数据面节点使用多个 NGINX 共享内存区(lua_shared_dict)在 worker 之间共享状态。其中大多数表 现为缓存:写满后会淘汰最近最少使用的条目,节点继续正常工作。但有少数共享内存区存放的数据会随部署规模增长且不会被淘汰——一旦写满,后续写入会被静默丢弃。本文说明哪些内存区需要规划容量、它们能存放多少数据,以及如何按你的场景调整大小。
需要规划容量的共享内存
API7 Dashboard 会监控以下内存区,因为它们的内容无法自愈:写满时造成的是持续、难以排查的数据丢失,而非一次性的缓存未命中。
| 共享内存区 | 默认值 | 存放内容 | 写满时的表现 |
|---|---|---|---|
prometheus-metrics-advanced | 128 MB | 每条 Prometheus 时间序列(约 1 KB) | 指标停止更新,仪表盘和告警出现断点 |
kubernetes / nacos / consul | 各 64 MB | 每个已发现服务一个条目(其节点列表) | 新增或变更的上游节点无法解析 |
api-calls-for-portal | 64 MB | 每个开发者门户 API 调用维度一个计数器 | 门户统计数据偏低 |
tracing_buffer | 32 MB | 待上报的 SkyWalking 链路追踪片段 | 追踪 span 被丢弃 |
其余所有共享内存区(限流计数器、EWMA 负载均衡状态、各类缓存等)都能自行淘汰或重置,无需调整。
上述默认值旨在覆盖绝大多数部署场景。仅当你的规模超出下文所述容量,或希望在小规模部署上回收内存时,才需要调整。显式设置的值始终优先于默认值。
容量参考
下列数据来自在 API7 Gateway 运行时上实测每兆字节可容纳的条目数。共享内存按固定的 slab 等级分配,因此每个条目的开销会向上取整到最接近的 2 的幂边界。跨越边界(更长的 key 或更大的 value)会使单条目开销大致翻倍,这也是下表数值成倍变化的原因。
Prometheus 指标
每条时间序列(唯一的「指标 + 标签」组合)约占 1 KB:库会把标签集存两份——一份是指标样本,一份是内部的 key 索引——而 NGINX 会把这两个条目各自向上取整到约 512 字节的 slab。
| 内存区大小 | 约可容纳的时间序列数 |
|---|---|
| 64 MB | 65,000 |
| 128 MB(默认) | 130,000 |
| 256 MB | 260,000 |
时间序列数量随启用 prometheus 插件的路由和服务数量增长,并乘以标签基数与直方图分桶数。直方图指标是主要来源:请求延迟直方图单个标签组合就约有 15 个分桶,而带宽等 counter 指标每个只贡献少量序列。高基数标签(例如按上游节点区分的标签)会使数量迅速膨胀;如需限制,可使用 prometheus 插件的 disabled_labels 元数据丢弃指定标签。标签很短时每 MB 可多容纳两到三倍序列;此外内存区写满时 /metrics 响应也会随之变大——大致每 MB 内存区对应约 0.2 MB 文本(写满的 128 MB 内存区约 25 MB),因此高基数场景下精简标签比单纯扩大内存区更有效。
服务发现
每个已发现的服务以其后端节点列表的 JSON 形式存储,因此单个服务的开销随该服务的节点数增长。
| 每服务节点数 | 每 64 MB(默认)可容纳的服务数 |
|---|---|
| 1 | 170,000 |
| 5 | 100,000 |
| 20 | 31,000 |
| 100 | 8,000 |
请按注册中心内的服务数量规划 kubernetes、nacos 或 consul 内存区大小,并为节点列表最大的服务预留余量。上表是 kubernetes 的数据,它会为每个服务额外存一个小的版本标记;nacos 和 consul 每个服务只存一个条目,在低节点数时可多容纳约 1.5 倍。
开发者门户 API 调用
每个条目是一个计数器,key 由订阅、开发者、应用、凭证、API 产品和响应状态码组合而成,约 512 字节。
| 内存区大小 | 约可容纳的计数器组合数 |
|---|---|
| 64 MB(默认) | 130,000 |
| 128 MB | 260,000 |
活跃组合数随门户消费者数、应用数、产品数以及出现的不同响应码数量增长。计数器会周期性刷新,因此应按峰值并发基数规划,而非累计流量。
链路追踪缓冲区
该缓冲区存放排队等待上报的 SkyWalking 链路追踪片段,用于吸收采集器变慢或短暂不可达时的峰值;片段上报后即释放。
| 片段大小 | 每 32 MB(默认)可容纳的片段数 |
|---|---|
| 约 1 KB | 16,000 |
| 约 2 KB | 8,000 |
| 约 4 KB | 4,000 |
请按采集器变慢时需要缓冲的时长规划,而非按稳态吞吐量。如果采集器健康时仍出现片段丢弃,则应调大该值。
修改默认值
可以在数据面覆盖上述共享内存区。值使用 128m 或 1g 等大小字符串。对于 Helm 部署,请通过 helm upgrade 应用变更;对于直接管理的数据面,请编辑 config.yaml 并重启节点。共享内存区只在启动时分配,因此必须完整重启才能使新容量生效,reload 不会调整容量。
- 数据面配置
- Helm
在数据面 config.yaml 的 nginx_config 下设置共享内存区,该配置会覆盖 config-default.yaml:
nginx_config:
meta:
lua_shared_dict:
prometheus-metrics: 512m # 对应 prometheus-metrics-advanced 内存区
http:
lua_shared_dict:
tracing_buffer: 64m
api-calls-for-portal: 128m
custom_lua_shared_dict:
kubernetes: 128m
nacos: 128m
consul: 128m
在网关 Chart values 中设置共享内存区:
apisix:
meta:
luaSharedDict:
prometheus-metrics: 512m # 对应 prometheus-metrics-advanced 内存区
http:
luaSharedDict:
tracing_buffer: 64m
api-calls-for-portal: 128m
customLuaSharedDicts:
- name: kubernetes
size: 128m
- name: nacos
size: 128m
- name: consul
size: 128m
Prometheus 内存区在 meta 上下文中使用 prometheus-metrics 键配置,对应 Dashboard 中显示的 prometheus-metrics-advanced 内存区。
监控使用情况
API7 Dashboard 会按数据面节点报告每个受监控内存区的已用容量和总容量,并在接近上限时发出告警。请结合实际流量确认容量规划,并在内存区开始丢弃数据前发现持续增长趋势。