Skip to content

Memcached 监控指标

监控指标类型

Memcached 监控指标主要分为以下几类:内存使用、连接状态、命令执行、性能指标、错误统计和系统资源。这些指标可以帮助运维人员了解 Memcached 的运行状态,及时发现和解决问题。

监控指标是 Memcached 运维的重要组成部分,通过监控这些指标,我们可以:

  • 实时了解 Memcached 的运行状态
  • 提前发现潜在的性能瓶颈和故障
  • 优化 Memcached 配置和使用方式
  • 确保 Memcached 服务的高可用性和稳定性

核心监控指标

1. 内存使用指标

bytes(已使用内存)

  • 描述:当前 Memcached 实例已使用的内存字节数,包括所有存储的键值对和元数据
  • 监控命令stats bytes
  • 正常范围:根据配置的最大内存(limit_maxbytes)而定,建议使用率保持在 80% 以下
  • 异常情况:当内存使用率接近或达到 limit_maxbytes 时,Memcached 会开始使用 LRU(最近最少使用)算法驱逐旧数据
  • 监控重要性:内存使用是 Memcached 最核心的监控指标之一,直接影响缓存命中率和服务稳定性

limit_maxbytes(最大可用内存)

  • 描述:Memcached 实例配置的最大可用内存字节数,由启动参数 -m 控制
  • 监控命令stats limit_maxbytes
  • 配置方式:启动时通过 -m 参数设置(单位:MB),例如 memcached -m 1024 表示配置 1GB 内存
  • 监控重要性:了解实例的内存上限,帮助评估当前内存使用是否合理

bytes_free(空闲内存)

  • 描述:当前 Memcached 实例的空闲内存字节数
  • 计算公式bytes_free = limit_maxbytes - bytes
  • 监控命令:无直接命令,需要通过计算或自定义脚本获取
  • 监控重要性:直观反映实例的可用内存情况,帮助判断是否需要扩容

curr_items(当前键值对数量)

  • 描述:当前 Memcached 实例中存储的键值对数量
  • 监控命令stats curr_items
  • 分析价值:结合 bytes 指标可计算平均对象大小,帮助优化缓存对象设计
  • 监控重要性:了解当前缓存的实际数据量,评估缓存效率

total_items(累计键值对数量)

  • 描述:从 Memcached 实例启动以来,累计存储的键值对总数
  • 监控命令stats total_items
  • 分析价值:反映缓存的总体使用活跃度,帮助评估缓存的使用频率
  • 监控重要性:长期监控可了解业务增长趋势,预测未来内存需求

evictions(LRU 驱逐次数)

  • 描述:由于内存不足,被 LRU 算法驱逐的键值对数量
  • 监控命令stats evictions
  • 正常范围:低频率驱逐(如每分钟几次)是正常的,高频率驱逐(如每秒数百次)表明内存严重不足
  • 异常处理:当驱逐次数过高时,需要考虑增加内存容量、优化缓存策略或调整过期时间
  • 监控重要性:直接反映内存压力,是判断是否需要扩容的重要依据

2. 连接状态指标

curr_connections

  • 描述:当前活跃连接数
  • 监控命令stats curr_connections
  • 正常范围:低于配置的最大连接数(默认 1024)

total_connections

  • 描述:从 Memcached 启动以来累计连接数
  • 监控命令stats total_connections
  • 分析价值:反映服务的连接活跃度

connection_structures

  • 描述:当前分配的连接结构体数量
  • 监控命令stats connection_structures
  • 正常范围:与 curr_connections 接近

listen_disabled_num

  • 描述:由于连接数达到上限而无法接受新连接的次数
  • 监控命令stats listen_disabled_num
  • 正常范围:0,若大于 0 表明连接数不足

3. 命令执行指标

cmd_get

  • 描述:累计 GET 命令执行次数
  • 监控命令stats cmd_get

cmd_set

  • 描述:累计 SET 命令执行次数
  • 监控命令stats cmd_set

cmd_flush

  • 描述:累计 FLUSH_ALL 命令执行次数
  • 监控命令stats cmd_flush

cmd_touch

  • 描述:累计 TOUCH 命令执行次数
  • 监控命令stats cmd_touch

get_hits

  • 描述:GET 命令命中次数
  • 监控命令stats get_hits

get_misses

  • 描述:GET 命令未命中次数
  • 监控命令stats get_misses

delete_hits

  • 描述:DELETE 命令命中次数
  • 监控命令stats delete_hits

