Memcached 教程(中文版)
Memcached 是一个高性能的分布式内存对象缓存系统,常用于加速动态 Web 应用,减轻数据库负载。下面从 基础概念 → 安装 → 使用 → 高级特性 → 生产实践 一步步讲解。
1. 什么是 Memcached?
- 全称:Distributed Memory Object Caching System
- 作用:把热点数据放进内存,读写速度极快(微秒级)
- 特点:
- 纯内存存储(掉电丢失)
- Key-Value 存储(Key ≤ 250 B,Value ≤ 1 MB)
- 支持多语言客户端
- 无持久化、无复制、无认证(需配合防火墙)
2. 安装 Memcached
Linux(Ubuntu/Debian)
sudo apt update
sudo apt install memcached libmemcached-tools -y
Linux(CentOS/RHEL)
sudo yum install epel-release -y
sudo yum install memcached libmemcached -y
macOS(Homebrew)
brew install memcached libmemcached
启动服务
# 默认监听 11211 端口,内存 64MB
memcached -d -m 512 -p 11211 -u memcache -c 1024 -P /var/run/memcached.pid
# systemd 管理(Ubuntu 20.04+)
sudo systemctl start memcached
sudo systemctl enable memcached
3. 基本命令行操作(telnet)
telnet 127.0.0.1 11211
常用命令:
| 命令 | 说明 |
|---|---|
set key flags exp size | 存储(exp=过期秒数,0=永不过期) |
add key ... | 仅当 key 不存在时存储 |
replace key ... | 仅当 key 存在时替换 |
get key | 读取 |
delete key | 删除 |
flush_all | 清空所有缓存 |
stats | 查看统计信息 |
quit | 退出 |
示例:
set user:1 0 900 9
zhangsan
STORED
get user:1
VALUE user:1 0 9
zhangsan
END
4. 客户端使用(以 Python 为例)
安装 Python 客户端
pip install pymemcache # 推荐,纯 Python
# 或
pip install python-memcached
pymemcache 示例
from pymemcache.client.base import Client
# 连接(支持多节点)
client = Client(('127.0.0.1', 11211))
# 存储
client.set('user:1001', '李四', expire=3600) # 1小时过期
# 读取
result = client.get('user:1001')
print(result) # b'李四'
# 自增/自减
client.set('counter', 0)
client.incr('counter', 5) # +5
client.decr('counter', 2) # -2
print(client.get('counter')) # b'3'
python-memcached 示例
import memcache
mc = memcache.Client(['127.0.0.1:11211'])
mc.set('key1', 'hello', time=60)
print(mc.get('key1'))
5. 其他语言客户端
| 语言 | 客户端 |
|---|---|
| PHP | new Memcached() |
| Java | Spymemcached / XMemcached |
| Node.js | memjs / memcached |
| Go | github.com/bradfitz/gomemcache |
| Ruby | Dalli |
6. 高级特性
6.1 多节点集群(一致性哈希)
client = Client([
('10.0.0.1', 11211),
('10.0.0.2', 11211),
('10.0.0.3', 11211)
])
自动按 Key 哈希分配节点,节点增减不影响大部分缓存。
6.2 序列化复杂对象
import json
user = {'id': 1, 'name': '王五', 'roles': ['admin']}
client.set('user:1', json.dumps(user))
6.3 缓存穿透防护(布隆过滤器)
# 伪代码
if bloom_filter.might_contain(key):
value = cache.get(key)
if not value:
value = db.query(key)
cache.set(key, value)
else:
value = db.query(key)
cache.set(key, value)
6.4 热点 Key 保护(本地缓存 + 分布式锁)
# 防止缓存雪崩
if not local_cache.get(key):
lock = distributed_lock.acquire(key)
if lock:
try:
value = db.query()
cache.set(key, value, 300)
local_cache.set(key, value, 10)
finally:
lock.release()
7. 生产环境最佳实践
| 项目 | 建议 |
|---|---|
| 内存分配 | -m 设置为物理内存的 50~70% |
| 连接数 | -c 4096(根据并发调整) |
| 监听地址 | 不要监听 0.0.0.0,改内网 IP |
| 防火墙 | 只允许 Web 服务器访问 11211 |
| 监控 | stats + Prometheus Exporter |
| 过期策略 | 热点数据 5~30 分钟,非热点 1~24 小时 |
| 避免大 Value | >100KB 建议拆分或用 Redis |
| 禁用 UDP | 加上 -U 0 防止反射攻击 |
8. 常见问题(FAQ)
| 问题 | 解决方案 |
|---|---|
| 缓存丢失 | 重启 Memcached 会清空,属正常 |
| 内存不足 | 自动 LRU 淘汰旧数据 |
| 缓存雪崩 | 设置随机过期时间 expire = 3600 + random(300) |
| 缓存击穿 | 热点 Key 加锁或本地缓存 |
| 无法连接 | 检查防火墙、SELinux、-p 端口 |
9. 监控命令
echo "stats" | nc 127.0.0.1 11211
关键指标:
curr_items:当前条目数total_items:历史总条目get_hits/get_misses:命中率evictions:淘汰数(>0 说明内存紧张)bytes:已用内存
10. 简单 Web 缓存示例(Flask + Memcached)
from flask import Flask
from pymemcache.client.base import Client
app = Flask(__name__)
cache = Client(('127.0.0.1', 11211))
@app.route('/user/<uid>')
def get_user(uid):
key = f'user:{uid}'
user = cache.get(key)
if not user:
# 模拟数据库查询
user = {'id': uid, 'name': f'User {uid}'}
cache.set(key, user, 60)
return user
小结
| 步骤 | 内容 |
|---|---|
| 1 | 安装 memcached |
| 2 | 启动服务(-m 512 -p 11211) |
| 3 | 使用客户端 set/get |
| 4 | 多节点 + 序列化 + 防穿透 |
| 5 | 监控 + 防火墙 + 合理过期 |
官方文档:http://memcached.org
GitHub:https://github.com/memcached/memcached
练习建议:
- 搭建本地 Memcached
- 用 Python 写一个缓存用户信息的 API
- 模拟 1000 次请求,观察
stats变化
需要 Docker 部署、与 Redis 对比、图形化管理工具?继续问我!
Hello there! I know this is somewhat off topic but I was wondering
which blog platform are you using for this website? I’m getting
fed up of WordPress because I’ve had issues with hackers and I’m looking at options for another platform.
I would be great if you could point me in the direction of a
good platform.