- 使用
pylibmc或pymemcache库直接连接并执行stats命令:这种方法最直接,可以获取 Memcached 服务器最核心的运行时统计信息,适合在应用程序内部进行轻量级监控或自定义监控脚本。 - 使用
statsd和Graphite等监控工具:这是生产环境中更推荐、更强大的方案,它将监控数据发送到中央监控系统,用于长期存储、可视化告警。
下面我将详细介绍这两种方法,并提供完整的代码示例。

使用 Python 库直接执行 stats 命令
Memcached 内置了一个 stats 命令,可以返回服务器的各种状态信息,我们可以用 Python 的 Memcached 客户端库来发送这个命令并解析结果。
推荐的库
pymemcache: 纯 Python 实现,安装简单,支持 Python 2 和 3。pylibmc: 基于libmemcachedC 库,性能更高,但需要先安装 C 库。
这里我们以 pymemcache 为例,因为它更易于上手。
安装 pymemcache
pip install pymemcache
编写监控脚本
下面的脚本会连接到 Memcached 服务器,获取所有 stats 信息,并打印出一些关键指标。
# memcache_stats_monitor.py
from pymemcache.client.base import Client
import sys
def get_memcache_stats(host='127.0.0.1', port=11211):
"""
连接到 Memcached 并获取 stats 信息
"""
try:
# 创建客户端连接
client = Client((host, port))
# 执行 stats 命令
stats = client.stats()
client.close()
return stats
except Exception as e:
print(f"连接到 Memcached 失败: {e}")
return None
def print_key_stats(stats):
"""
打印关键的统计信息
"""
if not stats:
return
print("\n--- Memcached 关键指标 ---")
# 关键指标列表,方便查看
key_metrics = [
'pid', 'uptime', 'time', 'version',
'curr_connections', 'total_connections', 'connection_structures',
'cmd_get', 'cmd_set', 'get_hits', 'get_misses',
'evictions', 'limit_maxbytes', 'bytes_used', 'bytes'
]
for key in key_metrics:
if key in stats:
# 注意:stats 返回的值都是 bytes 类型,需要解码
print(f"{key.ljust(20)}: {stats[key].decode('utf-8')}")
# 计算命中率
if b'get_hits' in stats and b'get_misses' in stats:
hits = int(stats[b'get_hits'])
misses = int(stats[b'get_misses'])
total = hits + misses
if total > 0:
hit_rate = (hits / total) * 100
print(f"{'hit_rate'.ljust(20)}: {hit_rate:.2f}%")
print("------------------------\n")
if __name__ == '__main__':
# 可以从命令行参数获取 host 和 port
HOST = sys.argv[1] if len(sys.argv) > 1 else '127.0.0.1'
PORT = int(sys.argv[2]) if len(sys.argv) > 2 else 11211
print(f"正在监控 Memcached 服务器: {HOST}:{PORT}")
stats = get_memcache_stats(HOST, PORT)
if stats:
print_key_stats(stats)
else:
print("未能获取到 Memcached 统计信息。")
如何运行和解读
运行脚本:

假设你的 Memcached 在 0.0.1:11211 运行:
python memcache_stats_monitor.py
或者指定其他服务器:
python memcache_stats_monitor.py 192.168.1.100 11212
关键指标解读:
uptime: 服务器运行的总秒数。curr_connections: 当前打开的连接数。total_connections: 服务器启动以来总连接数。cmd_get: 总get命令请求数。cmd_set: 总set命令请求数。get_hits:get命命成功命中次数。get_misses:get命令未命中次数。hit_rate: (命中次数 / (命中 + 未命中)) * 100%。这是衡量缓存效率最重要的指标之一,通常希望它越高越好(> 95%)。evictions: 由于内存不足被踢出的数据项数量,如果这个值持续增长,说明你的缓存可能不够大,或者键的过期策略不合理。limit_maxbytes: 分配给 Memcached 的最大内存字节数。bytes_used: 已使用的内存字节数。bytes: 存储所有数据项占用的总字节数(包括键、值、额外开销)。
集成到监控生态系统 (Statsd + Graphite)
对于生产环境,我们通常需要将数据可视化(例如生成图表)并在异常时触发告警。StatsD 是一个简单的网络守护进程,用于聚合和汇总统计数据,然后将它们发送到后端服务(如 Graphite、InfluxDB、Datadog 等)。