delete_misses

  • 描述:DELETE 命令未命中次数
  • 监控命令stats delete_misses

incr_hits

  • 描述:INCR 命令命中次数
  • 监控命令stats incr_hits

incr_misses

  • 描述:INCR 命令未命中次数
  • 监控命令stats incr_misses

decr_hits

  • 描述:DECR 命令命中次数
  • 监控命令stats decr_hits

decr_misses

  • 描述:DECR 命令未命中次数
  • 监控命令stats decr_misses

cas_hits

  • 描述:CAS 命令命中次数
  • 监控命令stats cas_hits

cas_misses

  • 描述:CAS 命令未命中次数
  • 监控命令stats cas_misses

cas_badval

  • 描述:CAS 命令版本不匹配次数
  • 监控命令stats cas_badval

4. 性能指标

cache_hit_ratio

  • 描述:缓存命中率
  • 计算公式cache_hit_ratio = (get_hits / (get_hits + get_misses)) × 100%
  • 正常范围:根据业务场景而定,一般应高于 80%

bytes_read

  • 描述:从网络读取的字节数
  • 监控命令stats bytes_read

bytes_written

  • 描述:写入网络的字节数
  • 监控命令stats bytes_written

time

  • 描述:Memcached 服务器当前 Unix 时间戳
  • 监控命令stats time

uptime

  • 描述:Memcached 服务器运行时间(秒)
  • 监控命令stats uptime

rusage_user

  • 描述:用户态 CPU 使用时间(秒)
  • 监控命令stats rusage_user

rusage_system

  • 描述:系统态 CPU 使用时间(秒)
  • 监控命令stats rusage_system

5. 错误统计指标

error

  • 描述:错误统计(如 bad command, bad data chunk 等)
  • 监控命令stats errors

malloc_fails

  • 描述:内存分配失败次数
  • 监控命令stats malloc_fails
  • 正常范围:0,若大于 0 表明内存分配存在问题

conn_yields

  • 描述:连接让出次数
  • 监控命令stats conn_yields
  • 分析价值:高值可能表明连接竞争激烈

监控指标获取方法

1. 内置命令获取

stats 命令

bash
# 基本 stats 命令
telnet localhost 11211
stats

# 获取所有 stats 信息
stats
STAT pid 1234
STAT uptime 3600
STAT time 1620000000
STAT version 1.6.18
STAT libevent 2.1.12-stable
STAT pointer_size 64
STAT rusage_user 0.100000
STAT rusage_system 0.200000
STAT max_connections 1024
STAT curr_connections 10
STAT total_connections 100
STAT rejected_connections 0
STAT connection_structures 10
STAT reserved_fds 20
STAT cmd_get 1000
STAT cmd_set 500
STAT cmd_flush 0
STAT cmd_touch 0
STAT get_hits 800
STAT get_misses 200
STAT delete_misses 0
STAT delete_hits 0
STAT incr_misses 0
STAT incr_hits 0
STAT decr_misses 0
STAT decr_hits 0
STAT cas_misses 0
STAT cas_hits 0
STAT cas_badval 0
STAT touch_hits 0
STAT touch_misses 0
STAT auth_cmds 0
STAT auth_errors 0
STAT bytes_read 102400
STAT bytes_written 204800
STAT limit_maxbytes 1073741824
STAT accepting_conns 1
STAT listen_disabled_num 0
STAT threads 4
STAT conn_yields 0
STAT hash_power_level 16
STAT hash_bytes 524288
STAT hash_is_expanding 0
STAT slab_reassign_rescues 0
STAT slab_reassign_chunk_rescues 0
STAT slab_reassign_evictions_nomem 0
STAT slab_reassign_inline_reclaim 0
STAT slab_reassign_busy_items 0
STAT slab_reassign_busy_deletes 0
STAT slab_reassign_running 0
STAT slabs_moved 0
STAT lru_crawler_running 0
STAT lru_crawler_starts 1
STAT lru_maintainer_juggles 0
STAT malloc_fails 0
STAT log_worker_dropped 0
STAT log_worker_written 0
STAT log_watcher_skipped 0
STAT log_watcher_sent 0
STAT bytes 10485760
STAT curr_items 1000
STAT total_items 5000
STAT slab_global_page_pool 0
STAT expired_unfetched 0
STAT evicted_unfetched 0
STAT evicted_active 0
STAT evictions 0
STAT reclaimed 0
STAT crawler_reclaimed 0
STAT crawler_items_checked 0
STAT lrutail_reflocked 0
STAT moves_to_cold 0
STAT moves_to_warm 0
STAT moves_within_lru 0
STAT direct_reclaims 0
STAT lru_bumps_dropped 0
END

