在 Laravel 应用中引入 Memcached 作为缓存后端,是应对高并发读请求、降低数据库负载的有效方式。Laravel 自带了对 Memcached 的完整支持,开发者无需自行封装客户端,只需正确安装服务端扩展并完成配置,即可在代码中通过统一接口操作缓存。Memcached 作为内存级键值存储,读写速度极快,尤其适合缓存数据库查询结果、页面片段、会话数据以及任意可序列化的临时数据。

一、环境准备与扩展安装
Laravel 的 Memcached 驱动依赖于 PHP 的 memcached 扩展,而不是已经废弃的 memcache 扩展。两者名称相似,但前者支持二进制协议、一致性哈希和连接池,并且拥有更完善的超时与错误处理机制,是官方推荐的选择。在 Ubuntu 等 Debian 系操作系统中,可以直接通过包管理器安装对应版本的扩展。
安装完成后,需要在 php.ini 中启用该扩展,并重启 PHP 服务使配置生效。可以通过命令行执行 php -m | grep memcached 确认扩展已加载。如果项目运行在 PHP-FPM 环境下,也必须确保 FPM 进程使用的 php.ini 包含该扩展,否则 Web 请求中会出现驱动不可用的异常。对于多版本 PHP 环境,还应确认扩展被安装到了当前项目实际使用的 PHP 版本中。
# 更新软件包索引 sudo apt-get update # 安装 PHP memcached 扩展 sudo apt-get install php-memcached # 重启 PHP-FPM 使扩展生效 sudo systemctl restart php8.2-fpm # 验证扩展是否成功加载 php -m | grep memcached
二、Laravel 缓存配置详解
Laravel 的缓存配置位于 config/cache.php 文件中。在该文件中,默认驱动由环境变量 CACHE_DRIVER 控制,将其改为 memcached 即可完成切换。更重要的是 memcached 节点数组的定义,它决定了客户端要连接的服务器列表,以及每个节点的连接参数。
每个节点可以设置 host、port、weight 等参数。其中 weight 用于加权分布,当某台机器的物理内存更大或性能更强时,可以分配更高的权重,从而让它承担更多的缓存键。Laravel 启动时会读取这些配置并实例化 Memcached 连接池。如果服务端未启动或端口配置错误,通常不会在启动阶段立即报错,而是在首次调用缓存时才会抛出异常,因此建议在上线前通过 artisan tinker 做一次连通性测试。
// config/cache.php 文件中的 memcached 存储配置片段
'stores' => [
'memcached' => [
'driver' => 'memcached',
'persistent_id' => 'laravel_cache',
'sasl' => [
env('MEMCACHED_USERNAME'),
env('MEMCACHED_PASSWORD'),
],
'options' => [
\Memcached::OPT_DISTRIBUTION => \Memcached::DISTRIBUTION_CONSISTENT,
\Memcached::OPT_LIBKETAMA_COMPATIBLE => true,
],
'servers' => [
[
'host' => env('MEMCACHED_HOST', '127.0.0.1'),
'port' => env('MEMCACHED_PORT', 11211),
'weight' => 100,
],
],
],
],
三、使用 Cache 门面操作缓存
Laravel 提供了 IlluminateSupportFacadesCache 门面,屏蔽了底层驱动的差异。无论使用文件、Redis 还是 Memcached,上层调用方式完全一致。常用方法包括 put、get、add、forever 与 remember,这些方法可以覆盖绝大多数缓存读写场景。
其中 remember 方法最为实用,它接受三个参数:键名、过期分钟数和一个闭包。当缓存缺失时,Laravel 会执行闭包并将返回结果写入 Memcached,这样就能避免在业务代码里反复判断键是否存在,代码更加简洁。使用时要特别注意 Memcached 单条记录的最大 value 通常为 1MB,超过该限制会导致写入失败,因此较大的对象应当进行序列化拆分,或者改用 Redis 作为后端。
use Illuminate\Support\Facades\Cache;
// 写入带过期时间的数据,30 分钟后自动失效
$userData = ['id' => 1, 'name' => 'Alice'];
Cache::put('user:1', $userData, 30);
// 读取缓存,如果不存在则返回 null
$value = Cache::get('user:1', null);
// 仅当键不存在时写入,避免覆盖已有缓存
Cache::add('config:site', ['theme' => 'default'], 60);
// 自动回源并缓存查询结果,10 分钟内不再重复查询数据库
$posts = Cache::remember('posts:latest', 10, function () {
return App\Models\Post::orderBy('id', 'desc')->limit(20)->get();
});
四、集群与多节点部署
当单台 Memcached 无法承载全部内存需求时,可以通过配置多个 server 节点实现横向扩展。Laravel 的 Memcached 驱动会将键通过一致性哈希算法分散到不同节点,应用层无需感知某个键具体存储在哪台服务器上。这种设计让缓存的读取路径保持简单,同时当某个节点宕机时,该节点上的键会失效并触发应用回源查询,不会拖垮整体可用性。
在多节点场景中,不建议使用 forever 永久缓存重要数据,因为 Memcached 节点一旦重启,内存数据会全部清空。更合理的做法是结合业务特性设置合理的 TTL,并利用监控工具观察缓存命中率的变化。通过对比不同后端,可以更清楚地判断 Memcached 适合哪些场景。
| 后端 | 优点 | 局限 |
|---|---|---|
| 文件缓存 | 零依赖,适合小型站点 | 磁盘 IO 慢,集群间不共享 |
| Memcached | 内存读写极快,支持多节点 | 无持久化,单条不能超过 1MB |
| Redis | 支持数据结构与持久化 | 内存占用略高,配置更复杂 |
五、常见误区与排查
一个典型误区是在开发环境使用数组或文件驱动,生产环境切换到 memcached 后未清理旧的序列化残留,导致旧代码读取到错误的数据格式。另一个常见问题是把会话驱动也设为 memcached 时,忘记修改 config/session.php 中的连接配置,造成用户登录状态丢失或会话无法共享。
排查连接问题时,可以临时在 artisan tinker 中执行写入并立即读取的操作。如果 put 之后 get 返回 null,通常说明服务端不可达、扩展未加载或配置的端口不正确。此外,SELinux 策略和防火墙规则也可能阻断 11211 端口的通信,需要同步放通相应规则,确保 Laravel 应用所在的服务器能够访问 Memcached 节点。
// 在 artisan tinker 中执行连通性测试
use Illuminate\Support\Facades\Cache;
Cache::store('memcached')->put('ping', 'pong', 1);
echo Cache::store('memcached')->get('ping');
综合来看,Memcached 在 Laravel 中的配置和使用并不复杂,关键在于环境准备、配置节点头、调用 Cache 门面以及上线前的连通性验证。对于读多写少、数据允许丢失或短期失效的场景,Memcached 能够显著降低数据库压力,提升请求响应速度。在实践过程中,建议结合缓存命名规范、合理 TTL 和命中率监控,持续优化缓存策略,让 Memcached 真正成为应用性能的稳定支撑。同时,也要注意 Memcached 与 Redis 在持久化、数据结构和内存管理上的差异,根据具体业务需求选择最合适的缓存后端,才能获得更理想的性能表现。
LaravelMemcachedcache_config修改时间:2026-08-06 06:09:26