Skip to content

Memcached 内存指标

核心内存指标

内存使用量指标

bytes

  • 描述:当前已使用的内存字节数
  • 监控命令stats bytes
  • 正常范围:根据配置的最大内存(limit_maxbytes)而定,建议使用率低于 80%
  • 异常情况:接近或达到 limit_maxbytes 时,会触发 LRU 驱逐

limit_maxbytes

  • 描述:Memcached 实例配置的最大可用内存字节数
  • 监控命令stats limit_maxbytes
  • 配置方式:启动时通过 -m 参数设置(单位:MB)
    bash
    memcached -m 1024  # 配置 1GB 内存

bytes_free

  • 描述:当前空闲内存字节数
  • 计算公式bytes_free = limit_maxbytes - bytes
  • 监控命令:可通过计算或自定义脚本获取

对象数量指标

curr_items

  • 描述:当前存储的键值对数量
  • 监控命令stats curr_items
  • 分析价值:结合 bytes 指标可计算平均对象大小

total_items

  • 描述:从 Memcached 启动以来累计存储的键值对数量
  • 监控命令stats total_items
  • 分析价值:反映缓存的总体使用活跃度

内存管理指标

evictions

  • 描述:由于内存不足被 LRU 算法驱逐的键值对数量
  • 监控命令stats evictions
  • 正常范围:低频率驱逐是正常的,高频率驱逐(如每秒数百次)表明内存不足
  • 优化建议:增加内存容量或优化缓存策略

reclaimed

  • 描述:通过过期时间自动回收的键值对数量
  • 监控命令stats reclaimed
  • 分析价值:高 reclaimed 率表明缓存过期策略设置合理

malloc_fails

  • 描述:内存分配失败次数
  • 监控命令stats malloc_fails
  • 正常范围:应为 0
  • 异常处理:若大于 0,检查系统内存是否充足,或调整 Memcached 内存配置

Slab 相关指标

Slab 基础指标

Slab 分配情况

bash
# 使用 memcached-tool 查看 slab 详情
$ memcached-tool localhost:11211 display
# 输出示例
#  #  Item_Size  Max_age   Pages   Count   Full?  Evicted Evict_Time OOM
#  1      96 B   18189 s       1    1000      no        0        0  0
#  2     120 B   18189 s       1    1000      no        0        0  0
#  3     152 B   18189 s       1    1000      no        0        0  0

Slab 内存使用率

  • 描述:每个 Slab 类别使用的内存比例
  • 计算方法(已分配内存 / 总分配内存) × 100%
  • 监控命令stats items 结合 stats slabs

Slab 效率指标

碎片率

  • 计算公式1 - (实际存储数据大小 / Slab 已分配内存)
  • 正常范围:低于 20%
  • 优化建议:碎片率过高时可重启 Memcached 实例

利用率

  • 计算公式(当前对象数 / Slab 最大容量) × 100%
  • 正常范围:50%-80%
  • 优化建议:利用率过低可能需要调整 Slab 大小

内存指标监控方案

命令行监控

实时监控脚本

bash
#!/bin/bash
# 实时监控 Memcached 内存指标

host="localhost"
port="11211"

while true; do
    echo "====================================="
    echo "$(date '+%Y-%m-%d %H:%M:%S')"
    echo "====================================="
    
    # 获取核心指标
    stats=$(echo -e "stats\nquit" | nc $host $port)
    
    bytes=$(echo "$stats" | grep "STAT bytes " | awk '{print $3}')
    limit_maxbytes=$(echo "$stats" | grep "STAT limit_maxbytes " | awk '{print $3}')
    curr_items=$(echo "$stats" | grep "STAT curr_items " | awk '{print $3}')
    total_items=$(echo "$stats" | grep "STAT total_items " | awk '{print $3}')
    evictions=$(echo "$stats" | grep "STAT evictions " | awk '{print $3}')
    malloc_fails=$(echo "$stats" | grep "STAT malloc_fails " | awk '{print $3}')
    
    # 计算使用率
    usage_pct=$(echo "scale=2; $bytes / $limit_maxbytes * 100" | bc)
    bytes_free=$((limit_maxbytes - bytes))
    avg_item_size=$(echo "scale=2; $bytes / $curr_items" | bc 2>/dev/null || echo 0)
    
    # 输出结果
    echo "内存使用率: ${usage_pct}%"
    echo "已用内存: ${bytes} 字节 (${bytes%???} KB)"
    echo "空闲内存: ${bytes_free} 字节 (${bytes_free%???} KB)"
    echo "当前对象数: ${curr_items}"
    echo "累计对象数: ${total_items}"
    echo "平均对象大小: ${avg_item_size} 字节"
    echo "驱逐次数: ${evictions}"
    echo "内存分配失败: ${malloc_fails}"
    
    sleep 5
done

Prometheus 监控

memcached_exporter 配置

  • 安装

    bash
    wget https://github.com/prometheus/memcached_exporter/releases/download/v0.14.1/memcached_exporter-0.14.1.linux-amd64.tar.gz
    tar -xzf memcached_exporter-0.14.1.linux-amd64.tar.gz
    cd memcached_exporter-0.14.1.linux-amd64
    ./memcached_exporter --memcached.address=localhost:11211
  • Prometheus 配置 (prometheus.yml):

    yaml
    scrape_configs:
      - job_name: 'memcached'
        static_configs:
          - targets: ['localhost:9150']