stats items 命令

bash
# 获取 items 相关统计
telnet localhost 11211
stats items
STAT items:1:number 1000
STAT items:1:age 3600
STAT items:1:evicted 0
STAT items:1:evicted_nonzero 0
STAT items:1:outofmemory 0
STAT items:1:tailrepairs 0
STAT items:1:reclaimed 0
STAT items:1:expired_unfetched 0
STAT items:1:evicted_unfetched 0
STAT items:1:evicted_active 0
STAT items:1:crawler_reclaimed 0
STAT items:1:lrutail_reflocked 0
STAT items:1:moves_to_cold 0
STAT items:1:moves_to_warm 0
STAT items:1:moves_within_lru 0
END

stats slabs 命令

bash
# 获取 slabs 相关统计
telnet localhost 11211
stats slabs
STAT 1:chunk_size 96
STAT 1:chunks_per_page 10922
STAT 1:total_pages 1
STAT 1:total_chunks 10922
STAT 1:used_chunks 1000
STAT 1:free_chunks 9922
STAT 1:free_chunks_end 0
STAT 1:mem_requested 92160
STAT 1:get_hits 800
STAT 1:cmd_set 1000
STAT 1:delete_hits 0
STAT 1:incr_hits 0
STAT 1:decr_hits 0
STAT 1:cas_hits 0
STAT 1:cas_badval 0
STAT 1:touch_hits 0
STAT active_slabs 1
STAT total_malloced 1048512
END

2. 脚本获取

Python 脚本示例

python
#!/usr/bin/env python3
import telnetlib

def get_memcached_stats(host, port):
    """获取 Memcached 统计信息"""
    tn = telnetlib.Telnet(host, port)
    tn.write(b"stats\r\n")
    tn.write(b"quit\r\n")
    response = tn.read_all().decode('utf-8')
    
    stats = {}
    for line in response.split('\n'):
        if line.startswith('STAT '):
            parts = line.split()
            stats[parts[1]] = parts[2]
    return stats

def calculate_hit_ratio(stats):
    """计算缓存命中率"""
    get_hits = int(stats.get('get_hits', 0))
    get_misses = int(stats.get('get_misses', 0))
    total_gets = get_hits + get_misses
    if total_gets > 0:
        return (get_hits / total_gets) * 100
    return 0

def main():
    host = 'localhost'
    port = 11211
    
    stats = get_memcached_stats(host, port)
    hit_ratio = calculate_hit_ratio(stats)
    
    print("Memcached 监控指标")
    print("=" * 50)
    print(f"缓存命中率: {hit_ratio:.2f}%")
    print(f"内存使用率: {(int(stats['bytes']) / int(stats['limit_maxbytes'])) * 100:.2f}%")
    print(f"当前连接数: {stats['curr_connections']}/{stats['max_connections']}")
    print(f"当前对象数: {stats['curr_items']}")
    print(f"驱逐次数: {stats['evictions']}")
    print(f"内存分配失败: {stats['malloc_fails']}")
    print(f"监听失败次数: {stats['listen_disabled_num']}")

if __name__ == "__main__":
    main()

Shell 脚本示例

bash
#!/bin/bash
# Memcached 监控脚本

host="localhost"
port="11211"

# 获取 stats 信息
stats=$(echo -e "stats\nquit" | nc $host $port)

# 提取关键指标
get_hits=$(echo "$stats" | grep "STAT get_hits " | awk '{print $3}')
get_misses=$(echo "$stats" | grep "STAT get_misses " | awk '{print $3}')
bytes=$(echo "$stats" | grep "STAT bytes " | awk '{print $3}')
limit_maxbytes=$(echo "$stats" | grep "STAT limit_maxbytes " | awk '{print $3}')
curr_connections=$(echo "$stats" | grep "STAT curr_connections " | awk '{print $3}')
max_connections=$(echo "$stats" | grep "STAT max_connections " | awk '{print $3}')
evictions=$(echo "$stats" | grep "STAT evictions " | awk '{print $3}')
malloc_fails=$(echo "$stats" | grep "STAT malloc_fails " | awk '{print $3}')

# 计算指标
total_gets=$((get_hits + get_misses))
if [ $total_gets -gt 0 ]; then
    hit_ratio=$(echo "scale=2; $get_hits / $total_gets * 100" | bc)