工作流程
你的应用/监控脚本 -> StatsD -> Graphite/InfluxDB -> Grafana/Datadog (可视化与告警)
安装 StatsD 和后端 (以 Graphite 为例)
这通常是在服务器上独立部署的,步骤比较复杂,这里只列出概念:
- StatsD:
npm install statsd - Graphite: 通常包含 Carbon (接收数据) 和 Whisper (存储数据)。
- Grafana: 用于可视化 Graphite 中的数据。
修改 Python 脚本以发送数据到 StatsD
我们将使用 statsd Python 客户端库。
安装 statsd 库:
pip install statsd
修改后的监控脚本:
这个脚本不再打印到控制台,而是将指标发送到 StatsD 服务器。
# memcache_stats_to_statsd.py
from pymemcache.client.base import Client
from statsd import StatsClient
import time
import sys
# --- 配置 ---
MEMCACHE_HOST = '127.0.0.1'
MEMCACHE_PORT = 11211
STATSD_HOST = '127.0.0.1' # StatsD 服务器的地址
STATSD_PORT = 8125 # StatsD 默认端口
STATSD_PREFIX = 'memcache.prod.server1' # 指标前缀,用于区分不同服务
def monitor_and_send():
"""
获取 Memcached stats 并发送到 StatsD
"""
memcache_client = Client((MEMCACHE_HOST, MEMCACHE_PORT))
statsd_client = StatsClient(STATSD_HOST, STATSD_PORT, prefix=STATSD_PREFIX)
try:
stats = memcache_client.stats()
if not stats:
print("未能获取到 Memcached 统计信息。")
return
# 发送计数器
statsd_client.incr('stats.total_connections', int(stats[b'total_connections']))
statsd_client.incr('stats.cmd_get', int(stats[b'cmd_get']))
statsd_client.incr('stats.cmd_set', int(stats[b'cmd_set']))
statsd_client.incr('stats.get_hits', int(stats[b'get_hits']))
statsd_client.incr('stats.get_misses', int(stats[b'get_misses']))
statsd_client.incr('stats.evictions', int(stats[b'evictions']))
# 发送计量器 (Gauges) - 代表一个瞬时值
statsd_client.gauge('stats.curr_connections', int(stats[b'curr_connections']))
statsd_client.gauge('memory.bytes_used', int(stats[b'bytes_used']))
statsd_client.gauge('memory.limit_maxbytes', int(stats[b'limit_maxbytes']))
# 计算并发送命中率
hits = int(stats[b'get_hits'])
misses = int(stats[b'get_misses'])
total = hits + misses
if total > 0:
hit_rate = (hits / total) * 100
statsd_client.gauge('stats.hit_rate', hit_rate)
print(f"{time.ctime()} - 指标已成功发送到 StatsD")
except Exception as e:
print(f"发生错误: {e}")
finally:
memcache_client.close()
if __name__ == '__main__':
# 可以设置一个循环来定期采集数据
# 每 10 秒采集一次
interval = int(sys.argv[1]) if len(sys.argv) > 1 else 10
print(f"开始监控,每 {interval} 秒发送一次数据...")
while True:
monitor_and_send()
time.sleep(interval)
如何运行和查看
-
运行脚本:这个脚本会持续运行。
# 每10秒采集一次 python memcache_stats_to_statsd.py 10
-
在 Graphite/Grafana 中查看:
- Graphite 会接收到这些指标,并以
memcache.prod.server1.stats.cmd_get这样的路径存储。 - 在 Grafana 中,你可以添加一个 Graphite 数据源,然后创建仪表盘。
- 在仪表盘上,你可以添加图表,并输入类似
memcache.prod.server1.stats.hit_rate的查询来实时查看缓存命中率的变化趋势。 - 你还可以设置告警规则,例如当
memcache.prod.server1.stats.evictions在 5 分钟内持续大于 0 时,发送一个通知。
- Graphite 会接收到这些指标,并以
总结与选择
| 特性 | 方法一 (直接 stats) |
方法二 (集成 StatsD) |
|---|---|---|
| 复杂度 | 低,只需一个 Python 库 | 高,需要部署 StatsD 和后端服务 |
| 实时性 | 高,即时获取 | 取决于采集间隔,通常为秒级 |
| 数据存储 | 无,只在内存中 | 有,数据持久化存储,可查询历史 |
| 可视化 | 无,需手动解析打印 | 强,可轻松生成图表和仪表盘 |
| 告警 | 无,需自己实现逻辑 | 强,可与监控系统深度集成 |
| 适用场景 | 开发调试、快速检查、简单脚本 | 生产环境、长期监控、自动化运维 |
建议:
- 如果你只是想快速检查一下 Memcached 的状态,或者写一个简单的、一次性的脚本,使用方法一。
- 如果你的应用正在生产环境中运行,你需要持续关注其健康状况,强烈建议你搭建一套方法二的监控体系,这是目前业界标准的做法。