常用 Prometheus 查询

txt
# 内存使用率
(memcached_bytes / memcached_limit_maxbytes) * 100

# 每秒驱逐率
rate(memcached_evictions_total[5m])

# 平均对象大小
memcached_bytes / memcached_curr_items

# 内存分配失败次数
memcached_malloc_fails_total

Grafana 仪表盘

推荐模板

  • ID: 2553(Memcached 监控模板)
  • 包含内存使用率、对象数量、驱逐率等核心指标
  • 支持多实例监控和告警配置

关键面板设计

  1. 内存使用率趋势图:显示过去 24 小时的内存使用变化
  2. 对象数量与大小:展示 curr_items、total_items 和平均对象大小
  3. 驱逐与回收统计:evictions 和 reclaimed 指标对比
  4. Slab 使用率分布:不同 Slab 类别的内存使用情况

内存指标分析与优化

内存使用率过高

问题表现

  • 内存使用率持续高于 90%
  • 频繁的 evictions(每秒数十次以上)
  • 可能出现 malloc_fails

优化方案

  1. 增加内存容量

    bash
    memcached -m 2048  # 将内存从 1GB 增加到 2GB
  2. 优化缓存策略

    • 缩短过期时间(TTL)
    • 减少大型对象的缓存
    • 实施更严格的缓存淘汰策略
  3. 数据分片

    • 将单个实例拆分为多个实例
    • 使用一致性哈希实现分布式缓存

内存碎片率过高

问题表现

  • bytes_free 较大,但仍有频繁 evictions
  • slab 利用率不均衡
  • 整体内存使用率不高,但无法存储更多对象

优化方案

  1. 定期重启

    bash
    # 使用 systemd 重启
    systemctl restart memcached
  2. 调整 Slab 配置

    • 使用 -o slab_chunk_max=16384 调整最大 chunk 大小
    • 使用 -o slab_reassign=true 启用 slab 自动重分配
  3. 优化数据大小

    • 压缩大型对象
    • 拆分过大的键值对
    • 统一数据大小格式

驱逐率过高

问题表现

  • evictions 每秒数百次以上
  • 缓存命中率下降
  • 应用响应时间增加

优化方案

  1. 增加内存:直接解决内存不足问题

  2. 优化缓存键设计

    • 减少冗余键
    • 合理设置过期时间
    • 避免缓存不常用数据
  3. 实现缓存分层

    • 热点数据缓存在内存中
    • 冷数据存储在磁盘或数据库中
  4. 预加载热点数据

    python
    # 缓存预热示例
    def warm_cache():
        hot_keys = get_hot_keys()  # 获取热点键列表
        for key in hot_keys:
            data = get_data_from_db(key)
            mc.set(key, data, expire=3600)  # 缓存 1 小时

常见问题(FAQ)

Q1: 如何计算 Memcached 的内存使用率?

A1: 内存使用率计算公式:

内存使用率 = (bytes / limit_maxbytes) × 100%

其中:

  • bytes:当前已使用内存字节数
  • limit_maxbytes:配置的最大可用内存字节数

Q2: 为什么 Memcached 显示还有空闲内存,但仍在驱逐对象?

A2: 可能原因:

  • 内存碎片导致无法分配连续内存块
  • 特定 Slab 类别内存不足,而其他 Slab 有空闲
  • 对象大小超过了最大 Slab chunk 大小

Q3: 如何监控 Slab 级别的内存使用情况?

A3: 使用以下方法:

  1. memcached-tool 命令:memcached-tool localhost:11211 display
  2. stats slabs 命令:查看每个 Slab 类别的详细统计
  3. stats items 命令:查看每个 Slab 中的对象数量

Q4: 内存分配失败(malloc_fails)如何处理?

A4: 处理步骤:

  1. 检查系统内存是否充足
  2. 增加 Memcached 配置的内存容量
  3. 优化缓存策略,减少内存占用
  4. 考虑使用多实例分片

Q5: 如何设置合理的 Memcached 内存大小?

A5: 建议:

  • 根据业务需求和系统资源确定
  • 预留 20-30% 系统内存给操作系统和其他进程
  • 监控内存使用率,根据实际情况调整
  • 一般 Web 应用可配置为系统内存的 50-70%

Q6: 内存指标告警阈值如何设置?

A6: 参考值:

  • 内存使用率:警告 80%,严重 90%
  • 驱逐率:警告 100 次/分钟,严重 500 次/分钟
  • 内存分配失败:任何值都应告警
  • 当前对象数:根据历史峰值设置,超过峰值 80% 告警

Q7: 如何优化 Memcached 内存使用效率?

A7: 优化建议:

  1. 合理设置键的过期时间
  2. 压缩大型对象
  3. 优化数据序列化格式
  4. 拆分过大的键值对
  5. 定期清理无效键
  6. 启用 Slab 自动重分配
  7. 实施缓存分层策略