PHP 连接 Memcached 服务

下面是一套 完整、可直接运行PHP 连接 Memcached 示例,涵盖:

  • 推荐客户端(Memcached vs Memcache
  • 单机 / 集群连接
  • 基本操作(增删改查、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_NOTSTOREDCAS 失败重试或使用 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 版本、框架、是否集群、是否认证),我给你 一键部署代码

文章已创建 2481

一个回复在 “PHP 连接 Memcached 服务

回复 website backlinks 取消回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部