else
    hit_ratio=0
fi

mem_usage=$(echo "scale=2; $bytes / $limit_maxbytes * 100" | bc)

# 输出结果
echo "Memcached 监控指标"
echo "=================="
echo "缓存命中率: ${hit_ratio}%"
echo "内存使用率: ${mem_usage}%"
echo "当前连接数: ${curr_connections}/${max_connections}"
echo "驱逐次数: ${evictions}"
echo "内存分配失败: ${malloc_fails}"

监控指标可视化

1. Prometheus + Grafana

安装 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 配置

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

Grafana 仪表盘

  • 推荐模板:ID 2553(Memcached 监控模板)
  • 包含内存使用率、缓存命中率、连接数、驱逐率等核心指标
  • 支持多实例监控和告警配置

2. 其他监控工具

Zabbix 监控

  • 安装 Zabbix 代理
  • 配置 Memcached 监控模板
  • 设置告警阈值

Datadog

  • 安装 Datadog 代理
  • 配置 Memcached 集成
  • 监控关键指标和创建仪表盘

New Relic

  • 安装 New Relic 代理
  • 配置 Memcached 监控
  • 查看应用级性能和依赖关系

监控指标最佳实践

1. 关键指标监控

必须监控的指标

  • 内存使用率(bytes / limit_maxbytes)
  • 缓存命中率(get_hits / (get_hits + get_misses))
  • 连接数(curr_connections / max_connections)
  • 驱逐率(evictions / cmd_get)
  • 内存分配失败次数(malloc_fails)
  • 监听失败次数(listen_disabled_num)

2. 告警阈值设置

建议告警阈值

  • 内存使用率:警告 > 80%,严重 > 90%
  • 缓存命中率:警告 < 70%,严重 < 50%
  • 连接数:警告 > 80%,严重 > 90%
  • 驱逐率:警告 > 10%,严重 > 20%
  • 内存分配失败:任何值都应告警
  • 监听失败:任何值都应告警

3. 监控频率

建议监控频率

  • 生产环境:10-30 秒采集一次
  • 非生产环境:1-5 分钟采集一次
  • 历史数据保留:
    • 近期数据(7 天内):保留原始粒度
    • 中期数据(30 天内):降采样到分钟级
    • 长期数据(1 年以上):降采样到小时级

4. 监控数据分析

趋势分析

  • 分析内存使用趋势,预测未来需求
  • 识别周期性的流量峰值
  • 监控缓存命中率变化,优化缓存策略

异常检测

  • 设置基线,检测异常波动
  • 结合多个指标进行关联分析
  • 建立告警规则,及时发现问题

常见问题(FAQ)

Q1: 如何计算 Memcached 缓存命中率?

A1: 缓存命中率计算公式:

缓存命中率 = (get_hits / (get_hits + get_misses)) × 100%

Q2: 内存使用率高但驱逐率低是怎么回事?

A2: 可能原因:

  • 内存使用率虽然高,但仍有足够空间,未触发 LRU 驱逐
  • 缓存数据访问频率高,没有需要驱逐的冷数据
  • 内存分配存在碎片,导致实际可用空间不足

Q3: 连接数持续增长怎么办?

A3: 处理方法:

  • 检查应用程序是否存在连接泄漏
  • 调整连接池配置,优化连接管理
  • 增加 Memcached 最大连接数
  • 考虑使用连接复用技术

Q4: 如何监控多个 Memcached 实例?

A4: 监控方法:

  • 使用集中式监控系统(如 Prometheus + Grafana)
  • 为每个实例配置独立的监控目标
  • 创建聚合视图,查看所有实例的整体状态
  • 设置实例级别的告警规则

Q5: 监控指标数据应该保留多久?

A5: 建议:

  • 原始数据:保留 7-14 天
  • 分钟级数据:保留 30 天
  • 小时级数据:保留 1 年
  • 天级数据:保留 3-5 年

Q6: 如何优化 Memcached 监控性能?

A6: 优化建议:

  • 合理设置监控频率,避免过于频繁的采集
  • 只监控必要的指标,减少数据传输量
  • 使用高效的监控工具和协议
  • 考虑在监控代理端进行数据预处理

Q7: 告警规则应该如何设置?

A7: 设置建议:

  • 基于历史数据设置合理阈值
  • 使用多级告警(警告、严重)
  • 考虑告警持续时间,避免告警风暴
  • 结合多个指标设置复合告警规则
  • 定期review和调整告警规则