Laravel 13 缓存新特性详解
摘要
Laravel 13 对缓存系统进行了增强,引入了 Cache::touch() 方法,允许延长缓存项的 TTL 而无需重新存储值。本文将深入讲解 Laravel 13 的缓存新特性,包括:
- Cache::touch() 核心概念与用法
- 缓存 TTL 延长场景
- 多驱动支持
- 原子操作与并发安全
- 缓存预热与失效策略
- 实战案例:会话续期与热点数据保活
本文适合希望优化缓存管理的 Laravel 开发者。
1. Cache::touch() 概述
1.1 传统方式的问题
在 Laravel 13 之前,延长缓存 TTL 需要先获取值,再重新存储:
1 2 3 4 5
| $value = Cache::get('key'); if ($value !== null) { Cache::put('key', $value, $newTtl); }
|
问题:
- 需要读取并重新写入值
- 对于大值,内存开销大
- 非原子操作,存在竞态条件
1.2 Cache::touch() 的优势
1 2
| Cache::touch('key', $additionalSeconds);
|
优势:
2. 基础用法
2.1 基本语法
1 2 3 4 5 6 7
| use Illuminate\Support\Facades\Cache;
Cache::touch('key', 60);
Cache::touch('key', now()->addHour());
|
2.2 返回值
1 2 3 4 5 6 7
| $success = Cache::touch('key', 60);
if ($success) { } else { }
|
2.3 链式调用
1
| Cache::store('redis')->touch('key', 60);
|
3. 应用场景
3.1 会话续期
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <?php
namespace App\Services;
use Illuminate\Support\Facades\Cache;
class SessionService { public function keepAlive(string $sessionId): bool { return Cache::touch("session:{$sessionId}", 3600); } public function extend(string $sessionId, int $minutes = 30): bool { return Cache::touch("session:{$sessionId}", $minutes * 60); } }
|
3.2 热点数据保活
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <?php
namespace App\Services;
use Illuminate\Support\Facades\Cache;
class HotDataService { public function keepHot(string $key): void { Cache::touch($key, 3600); } public function access(string $key): mixed { $value = Cache::get($key); if ($value !== null) { Cache::touch($key, 3600); } return $value; } }
|
3.3 限流器续期
1 2 3 4 5 6 7 8 9 10 11 12 13
| <?php
namespace App\Services;
use Illuminate\Support\Facades\Cache;
class RateLimiterService { public function extendWindow(string $key, int $seconds): bool { return Cache::touch("rate_limit:{$key}", $seconds); } }
|
3.4 锁续期
1 2 3 4 5 6 7 8 9 10 11 12 13
| <?php
namespace App\Services;
use Illuminate\Support\Facades\Cache;
class LockService { public function extendLock(string $lockKey, int $seconds): bool { return Cache::touch("lock:{$lockKey}", $seconds); } }
|
4. 多驱动支持
4.1 Redis
1
| Cache::store('redis')->touch('key', 60);
|
Redis 实现使用 EXPIRE 命令,性能最优。
4.2 Memcached
1
| Cache::store('memcached')->touch('key', 60);
|
Memcached 原生支持 touch 操作。
4.3 Database
1
| Cache::store('database')->touch('key', 60);
|
数据库驱动通过更新 expiration 字段实现。
4.4 File
1
| Cache::store('file')->touch('key', 60);
|
文件驱动通过更新文件修改时间实现。
5. 高级用法
5.1 批量 touch
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| use Illuminate\Support\Facades\Cache;
class CacheBatchService { public function touchMany(array $keys, int $seconds): array { $results = []; foreach ($keys as $key) { $results[$key] = Cache::touch($key, $seconds); } return $results; } }
|
5.2 条件 touch
1 2 3 4 5 6 7 8 9 10 11 12 13
| class ConditionalCacheService { public function touchIfPopular(string $key): bool { $hits = Cache::get("hits:{$key}", 0); if ($hits > 100) { return Cache::touch($key, 3600); } return false; } }
|
5.3 与事件结合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <?php
namespace App\Listeners;
use Illuminate\Support\Facades\Cache; use Illuminate\Cache\Events\CacheHit;
class ExtendHotCache { public function handle(CacheHit $event): void { if ($this->isHotKey($event->key)) { Cache::touch($event->key, 3600); } } private function isHotKey(string $key): bool { return str_starts_with($key, 'hot:'); } }
|
6. 实战案例
6.1 智能缓存管理器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| <?php
namespace App\Services;
use Illuminate\Support\Facades\Cache;
class SmartCacheManager { protected array $hotKeys = []; public function get(string $key, mixed $default = null): mixed { $value = Cache::get($key, $default); if ($value !== null) { $this->recordHit($key); $this->autoExtend($key); } return $value; } public function put(string $key, mixed $value, ?int $ttl = null): bool { return Cache::put($key, $value, $ttl ?? 3600); } protected function recordHit(string $key): void { $this->hotKeys[$key] = ($this->hotKeys[$key] ?? 0) + 1; } protected function autoExtend(string $key): void { if (($this->hotKeys[$key] ?? 0) > 10) { Cache::touch($key, 3600); } } }
|
6.2 API 响应缓存
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| <?php
namespace App\Services;
use Illuminate\Support\Facades\Cache;
class ApiResponseCache { public function getOrCache(string $endpoint, callable $callback, int $ttl = 3600): mixed { $key = "api:{$endpoint}"; return Cache::remember($key, $ttl, function () use ($callback, $key) { $response = $callback(); Cache::put("{$key}:created", now(), $ttl); return $response; }); } public function extend(string $endpoint, int $seconds): bool { $key = "api:{$endpoint}"; $main = Cache::touch($key, $seconds); $meta = Cache::touch("{$key}:created", $seconds); return $main && $meta; } }
|
6.3 用户活动追踪
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| <?php
namespace App\Services;
use Illuminate\Support\Facades\Cache;
class UserActivityService { public function recordActivity(int $userId): void { $key = "user:active:{$userId}"; if (Cache::has($key)) { Cache::touch($key, 300); } else { Cache::put($key, now(), 300); } } public function isOnline(int $userId): bool { return Cache::has("user:active:{$userId}"); } public function getOnlineUsers(): array { } }
|
7. 性能对比
7.1 基准测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| $start = microtime(true); for ($i = 0; $i < 10000; $i++) { $value = Cache::get('large_data'); Cache::put('large_data', $value, 3600); } $traditional = microtime(true) - $start;
$start = microtime(true); for ($i = 0; $i < 10000; $i++) { Cache::touch('large_data', 3600); } $touch = microtime(true) - $start;
echo "Traditional: {$traditional}s\n"; echo "Touch: {$touch}s\n";
|
8. 最佳实践
8.1 合理设置 TTL
1 2 3 4
| Cache::touch('user:session', 3600); Cache::touch('api:response', 300); Cache::touch('config:cache', 86400);
|
8.2 错误处理
1 2 3 4
| if (!Cache::touch('key', 60)) { Cache::remember('key', 3600, $callback); }
|
8.3 监控与日志
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| class MonitoredCacheService { public function touch(string $key, int $seconds): bool { $start = microtime(true); $result = Cache::touch($key, $seconds); $duration = (microtime(true) - $start) * 1000; if ($duration > 10) { Log::warning('Slow cache touch', [ 'key' => $key, 'duration_ms' => $duration, ]); } return $result; } }
|
9. 总结
Laravel 13 的 Cache::touch() 为缓存管理提供了更高效的方式:
- 性能优越:无需读取值,直接修改 TTL
- 原子操作:避免竞态条件
- 内存友好:不加载大值到内存
- 多驱动支持:Redis、Memcached、Database 等
通过本指南,您已经掌握了缓存新特性的核心用法,可以开始优化应用的缓存管理了。
参考资料