外观
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
ENDstats 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
ENDstats 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
END2. 脚本获取
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:11211Prometheus 配置
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和调整告警规则
