下面是一套 完整、可直接运行 的 PHP 连接 Memcached 示例,涵盖:
- 推荐客户端(
MemcachedvsMemcache) - 单机 / 集群连接
- 基本操作(增删改查、TTL、CAS)
- 连接池、持久连接
- Laravel / Symfony 集成
- 安全认证(SASL)
- 错误处理与监控
推荐客户端:Memcached 扩展(带 d)
| 客户端 | 说明 |
|---|---|
Memcached(推荐) | 支持 二进制协议、SASL 认证、持久连接、连接池 |
Memcache(不推荐) | 仅文本协议,已停止维护 |
官方文档:https://www.php.net/manual/en/book.memcached.php
1. 安装 Memcached 扩展
# Ubuntu/Debian
sudo apt-get install php-memcached
# CentOS/RHEL
sudo yum install php-pecl-memcached
# 或使用 pecl
pecl install memcached
重启 PHP-FPM / Apache
2. 基础连接(单机)
<?php
// 创建客户端实例
$mem = new Memcached();
// 添加服务器(支持多节点)
$mem->addServer('127.0.0.1', 11211);
// 可选:设置连接池大小(每个进程)
$mem->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE, true); // 一致性哈希
$mem->setOption(Memcached::OPT_TCP_NODELAY, true); // 提升性能
$mem->setOption(Memcached::OPT_CONNECT_TIMEOUT, 500); // 连接超时 500ms
$mem->setOption(Memcached::OPT_RETRY_TIMEOUT, 1); // 重试间隔
$mem->setOption(Memcached::OPT_SEND_TIMEOUT, 1000); // 发送超时
$mem->setOption(Memcached::OPT_RECV_TIMEOUT, 1000); // 接收超时
// 设置数据(key, value, TTL 秒)
$mem->set('name', '张三', 3600); // 1小时过期
$mem->set('age', 25, 0); // 永不过期
// 获取
$name = $mem->get('name');
$age = $mem->get('age');
echo "name: $name, age: $age\n";
// 自增
$counter = $mem->increment('counter', 1, 1); // 初始值1
echo "counter: $counter\n";
// 删除
$mem->delete('name');
3. 集群连接(多节点 + 权重)
$mem = new Memcached();
// 格式:host:port:weight
$servers = [
['node1.example.com', 11211, 33],
['node2.example.com', 11211, 33],
['node3.example.com', 11211, 34],
];
$mem->addServers($servers);
$mem->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE, true); // 一致性哈希
4. 持久连接(推荐生产)
$mem = new Memcached('persistent_pool'); // 持久连接池 ID
if (count($mem->getServerList()) == 0) {
$mem->addServer('127.0.0.1', 11211);
$mem->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE, true);
}
// 多个请求共享同一个连接
$mem->set('key1', 'value1');
$value = $mem->get('key1');
优势:避免每次请求都建立 TCP 连接,提升性能
5. CAS 操作(乐观锁)
$key = 'counter';
$gets = $mem->get($key, null, $casToken);
if ($gets !== false) {
$newValue = $gets + 1;
if ($mem->cas($casToken, $key, $newValue)) {
echo "CAS 成功: $newValue\n";
} else {
echo "CAS 失败,被他人修改\n";
}
} else {
// 首次设置
$mem->set($key, 1);
}
6. 批量操作
// 批量设置
$mem->setMulti([
'user:1' => '张三',
'user:2' => '李四',
'user:3' => '王五',
], 3600);
// 批量获取
$keys = ['user:1', 'user:2', 'user:3', 'user:999'];
$result = $mem->getMulti($keys);
print_r($result);
/*
Array
(
[user:1] => 张三
[user:2] => 李四
[user:3] => 王五
)
*/
7. 错误处理与状态码
$result = $mem->set('key', 'value');
if ($result === false) {
$code = $mem->getResultCode();
$msg = $mem->getResultMessage();
echo "错误码: $code, 消息: $msg\n";
// 常见错误码:
// Memcached::RES_NOTFOUND
// Memcached::RES_TIMEOUT
// Memcached::RES_CONNECTION_FAILURE
}
8. 序列化复杂对象(JSON)
$user = ['name' => '赵六', 'age' => 30, 'tags' => ['vip', 'premium']];
$mem->set('user:4', json_encode($user), 3600);
$json = $mem->get('user:4');
$user = json_decode($json, true);
print_r($user);
9. Laravel 集成(推荐)
1. 安装扩展
composer require php-memcached
2. config/cache.php
'memcached' => [
'driver' => 'memcached',
'persistent_id' => 'cache_pool',
'sasl' => [
'username', // 可选
'password', // 可选
],
'options' => [
Memcached::OPT_LIBKETAMA_COMPATIBLE => true,
Memcached::OPT_TCP_NODELAY => true,
],
'servers' => [
[
'host' => env('MEMCACHED_HOST', '127.0.0.1'),
'port' => env('MEMCACHED_PORT', 11211),
'weight' => 100,
],
],
],
3. .env
CACHE_DRIVER=memcached
MEMCACHED_HOST=192.168.1.10
MEMCACHED_PORT=11211
4. 使用
Cache::put('key', 'value', 600); // 10分钟
$value = Cache::get('key');
Cache::forever('perm', 'data');
Cache::forget('key');
10. Symfony 集成
# config/packages/cache.yaml
framework:
cache:
app: cache.adapter.memcached
pools:
cache.app:
adapter: cache.adapter.memcached
provider: 'memcached://127.0.0.1:11211'
$cache = $this->get('cache.app');
$cache->save('key', 'value', 3600);
$value = $cache->get('key');
11. SASL 认证连接(安全模式)
启动 Memcached(启用 SASL)
memcached -S -u memcached -p mysecretpassword
PHP 连接
$mem = new Memcached();
$mem->setSaslAuthData('memcached', 'mysecretpassword');
$mem->addServer('127.0.0.1', 11211);
12. 监控与健康检查
$stats = $mem->getStats();
foreach ($stats as $server => $data) {
echo "$server: ";
echo "uptime={$data['uptime']} ";
echo "curr_items={$data['curr_items']} ";
echo "bytes={$data['bytes']} ";
echo "get_hits={$data['get_hits']} ";
echo "evictions={$data['evictions']}\n";
}
13. 常见错误与排查
| 错误 | 原因 | 解决 |
|---|---|---|
Class 'Memcached' not found | 扩展未安装 | php -m | grep memcached |
Connection refused | 端口不通 | telnet 127.0.0.1 11211 |
RES_NOTSTORED | CAS 失败 | 重试或使用 set |
RES_TIMEOUT | 网络延迟 | 调大 OPT_SEND_TIMEOUT |
| 数据乱码 | 序列化不一致 | 统一使用 json_encode |
最佳实践总结
| 项目 | 建议 |
|---|---|
| 客户端 | 使用 Memcached(带 d) |
| 连接方式 | 持久连接 new Memcached('pool_id') |
| 哈希算法 | OPT_LIBKETAMA_COMPATIBLE = true |
| 序列化 | json_encode() + json_decode() |
| 错误处理 | 检查 getResultCode() |
| 框架集成 | Laravel CACHE_DRIVER=memcached |
| 监控 | 定期 getStats() + Prometheus |
一键运行完整示例(含 JSON + 持久连接)
<?php
$mem = new Memcached('my_app_pool');
if (count($mem->getServerList()) === 0) {
$mem->addServer('127.0.0.1', 11211);
$mem->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE, true);
$mem->setOption(Memcached::OPT_TCP_NODELAY, true);
}
// 复杂对象
$user = ['id' => 1, 'name' => '王五', 'roles' => ['admin']];
$mem->set('user:1', json_encode($user), 3600);
$json = $mem->get('user:1');
if ($json) {
$user = json_decode($json, true);
print_r($user);
} else {
echo "缓存未命中\n";
}
// 统计
$stats = $mem->getStats();
print_r($stats);
需要我帮你生成:
- Laravel 完整缓存服务类?
- Docker + PHP + Memcached 环境?
- 分布式锁实现?
- 健康检查接口
/health/memcached?
告诉我你的环境(PHP 版本、框架、是否集群、是否认证),我给你 一键部署代码!
Hello to all, how is the whole thing, I think every
one is getting more from this website, and your views are pleasant in support of new people.