캐시

업데이트됨

번역일: 2026년 7월 22일

이 페이지는 원문이 업데이트되어 번역이 갱신되었습니다.

원문 수정
2026년 7월 22일
번역 갱신
2026년 7월 22일

캐시

소개

애플리케이션에서 데이터를 조회하거나 처리하는 작업 중에는 시간이 오래 걸리는 것들이 있습니다. 예를 들어 복잡한 DB 쿼리, 외부 API 호출, 대용량 데이터 집계 등이 대표적입니다. 이런 경우, 결과를 일정 시간 동안 캐시에 저장해 두면 같은 요청이 다시 들어왔을 때 훨씬 빠르게 응답할 수 있습니다.

Laravel은 다양한 캐시 백엔드를 위한 통합된 API를 제공합니다. 설정 파일만 바꾸면 Memcached, Redis, DynamoDB, 관계형 데이터베이스 등을 캐시 저장소로 손쉽게 전환할 수 있습니다. 로컬 개발 환경이라면 별도 설정 없이 파일이나 배열 기반 드라이버를 바로 쓸 수 있습니다.

설정

캐시 설정 파일은 config/cache.php에 있습니다. 이 파일에서 애플리케이션 전체에서 기본으로 사용할 캐시 드라이버를 지정할 수 있습니다. Laravel은 기본적으로 Memcached, Redis, DynamoDB, 그리고 관계형 데이터베이스를 포함한 다양한 캐시 백엔드를 지원합니다. 그 외에도 파일 기반 드라이버와, 테스트 용도로 유용한 arraynull 드라이버도 제공됩니다.

설정 파일에는 각 옵션에 대한 설명이 주석으로 달려 있으므로 꼭 한 번 읽어보시기 바랍니다. Laravel의 기본 캐시 드라이버는 database로, DB의 특정 테이블에 직렬화된 캐시 데이터를 저장합니다.

드라이버 사전 요구사항

Database

database 드라이버를 사용할 경우, 캐시 데이터를 저장할 테이블이 필요합니다. 보통 Laravel의 기본 마이그레이션에 이미 포함되어 있지만, 만약 테이블이 없다면 make:cache-table Artisan 명령으로 마이그레이션 파일을 생성할 수 있습니다.

php artisan make:cache-tablephp artisan migrate

Memcached

Memcached 드라이버를 사용하려면 Memcached PECL 패키지가 설치되어 있어야 합니다. 사용할 Memcached 서버 목록은 config/cache.php 설정 파일에서 지정합니다.

'memcached' => [ // ... 'servers' => [ [ 'host' => env('MEMCACHED_HOST', '127.0.0.1'), 'port' => env('MEMCACHED_PORT', 11211), 'weight' => 100, ], ], ],

필요하다면 host 옵션을 UNIX 소켓 경로로 지정할 수도 있습니다. 이 경우 port0으로 설정합니다.

'memcached' => [ // ... 'servers' => [ [ 'host' => '/var/run/memcached/memcached.sock', 'port' => 0, 'weight' => 100 ], ], ],

Redis

Redis 드라이버를 사용하려면 먼저 PECL을 통해 PhpRedis PHP 익스텐션을 설치하거나, Composer로 predis/predis 패키지(~2.0)를 설치해야 합니다. Laravel Sail에는 Redis가 기본으로 포함되어 있습니다. 또한 Laravel ForgeLaravel Cloud 같은 공식 Laravel 플랫폼도 PhpRedis 익스텐션이 기본 설치되어 있습니다.

Redis 설정에 대한 더 자세한 내용은 Laravel의 Redis 문서를 참고하세요.

DynamoDB

DynamoDB 드라이버를 사용하려면 캐시 데이터를 저장할 DynamoDB 테이블을 먼저 생성해야 합니다. 보통 테이블 이름은 cache로 짓지만, config/cache.php 설정 파일의 stores.dynamodb.table 값에 맞게 생성하면 됩니다. 테이블 이름은 DYNAMODB_CACHE_TABLE 환경 변수로도 지정할 수 있습니다.

이 테이블에는 문자열 타입의 파티션 키가 필요하며, 키 이름은 config/cache.php 설정 파일의 stores.dynamodb.attributes.key 값과 일치해야 합니다. 기본값은 key입니다.

다음으로, Laravel 애플리케이션이 DynamoDB와 통신할 수 있도록 AWS SDK를 설치합니다.

composer require aws/aws-sdk-php

또한 DynamoDB 캐시 스토어 설정 옵션에 값이 채워져 있는지 확인하세요. 보통 AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_DEFAULT_REGION 같은 옵션은 .env 파일에서 정의합니다.

'dynamodb' => [ 'driver' => 'dynamodb', 'key' => env('AWS_ACCESS_KEY_ID'), 'secret' => env('AWS_SECRET_ACCESS_KEY'), 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), 'table' => env('DYNAMODB_CACHE_TABLE', 'cache'), 'endpoint' => env('DYNAMODB_ENDPOINT'), ],

캐시 사용법

캐시 인스턴스 가져오기

캐시 스토어 인스턴스를 얻으려면 Cache 파사드를 사용하면 됩니다. 이 문서 전반에서 Cache 파사드를 기준으로 설명합니다. Cache 파사드는 Laravel 캐시 컨트랙트의 구현체에 간편하게 접근할 수 있도록 해줍니다.

<?php namespace App\Http\Controllers; use Illuminate\Support\Facades\Cache; class UserController extends Controller { public function index(): array { $value = Cache::get('key'); return [ // ... ]; } }

여러 캐시 스토어 접근하기

Cache 파사드의 store 메서드를 사용하면 특정 캐시 스토어에 접근할 수 있습니다. store에 전달하는 이름은 config/cache.phpstores 배열에 정의된 스토어 이름이어야 합니다.

$value = Cache::store('memcached')->get('foo'); Cache::store('redis')->put('bar', 'baz', 600); // 10분

캐시에서 항목 조회하기

Cache 파사드의 get 메서드는 캐시에서 항목을 조회할 때 사용합니다. 해당 키가 캐시에 없으면 null을 반환합니다. 두 번째 인수로 기본값을 지정하면, 항목이 없을 때 해당 값이 반환됩니다.

$value = Cache::get('key'); $value = Cache::get('key', 'default');

기본값으로 클로저를 전달할 수도 있습니다. 캐시에 해당 항목이 없을 때 클로저가 실행되고 그 반환값이 사용됩니다. 클로저를 활용하면 데이터베이스나 외부 서비스에서 값을 지연 조회하도록 처리할 수 있습니다.

$value = Cache::get('key', function () { return DB::table(/* ... */)->get(); });

항목 존재 여부 확인

has 메서드를 사용하면 캐시에 해당 항목이 존재하는지 확인할 수 있습니다. 항목이 존재하지만 값이 null인 경우에도 false를 반환합니다.

if (Cache::has('key')) { // ... }

숫자 값 증가 / 감소

incrementdecrement 메서드를 사용하면 캐시에 저장된 정수 값을 증감할 수 있습니다. 두 메서드 모두 두 번째 인수로 증감할 양을 지정할 수 있습니다.

// 값이 없으면 0으로 초기화된 후 증가합니다 Cache::increment('key'); Cache::increment('key', $amount); Cache::decrement('key'); Cache::decrement('key', $amount);

조회 후 없으면 저장하기

캐시에서 값을 가져오되, 없으면 기본값을 저장하고 반환하는 패턴이 자주 사용됩니다. Cache::remember 메서드가 이 역할을 합니다. 캐시에 항목이 없으면 전달한 클로저를 실행해 그 결과를 캐시에 저장합니다.

$value = Cache::remember('users', $seconds, function () { return DB::table('users')->get(); });

캐시에 영구적으로 저장하려면 rememberForever 메서드를 사용하세요.

$value = Cache::rememberForever('users', function () { return DB::table('users')->get(); });

조회 후 삭제하기

캐시에서 항목을 가져온 다음 바로 삭제해야 할 때는 pull 메서드를 사용합니다. get과 마찬가지로, 항목이 없으면 null을 반환합니다.

$value = Cache::pull('key'); $value = Cache::pull('key', 'default');

캐시에 항목 저장하기

Cache 파사드의 put 메서드로 항목을 캐시에 저장할 수 있습니다.

Cache::put('key', 'value', $seconds = 10);

유효 시간을 지정하지 않으면 항목이 만료되지 않고 영구적으로 저장됩니다.

Cache::put('key', 'value');

정수(초) 대신 DateTime 인스턴스를 전달해 만료 시각을 지정할 수도 있습니다.

Cache::put('key', 'value', now()->addMinutes(10));

없을 때만 저장하기

add 메서드는 캐시에 해당 키가 없을 때만 저장하며, 실제로 저장됐으면 true, 이미 존재하면 false를 반환합니다. 이 메서드는 원자적으로 동작합니다.

Cache::add('key', 'value', $seconds);

영구 저장하기

forever 메서드를 사용하면 만료 없이 캐시에 영구적으로 저장할 수 있습니다. 영구 저장된 항목은 forget 메서드로 직접 삭제해야 합니다.

Cache::forever('key', 'value');

NOTE

Memcached를 사용할 경우, "영구" 저장된 항목도 캐시 용량이 가득 차면 자동으로 제거될 수 있습니다.

항목 유효기간 연장하기

touch 메서드를 사용하면 캐시 항목의 만료 시간을 연장할 수 있습니다. 기본 TTL이 설정된 경우 현재 시간을 기준으로 다시 산정됩니다. 항목이 존재하면 true를, 없으면 false를 반환합니다.

Cache::touch('key'); Cache::touch('key', $seconds);

NOTE

touch는 현재 database, file, redis, memcached, array 드라이버에서 지원됩니다.

캐시에서 항목 삭제하기

forget 메서드로 캐시에서 특정 항목을 삭제할 수 있습니다.

Cache::forget('key');

만료 시간을 0 또는 음수로 지정해도 항목이 삭제됩니다.

Cache::put('key', 'value', 0); Cache::put('key', 'value', -5);

flush 메서드를 사용하면 캐시 전체를 비울 수 있습니다.

Cache::flush();

WARNING

flush는 캐시 접두사(prefix)를 고려하지 않고 저장소 전체를 삭제합니다. 여러 애플리케이션이 캐시를 공유하는 경우, 다른 애플리케이션의 캐시까지 삭제될 수 있으니 주의하세요.

캐시 메모이제이션

같은 요청 처리 중에 동일한 캐시 키를 여러 번 조회해야 할 때, 매번 캐시 스토어에 접근하는 것은 비효율적입니다. Cache::memo 메서드는 요청 범위 내에서 결과를 인메모리에 저장해두고, 같은 키로 다시 조회할 때 캐시 스토어를 거치지 않고 바로 반환합니다.

$user = Cache::memo(function () { return Cache::get('user'); }); // 이후 같은 클로저를 다시 호출해도 캐시 스토어에는 접근하지 않음 $user = Cache::memo(function () { return Cache::get('user'); });

Cache 헬퍼

Cache 파사드 외에도, 전역 cache 헬퍼 함수로 캐시를 조회하거나 저장할 수 있습니다. 문자열 하나만 전달하면 해당 키의 값을 반환합니다.

$value = cache('key');

키-값 쌍의 배열과 유효 시간을 함께 전달하면 캐시에 저장합니다.

cache(['key' => 'value'], $seconds); cache(['key' => 'value'], now()->addMinutes(10));

인수 없이 호출하면 Illuminate\Cache\CacheManager 인스턴스를 반환하므로, 파사드처럼 메서드를 체이닝할 수 있습니다.

cache()->remember('users', $seconds, function () { return DB::table('users')->get(); });

NOTE

테스트 코드에서 cache() 전역 함수를 사용할 경우, Cache::shouldReceive 메서드를 활용해 파사드와 동일하게 목킹(mocking)할 수 있습니다.

캐시 태그

WARNING

캐시 태그는 file, dynamodb, database 드라이버에서는 지원되지 않습니다. 또한 여러 태그를 "영구 저장"과 함께 사용하는 경우, memcached처럼 오래된 레코드를 자동으로 삭제해주는 드라이버를 사용하면 성능이 더 좋습니다.

태그가 달린 캐시 항목 저장하기

캐시 태그를 사용하면 연관된 캐시 항목들을 그룹으로 묶어 한 번에 삭제할 수 있습니다. 태그 목록을 배열로 전달해 태그가 달린 캐시에 접근할 수 있습니다.

Cache::tags(['people', 'artists'])->put('John', $john, $seconds); Cache::tags(['people', 'authors'])->put('Anne', $anne, $seconds);

태그가 달린 캐시 항목 조회하기

태그가 달린 항목을 조회할 때는 저장 시 사용한 태그 목록을 동일하게 지정해야 합니다.

$john = Cache::tags(['people', 'artists'])->get('John'); $anne = Cache::tags(['people', 'authors'])->get('Anne');

태그가 달린 캐시 항목 삭제하기

특정 태그 또는 태그 조합에 해당하는 모든 항목을 한 번에 삭제할 수 있습니다. 아래 예시에서는 people 태그가 달린 모든 항목이 삭제되므로, JohnAnne 모두 삭제됩니다.

Cache::tags(['people', 'authors'])->flush();

반면, 아래 예시에서는 authors 태그에 해당하는 항목만 삭제되므로 Anne만 삭제되고 John은 남습니다.

Cache::tags('authors')->flush();

오래된 캐시 태그 정리하기

WARNING

태그 정리는 Redis를 캐시 드라이버로 사용할 때만 필요합니다.

Redis 드라이버를 사용할 경우, 시간이 지나면서 오래된 태그 참조가 쌓일 수 있습니다. 이를 정기적으로 정리하려면 Laravel의 스케줄러에 cache:prune-stale-tags Artisan 명령을 등록하는 것이 좋습니다.

use Illuminate\Support\Facades\Schedule; Schedule::command('cache:prune-stale-tags')->hourly();

원자적 잠금

WARNING

이 기능을 사용하려면 애플리케이션의 기본 캐시 드라이버가 memcached, redis, dynamodb, database, file, array 중 하나여야 합니다. 또한 모든 서버가 동일한 중앙 캐시 서버와 통신해야 합니다.

잠금 관리

원자적 잠금(Atomic Lock)을 사용하면 경쟁 조건(race condition)을 걱정하지 않고 분산 잠금을 제어할 수 있습니다. 예를 들어 Laravel Forge는 한 번에 하나의 원격 작업만 실행되도록 원자적 잠금을 활용합니다. Cache::lock 메서드로 잠금을 생성하고 관리할 수 있습니다.

use Illuminate\Support\Facades\Cache; $lock = Cache::lock('foo', 10); if ($lock->get()) { // 10초 동안 잠금 유지 $lock->release(); }

get 메서드는 클로저를 받을 수도 있습니다. 클로저 실행이 끝나면 Laravel이 자동으로 잠금을 해제합니다.

Cache::lock('foo', 10)->get(function () { // 10초 동안 잠금 유지 후 자동 해제 });

잠금을 즉시 획득할 수 없는 경우, 지정한 시간(초) 동안 대기하도록 할 수 있습니다. 시간 내에 잠금을 획득하지 못하면 Illuminate\Contracts\Cache\LockTimeoutException이 발생합니다.

use Illuminate\Contracts\Cache\LockTimeoutException; $lock = Cache::lock('foo', 10); try { $lock->block(5); // 최대 5초 대기 후 잠금 획득 } catch (LockTimeoutException $e) { // 잠금 획득 실패 } finally { $lock->release(); }

block 메서드에도 클로저를 전달할 수 있습니다.

Cache::lock('foo', 10)->block(5, function () { // 최대 5초 대기 후 잠금 획득, 완료 후 자동 해제 });

프로세스 간 잠금 관리

한 프로세스에서 잠금을 획득하고, 다른 프로세스에서 해제해야 하는 경우가 있습니다. 예를 들어, 웹 요청 중에 잠금을 획득하고 해당 요청으로 트리거된 큐 Job이 완료된 후 잠금을 해제할 수 있습니다. 이 경우 잠금의 범위를 지정하는 "소유자 토큰"을 Job에 전달해야 합니다.

// 컨트롤러에서 $podcast = Podcast::find($id); $lock = Cache::lock('processing', 120); if ($lock->get()) { ProcessPodcast::dispatch($podcast, $lock->owner()); }
// ProcessPodcast Job에서 Cache::restoreLock('processing', $this->owner)->release();

소유자 정보 없이 잠금을 강제로 해제하려면 forceRelease 메서드를 사용하세요.

Cache::lock('processing')->forceRelease();

잠금 갱신

처리 시간이 예상보다 길어질 수 있을 때 잠금 TTL을 연장해야 하는 경우가 있습니다. extend 메서드를 사용하면 기존 잠금을 갱신할 수 있습니다.

Cache::lock('processing', 120)->extend(60);

동시성 제한

원자적 잠금을 활용한 동시성 제한 기능도 제공됩니다. 특정 코드가 동시에 여러 번 실행되는 것을 제한할 때 유용합니다. 자세한 내용은 동시성 제한 문서를 참고하세요.

캐시 페일오버

때로는 redismemcached처럼 성능이 좋은 캐시 드라이버를 사용하면서도, 해당 드라이버에 문제가 생겼을 때 databasearray 같은 다른 드라이버로 자동 전환(페일오버)하고 싶을 수 있습니다. 이를 위해 config/cache.php에서 failover 드라이버를 설정할 수 있습니다.

'failover' => [ 'driver' => 'failover', 'stores' => [ 'redis', 'database', ], ],

failover 드라이버는 stores에 나열된 순서대로 사용 가능한 스토어를 찾습니다. 앞에 있는 스토어가 실패하면 자동으로 다음 스토어를 사용합니다.

설정 후, 이 스토어를 기본 캐시 드라이버로 지정하거나 Cache::store('failover')로 직접 접근할 수 있습니다.

'default' => env('CACHE_STORE', 'failover'),

커스텀 캐시 드라이버 추가하기

드라이버 작성하기

커스텀 캐시 드라이버를 만들려면 Illuminate\Contracts\Cache\Store 컨트랙트를 구현해야 합니다. 예를 들어 MongoDB 기반 캐시 드라이버는 다음과 같이 작성할 수 있습니다.

<?php namespace App\Extensions; use Illuminate\Contracts\Cache\Store; class MongoStore implements Store { public function get($key) {} public function many(array $keys) {} public function put($key, $value, $seconds) {} public function putMany(array $values, $seconds) {} public function increment($key, $value = 1) {} public function decrement($key, $value = 1) {} public function forever($key, $value) {} public function forget($key) {} public function flush() {} public function getPrefix() {} }

각 메서드는 MongoDB 연결을 통해 구현하면 됩니다. 구현 참고용으로 Laravel 프레임워크 소스코드Illuminate\Cache\MemcachedStore를 살펴보는 것을 권장합니다. 구현이 완료되면 Cache 파사드의 extend 메서드로 드라이버를 등록할 수 있습니다.

Cache::extend('mongo', function (Application $app) { return Cache::repository(new MongoStore); });

NOTE

커스텀 캐시 드라이버 코드를 어디에 둘지 고민된다면 app/Extensions 디렉터리를 만들어 넣는 것을 추천합니다. 단, Laravel에서 고정된 위치는 없으므로 프로젝트 구조에 맞게 자유롭게 결정하면 됩니다.

드라이버 등록하기

Laravel에 커스텀 캐시 드라이버를 등록하려면 Cache 파사드의 extend 메서드를 사용합니다. Cache::extend는 서비스 프로바이더의 boot 메서드에서 호출하는 것이 일반적입니다. 기본 제공되는 App\Providers\AppServiceProvider를 활용하거나, 별도의 서비스 프로바이더를 생성해도 됩니다.

<?php namespace App\Providers; use App\Extensions\MongoStore; use Illuminate\Contracts\Foundation\Application; use Illuminate\Support\Facades\Cache; use Illuminate\Support\ServiceProvider; class CacheServiceProvider extends ServiceProvider { /** * 서비스 등록 */ public function register(): void { // ... } /** * 서비스 부트스트랩 */ public function boot(): void { Cache::extend('mongo', function (Application $app) { return Cache::repository(new MongoStore); }); } }

extend 메서드의 첫 번째 인수는 드라이버 이름입니다. config/cache.phpdriver 옵션에 이 이름을 지정하면 됩니다. 두 번째 인수는 Illuminate\Cache\Repository 인스턴스를 반환해야 하는 클로저입니다. 클로저에는 서비스 컨테이너 인스턴스인 $app이 전달됩니다.

등록이 완료되면 .env 파일이나 config/cache.php에서 드라이버 이름을 지정해 사용할 수 있습니다.

CACHE_STORE=mongo

이벤트

캐시 관련 이벤트가 발생할 때 특정 코드를 실행하려면 캐시 이벤트 리스너를 등록할 수 있습니다. 보통 이벤트 리스너는 App\Providers\EventServiceProvider에 정의합니다.

use App\Listeners\LogCacheHit; use App\Listeners\LogCacheMissed; use App\Listeners\LogKeyForgotten; use App\Listeners\LogKeyWritten; use Illuminate\Cache\Events\CacheHit; use Illuminate\Cache\Events\CacheMissed; use Illuminate\Cache\Events\KeyForgotten; use Illuminate\Cache\Events\KeyWritten; protected $listen = [ CacheHit::class => [ LogCacheHit::class, ], CacheMissed::class => [ LogCacheMissed::class, ], KeyForgotten::class => [ LogKeyForgotten::class, ], KeyWritten::class => [ LogKeyWritten::class, ], ];

특정 캐시 이벤트를 비활성화하고 싶다면, config/cache.php 설정 파일에서 해당 이벤트를 끌 수 있습니다.

'stores' => [ 'redis' => [ 'driver' => 'redis', // ... 'events' => false, ], ],

캐시

소개

애플리케이션에서 수행하는 일부 데이터 조회나 처리 작업은 CPU를 많이 사용하거나 완료하는 데 수 초가 걸릴 수 있습니다. 이런 경우, 조회한 데이터를 일정 시간 동안 캐시해두면 이후 동일한 요청에서 훨씬 빠르게 응답할 수 있습니다. 캐시된 데이터는 보통 MemcachedRedis처럼 매우 빠른 데이터 저장소에 보관됩니다.

Laravel은 다양한 캐시 백엔드를 위한 표현력 있고 통일된 API를 제공합니다. 덕분에 어떤 저장소를 선택하더라도 동일한 코드로 빠른 데이터 조회를 활용해 웹 애플리케이션의 응답 속도를 높일 수 있습니다.

캐시

설정

캐시 설정 파일은 config/cache.php에 있습니다. 이 파일에서 애플리케이션 전체에서 기본으로 사용할 캐시 스토어를 지정할 수 있습니다. Laravel은 Memcached, Redis, DynamoDB, 관계형 데이터베이스, 파일시스템 디스크 등 널리 사용되는 캐시 백엔드를 기본으로 지원합니다. 파일 기반 캐시 드라이버도 제공되며, arraynull 드라이버는 자동화된 테스트 환경에서 유용하게 쓸 수 있습니다.

설정 파일에는 그 외에도 다양한 옵션이 있으니 한 번 살펴보시기 바랍니다. 기본값은 database 캐시 드라이버로, 직렬화된 캐시 객체를 애플리케이션 데이터베이스에 저장합니다.

드라이버 사전 요구 사항

Database

database 캐시 드라이버를 사용하려면 캐시 데이터를 저장할 데이터베이스 테이블이 필요합니다. 일반적으로 Laravel 기본 마이그레이션 파일인 0001_01_01_000001_create_cache_table.php에 이미 포함되어 있습니다. 만약 해당 마이그레이션이 없다면 make:cache-table Artisan 명령어로 생성할 수 있습니다:

php artisan make:cache-tablephp artisan migrate

Memcached

Memcached 드라이버를 사용하려면 Memcached PECL 패키지가 설치되어 있어야 합니다. 사용할 Memcached 서버 목록은 config/cache.php에 정의합니다. 파일 내에 이미 memcached.servers 항목이 준비되어 있습니다:

'memcached' => [ // ... 'servers' => [ [ 'host' => env('MEMCACHED_HOST', '127.0.0.1'), 'port' => env('MEMCACHED_PORT', 11211), 'weight' => 100, ], ], ],

필요한 경우 host에 UNIX 소켓 경로를 지정할 수도 있습니다. 이때 port는 반드시 0으로 설정해야 합니다:

'memcached' => [ // ... 'servers' => [ [ 'host' => '/var/run/memcached/memcached.sock', 'port' => 0, 'weight' => 100 ], ], ],

Redis

Laravel에서 Redis 캐시를 사용하려면 PECL을 통해 PhpRedis PHP 확장을 설치하거나, Composer로 predis/predis 패키지를 설치해야 합니다. Laravel Sail에는 PhpRedis 확장이 이미 포함되어 있으며, Laravel CloudLaravel Forge 같은 공식 Laravel 플랫폼에도 기본 설치되어 있습니다.

Redis 설정에 대한 자세한 내용은 Laravel Redis 문서를 참고하세요.

Storage

storage 캐시 드라이버를 사용하면 애플리케이션에 설정된 파일시스템 디스크 중 하나에 캐시 값을 저장할 수 있습니다. 예를 들어 기존에 사용 중인 S3 디스크를 키/값 캐시 스토어로 활용하고 싶을 때 유용합니다:

'storage' => [ 'driver' => 'storage', 'disk' => env('CACHE_STORAGE_DISK'), 'path' => env('CACHE_STORAGE_PATH', 'framework/cache/data'), ],

DynamoDB

DynamoDB 캐시 드라이버를 사용하기 전에, 캐시 데이터를 저장할 DynamoDB 테이블을 먼저 생성해야 합니다. 테이블 이름은 보통 cache로 지정하지만, cache 설정 파일의 stores.dynamodb.table 값을 기준으로 이름을 정해도 됩니다. 환경 변수 DYNAMODB_CACHE_TABLE로도 테이블 이름을 설정할 수 있습니다.

테이블에는 문자열 파티션 키가 필요하며, 키 이름은 cache 설정 파일의 stores.dynamodb.attributes.key 값과 일치해야 합니다. 기본값은 key입니다.

DynamoDB는 만료된 항목을 자동으로 삭제하지 않으므로, 테이블에 TTL(Time to Live)을 반드시 활성화해야 합니다. TTL 설정 시 속성 이름은 expires_at으로 지정하세요.

다음으로 AWS SDK를 설치해 Laravel 애플리케이션이 DynamoDB와 통신할 수 있도록 합니다:

composer require aws/aws-sdk-php

또한 DynamoDB 캐시 스토어에 필요한 설정값을 제공해야 합니다. AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY 등의 값은 애플리케이션의 .env 파일에 정의하는 것이 일반적입니다:

'dynamodb' => [ 'driver' => 'dynamodb', 'key' => env('AWS_ACCESS_KEY_ID'), 'secret' => env('AWS_SECRET_ACCESS_KEY'), 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), 'table' => env('DYNAMODB_CACHE_TABLE', 'cache'), 'endpoint' => env('DYNAMODB_ENDPOINT'), ],

MongoDB

MongoDB를 사용하는 경우, 공식 패키지 mongodb/laravel-mongodb에서 제공하는 mongodb 캐시 드라이버를 이용할 수 있습니다. mongodb 데이터베이스 커넥션을 통해 설정하며, MongoDB의 TTL 인덱스를 활용해 만료된 캐시 항목을 자동으로 삭제할 수 있습니다.

MongoDB 설정에 대한 자세한 내용은 MongoDB의 캐시 및 잠금 문서를 참고하세요.

캐시

캐시 인스턴스 얻기

캐시 스토어 인스턴스를 얻으려면 Cache 파사드를 사용하면 됩니다. 이 문서 전반에서도 Cache 파사드를 기준으로 설명합니다. Cache 파사드는 Laravel 캐시 컨트랙트의 구현체에 간편하게 접근할 수 있는 방법을 제공합니다.

<?php namespace App\Http\Controllers; use Illuminate\Support\Facades\Cache; class UserController extends Controller { /** * 전체 사용자 목록을 반환합니다. */ public function index(): array { $value = Cache::get('key'); return [ // ... ]; } }

여러 캐시 스토어 접근하기

Cache 파사드의 store 메서드를 사용하면 여러 캐시 스토어에 접근할 수 있습니다. store 메서드에 전달하는 키는 cache 설정 파일의 stores 배열에 정의된 스토어 이름과 일치해야 합니다.

$value = Cache::store('file')->get('foo'); Cache::store('redis')->put('bar', 'baz', 600); // 10분

캐시에서 아이템 조회하기

Cache 파사드의 get 메서드로 캐시에서 값을 가져올 수 있습니다. 해당 키가 캐시에 없으면 null이 반환됩니다. 두 번째 인자로 기본값을 지정하면, 캐시에 값이 없을 때 해당 기본값이 반환됩니다.

$value = Cache::get('key'); $value = Cache::get('key', 'default');

기본값으로 클로저를 전달할 수도 있습니다. 캐시에 해당 키가 없을 때 클로저가 실행되어 그 결과가 반환됩니다. 클로저를 사용하면 데이터베이스나 외부 서비스 호출을 실제로 필요한 순간까지 미룰 수 있습니다.

$value = Cache::get('key', function () { return DB::table(/* ... */)->get(); });

아이템 존재 여부 확인

has 메서드로 특정 아이템이 캐시에 존재하는지 확인할 수 있습니다. 아이템이 존재하더라도 값이 null이면 false를 반환합니다.

if (Cache::has('key')) { // ... }

값 증가 / 감소

incrementdecrement 메서드로 캐시에 저장된 정수 값을 증가하거나 감소시킬 수 있습니다. 두 번째 인자로 증감할 양을 지정할 수 있습니다.

// 값이 없으면 초기화... Cache::add('key', 0, now()->plus(hours: 4)); // 값 증가 또는 감소... Cache::increment('key'); Cache::increment('key', $amount); Cache::decrement('key'); Cache::decrement('key', $amount);

조회 후 없으면 저장 (remember)

캐시에서 값을 가져오되, 없으면 특정 값을 계산해서 저장하고 싶을 때는 Cache::remember 메서드를 사용합니다. 예를 들어 전체 사용자 목록을 캐시에서 가져오고, 캐시에 없으면 데이터베이스에서 조회한 뒤 캐시에 저장하는 패턴을 간단하게 구현할 수 있습니다.

$value = Cache::remember('users', $seconds, function () { return DB::table('users')->get(); });

캐시에 해당 키가 없으면 클로저가 실행되고, 그 결과가 캐시에 저장됩니다.

값이 캐시에서 직접 가져온 것인지, 아니면 클로저를 실행해서 얻은 것인지 알고 싶다면 rememberWithWarmth 메서드를 사용하세요. 이 메서드는 캐시 값과 함께, 캐시에서 바로 가져온 경우(true) 또는 클로저로 새로 계산된 경우(false)를 나타내는 불리언 값을 배열로 반환합니다.

[$value, $warm] = Cache::rememberWithWarmth('users', $seconds, function () { return DB::table('users')->get(); });

캐시에 없으면 영구적으로 저장하고 싶다면 rememberForever 메서드를 사용하세요.

$value = Cache::rememberForever('users', function () { return DB::table('users')->get(); });

Stale While Revalidate

Cache::remember를 사용할 때, 캐시가 만료된 직후 첫 번째 요청은 값을 다시 계산하는 동안 응답이 느려질 수 있습니다. 일부 데이터는 약간 오래된 값을 잠시 제공하면서 백그라운드에서 갱신하는 방식이 더 나을 수 있습니다. 이를 "stale-while-revalidate" 패턴이라고 하며, Cache::flexible 메서드로 구현할 수 있습니다.

flexible 메서드는 두 개의 값을 담은 배열을 인자로 받습니다. 첫 번째 값은 캐시가 "신선(fresh)"한 기간(초), 두 번째 값은 "오래됨(stale)" 상태로 제공할 수 있는 최대 기간(초)입니다.

  • 첫 번째 값 이내 요청: 캐시를 즉시 반환, 재계산 없음
  • 두 값 사이 요청: 오래된 값을 반환하되, 응답 전송 후 백그라운드에서 캐시를 지연 함수로 갱신
  • 두 번째 값 이후 요청: 캐시 만료로 간주하여 즉시 재계산, 응답이 느려질 수 있음
$value = Cache::flexible('users', [5, 10], function () { return DB::table('users')->get(); });

조회 후 삭제 (pull)

캐시에서 값을 가져온 뒤 즉시 삭제하고 싶을 때는 pull 메서드를 사용하세요. get과 마찬가지로, 키가 없으면 null이 반환됩니다.

$value = Cache::pull('key'); $value = Cache::pull('key', 'default');

캐시에 아이템 저장하기

Cache 파사드의 put 메서드로 캐시에 값을 저장할 수 있습니다.

Cache::put('key', 'value', $seconds = 10);

만료 시간을 지정하지 않으면 값은 영구적으로 저장됩니다.

Cache::put('key', 'value');

초(integer) 대신 DateTime 인스턴스로 만료 시각을 직접 지정할 수도 있습니다.

Cache::put('key', 'value', now()->plus(minutes: 10));

없을 때만 저장 (add)

add 메서드는 캐시에 해당 키가 없을 때만 값을 저장합니다. 실제로 저장되면 true, 이미 존재하면 false를 반환합니다. add 메서드는 원자적(atomic) 연산으로 처리됩니다.

Cache::add('key', 'value', $seconds);

캐시 만료 시간 연장하기

touch 메서드로 이미 저장된 캐시 아이템의 TTL(유효 시간)을 연장할 수 있습니다. 아이템이 존재하고 만료 시간이 성공적으로 연장되면 true, 아이템이 없으면 false를 반환합니다.

Cache::touch('key', 3600);

DateTimeInterface, DateInterval, 또는 Carbon 인스턴스로 정확한 만료 시각을 지정할 수도 있습니다.

Cache::touch('key', now()->addHours(2));

영구 저장

forever 메서드를 사용하면 만료 없이 캐시에 값을 영구 저장합니다. 이 값은 자동으로 삭제되지 않으므로, forget 메서드를 사용해 직접 제거해야 합니다.

Cache::forever('key', 'value');

NOTE

Memcached 드라이버를 사용하는 경우, 캐시 저장소가 최대 용량에 도달하면 "영구 저장"된 아이템도 삭제될 수 있습니다.

캐시에서 아이템 삭제하기

forget 메서드로 캐시에서 특정 아이템을 삭제할 수 있습니다.

Cache::forget('key');

만료 시간을 0 또는 음수로 설정하는 방식으로도 아이템을 삭제할 수 있습니다.

Cache::put('key', 'value', 0); Cache::put('key', 'value', -5);

캐시 전체를 비우려면 flush 메서드를 사용합니다.

Cache::flush();

캐시에 저장된 모든 원자적 잠금(atomic lock)을 제거하려면 flushLocks 메서드를 사용합니다.

Cache::flushLocks();

WARNING

flush 메서드는 설정된 캐시 "prefix"를 무시하고 캐시 스토어의 모든 항목을 삭제합니다. 여러 애플리케이션이 동일한 캐시 스토어를 공유하는 경우 특히 주의하세요.

캐시 메모이제이션

Laravel의 memo 캐시 드라이버는 단일 요청 또는 Job 실행 중에 캐시에서 조회한 값을 메모리에 임시로 저장합니다. 동일한 실행 흐름 내에서 같은 키를 반복 조회할 때 캐시 스토어에 불필요하게 접근하지 않아 성능을 크게 향상시킬 수 있습니다.

메모이제이션된 캐시를 사용하려면 memo 메서드를 호출하세요.

use Illuminate\Support\Facades\Cache; $value = Cache::memo()->get('key');

memo 메서드에 캐시 스토어 이름을 지정하면, 해당 스토어를 기반으로 메모이제이션 드라이버가 동작합니다.

// 기본 캐시 스토어 사용... $value = Cache::memo()->get('key'); // Redis 캐시 스토어 사용... $value = Cache::memo('redis')->get('key');

특정 키에 대해 처음 get을 호출하면 캐시 스토어에서 값을 가져오지만, 이후 동일 요청 내에서의 호출은 메모리에서 바로 반환됩니다.

// 캐시 스토어에서 조회... $value = Cache::memo()->get('key'); // 메모리에서 반환 (캐시 스토어 미접근)... $value = Cache::memo()->get('key');

put, increment, remember 등 캐시 값을 변경하는 메서드를 호출하면, 메모이제이션된 값은 자동으로 무효화되고 실제 캐시 스토어에 새 값이 기록됩니다.

Cache::memo()->put('name', 'Taylor'); // 캐시 스토어에 저장... Cache::memo()->get('name'); // 캐시 스토어에서 조회... Cache::memo()->get('name'); // 메모이제이션 값 반환... Cache::memo()->put('name', 'Tim'); // 메모이제이션 무효화 후 새 값 저장... Cache::memo()->get('name'); // 캐시 스토어에서 다시 조회...

cache 헬퍼 함수

Cache 파사드 외에도 전역 cache 함수로 캐시 값을 조회하고 저장할 수 있습니다. 문자열 인자 하나만 전달하면 해당 키의 값을 반환합니다.

$value = cache('key');

키/값 배열과 만료 시간을 함께 전달하면 지정한 시간 동안 값을 저장합니다.

cache(['key' => 'value'], $seconds); cache(['key' => 'value'], now()->plus(minutes: 10));

인자 없이 호출하면 Illuminate\Contracts\Cache\Factory 구현 인스턴스를 반환하므로, 다른 캐시 메서드를 체이닝해서 사용할 수 있습니다.

cache()->remember('users', $seconds, function () { return DB::table('users')->get(); });

NOTE

전역 cache 함수를 테스트할 때는 파사드 테스트와 동일하게 Cache::shouldReceive 메서드를 사용할 수 있습니다.

캐시 태그

WARNING

캐시 태그는 file, dynamodb, database, storage 캐시 드라이버에서는 지원되지 않습니다.

태그가 지정된 캐시 항목 저장

캐시 태그를 사용하면 연관된 캐시 항목들을 하나 이상의 태그로 묶어서 관리할 수 있습니다. 특히 특정 태그에 해당하는 캐시를 한 번에 삭제하고 싶을 때 유용합니다. 태그가 지정된 캐시에 접근하려면 태그 이름의 배열을 tags 메서드에 전달하면 됩니다. 예를 들어 다음과 같이 두 항목을 각각 다른 태그 조합으로 저장할 수 있습니다.

use Illuminate\Support\Facades\Cache; Cache::tags(['people', 'artists'])->put('John', $john, $seconds); Cache::tags(['people', 'authors'])->put('Anne', $anne, $seconds);

태그가 지정된 캐시 항목 조회

태그를 지정하여 저장한 항목은 반드시 동일한 태그를 함께 제공해야 조회할 수 있습니다. tags 메서드에 저장 시 사용한 것과 동일한 순서의 태그 배열을 전달한 뒤, get 메서드로 키를 지정하면 됩니다.

$john = Cache::tags(['people', 'artists'])->get('John'); $anne = Cache::tags(['people', 'authors'])->get('Anne');

태그가 지정된 캐시 항목 삭제

특정 태그가 할당된 캐시 항목을 한 번에 모두 삭제할 수 있습니다. 예를 들어 아래 코드는 people 또는 authors 태그가 포함된 모든 캐시를 삭제합니다. 결과적으로 AnneJohn 모두 캐시에서 제거됩니다.

Cache::tags(['people', 'authors'])->flush();

반면 아래 코드는 authors 태그만 지정했으므로, Anne만 삭제되고 John은 캐시에 그대로 남습니다.

Cache::tags('authors')->flush();

아토믹 락(Atomic Locks)

WARNING

이 기능을 사용하려면 애플리케이션의 기본 캐시 드라이버로 memcached, redis, dynamodb, database, file, array 중 하나를 사용해야 합니다. 또한 모든 서버가 동일한 중앙 캐시 서버와 통신하고 있어야 합니다.

락 관리

아토믹 락을 사용하면 경쟁 조건(race condition)을 걱정하지 않고 분산 락을 안전하게 다룰 수 있습니다. 예를 들어 Laravel Cloud는 아토믹 락을 활용해 서버에서 동시에 하나의 원격 작업만 실행되도록 보장합니다. Cache::lock 메서드로 락을 생성하고 관리할 수 있습니다.

use Illuminate\Support\Facades\Cache; $lock = Cache::lock('foo', 10); if ($lock->get()) { // 10초 동안 락을 획득했습니다... $lock->release(); }

get 메서드에 클로저를 전달하면, 클로저 실행이 끝난 후 Laravel이 락을 자동으로 해제합니다.

Cache::lock('foo', 10)->get(function () { // 10초 동안 락을 획득하고, 실행 후 자동으로 해제됩니다... });

락을 요청했을 때 이미 다른 프로세스가 사용 중이라면, 지정한 초만큼 대기하도록 설정할 수 있습니다. 지정한 시간 안에 락을 획득하지 못하면 Illuminate\Contracts\Cache\LockTimeoutException이 발생합니다.

use Illuminate\Contracts\Cache\LockTimeoutException; $lock = Cache::lock('foo', 10); try { $lock->block(5); // 최대 5초 대기 후 락을 획득했습니다... } catch (LockTimeoutException $e) { // 락을 획득하지 못했습니다... } finally { $lock->release(); }

block 메서드에도 클로저를 전달할 수 있습니다. 이 방식을 사용하면 락 획득 후 클로저가 실행되고, 실행 완료 시 락이 자동으로 해제됩니다.

Cache::lock('foo', 10)->block(5, function () { // 최대 5초 대기 후 락을 획득하고, 10초 동안 유지됩니다... });

프로세스 간 락 공유

한 프로세스에서 락을 획득하고, 다른 프로세스에서 해제해야 하는 경우가 있습니다. 예를 들어 웹 요청에서 락을 걸고, 해당 요청으로 디스패치된 큐 Job의 마지막 단계에서 락을 해제하는 시나리오가 있습니다. 이때는 락의 소유자 토큰(owner token)을 큐 Job에 전달해, Job 안에서 해당 토큰으로 락 인스턴스를 복원하면 됩니다.

아래 예시에서는 락을 성공적으로 획득한 경우 큐 Job을 디스패치하면서, owner 메서드로 소유자 토큰을 함께 전달합니다.

$podcast = Podcast::find($id); $lock = Cache::lock('processing', 120); if ($lock->get()) { ProcessPodcast::dispatch($podcast, $lock->owner()); }

ProcessPodcast Job 안에서는 소유자 토큰을 이용해 락을 복원하고 해제합니다.

Cache::restoreLock('processing', $this->owner)->release();

현재 소유자와 관계없이 강제로 락을 해제하려면 forceRelease 메서드를 사용합니다.

Cache::lock('processing')->forceRelease();

락 갱신

현재 보유 중인 락의 만료 시간을 연장하려면 refresh 메서드를 사용합니다. 인자를 생략하면 락의 원래 지속 시간으로 연장됩니다. 오랜 시간이 걸리는 작업에서 처음부터 긴 락을 잡는 대신, 짧은 락을 획득하고 주기적으로 갱신하는 방식으로 활용하면 유용합니다.

$lock = Cache::lock('generate-reports', 60); if ($lock->get()) { foreach ($reports as $report) { $report->generate(); // 락을 60초 더 연장합니다... $lock->refresh(); } $lock->release(); }

동시 실행 제한

아토믹 락 기능을 바탕으로 클로저의 동시 실행 횟수를 제한하는 편의 메서드도 제공됩니다.

withoutOverlapping — 중복 실행 방지

인프라 전체에서 동시에 하나의 인스턴스만 실행되어야 할 때 withoutOverlapping을 사용합니다.

Cache::withoutOverlapping('foo', function () { // 락을 획득하고 실행됩니다... });

기본적으로 락은 클로저 실행이 끝날 때까지 유지되며, 락 획득까지 최대 10초 대기합니다. 이 값은 추가 인자로 조정할 수 있습니다.

Cache::withoutOverlapping('foo', function () { // 최대 5초 대기 후 락을 획득하며, 120초 동안 유지됩니다... }, lockFor: 120, waitFor: 5);

지정한 대기 시간 안에 락을 획득하지 못하면 Illuminate\Contracts\Cache\LockTimeoutException이 발생합니다.

funnel — 최대 동시 실행 수 제한

특정 수 이하의 동시 실행만 허용하려면 funnel 메서드를 사용합니다. 락을 지원하는 모든 캐시 드라이버에서 사용할 수 있습니다.

Cache::funnel('foo') ->limit(3) ->releaseAfter(60) ->block(10) ->then(function () { // 동시성 락을 획득했습니다... }, function () { // 동시성 락을 획득하지 못했습니다... });

각 메서드의 역할은 다음과 같습니다.

메서드설명
limit(n)최대 동시 실행 수
releaseAfter(초)획득한 슬롯의 안전 타임아웃(자동 해제까지의 최대 시간)
block(초)빈 슬롯을 기다리는 최대 대기 시간

실패 클로저 대신 예외로 처리하고 싶다면 두 번째 클로저를 생략하면 됩니다. 지정한 대기 시간 안에 락을 획득하지 못하면 Illuminate\Cache\Limiters\LimiterTimeoutException이 발생합니다.

use Illuminate\Cache\Limiters\LimiterTimeoutException; try { Cache::funnel('foo') ->limit(3) ->releaseAfter(60) ->block(10) ->then(function () { // 동시성 락을 획득했습니다... }); } catch (LimiterTimeoutException $e) { // 동시성 락을 획득하지 못했습니다... }

특정 캐시 스토어를 지정하려면 해당 스토어에서 funnel 메서드를 호출하면 됩니다.

Cache::store('redis')->funnel('foo') ->limit(3) ->block(10) ->then(function () { // "redis" 스토어를 사용해 동시성 락을 획득했습니다... });

NOTE

funnel 메서드를 사용하려면 캐시 스토어가 Illuminate\Contracts\Cache\LockProvider 인터페이스를 구현하고 있어야 합니다. 락을 지원하지 않는 캐시 스토어에서 funnel을 호출하면 BadMethodCallException이 발생합니다.

캐시 Failover

failover 캐시 드라이버는 캐시 작업이 실패했을 때 자동으로 다음 저장소로 전환하는 고가용성 기능을 제공합니다. 기본 캐시 저장소에 문제가 생기면, Laravel은 설정된 저장소 목록을 순서대로 시도하여 캐시 서비스를 유지합니다. 프로덕션 환경에서 캐시 신뢰성이 중요한 경우 특히 유용합니다.

Failover 캐시 저장소를 구성하려면 failover 드라이버를 지정하고, 순서대로 시도할 저장소 이름 배열을 제공합니다. config/cache.php 파일에는 기본적으로 예시 설정이 포함되어 있습니다:

'failover' => [ 'driver' => 'failover', 'stores' => [ 'database', 'array', ], ],

위 예시에서는 database 저장소에 장애가 발생하면 자동으로 array 저장소로 전환됩니다.

설정을 완료한 후에는 .env 파일에서 기본 캐시 저장소를 failover 저장소로 지정해야 합니다:

CACHE_STORE=failover

NOTE

실제 운영 환경에서는 array 드라이버가 메모리 기반으로 요청이 끝나면 데이터가 사라지므로, 최후 수단 저장소로만 적합합니다. 가능하면 Redis → Memcached → database 처럼 내구성 있는 저장소를 우선 순위에 두는 것을 권장합니다.

캐시 저장소 작업이 실패하여 failover가 활성화되면, Laravel은 Illuminate\Cache\Events\CacheFailedOver 이벤트를 디스패치합니다. 이 이벤트를 리스닝하면 장애 발생 사실을 로그에 기록하거나 Slack 알림 등으로 모니터링할 수 있습니다:

use Illuminate\Cache\Events\CacheFailedOver; use Illuminate\Support\Facades\Event; Event::listen(function (CacheFailedOver $event) { // $event->storeName : 실패한 저장소 이름 logger()->error("캐시 저장소 장애 발생: {$event->storeName}"); });

커스텀 캐시 드라이버 추가하기

드라이버 작성하기

커스텀 캐시 드라이버를 만들려면 먼저 Illuminate\Contracts\Cache\Store 컨트랙트를 구현해야 합니다. MongoDB 기반의 캐시 구현체는 다음과 같은 형태가 됩니다:

<?php namespace App\Extensions; use Illuminate\Contracts\Cache\Store; class MongoStore implements Store { public function get($key) {} public function many(array $keys) {} public function put($key, $value, $seconds) {} public function putMany(array $values, $seconds) {} public function increment($key, $value = 1) {} public function decrement($key, $value = 1) {} public function forever($key, $value) {} public function forget($key) {} public function flush() {} public function getPrefix() {} }

각 메서드를 MongoDB 연결을 사용해 구현하면 됩니다. 각 메서드의 구현 방법이 궁금하다면 Laravel 프레임워크 소스 코드에서 Illuminate\Cache\MemcachedStore를 참고하세요. 구현이 완료되면 Cache 파사드의 extend 메서드를 호출하여 커스텀 드라이버 등록을 마무리할 수 있습니다:

Cache::extend('mongo', function (Application $app) { return Cache::repository(new MongoStore); });

NOTE

커스텀 캐시 드라이버 코드를 어디에 둘지 고민된다면, app 디렉터리 안에 Extensions 네임스페이스를 만들어 관리하는 방법을 추천합니다. 다만 Laravel은 특정 디렉터리 구조를 강제하지 않으므로, 자신의 프로젝트 성격에 맞게 자유롭게 구성해도 됩니다.

드라이버 등록하기

커스텀 캐시 드라이버를 Laravel에 등록할 때는 Cache 파사드의 extend 메서드를 사용합니다. 이때 주의할 점이 있습니다. 다른 서비스 프로바이더의 boot 메서드에서 캐시 값을 읽으려 할 수 있으므로, 커스텀 드라이버는 booting 콜백 안에서 등록해야 합니다.

booting 콜백을 사용하면 모든 서비스 프로바이더의 register 메서드가 실행된 후, 각 서비스 프로바이더의 boot 메서드가 호출되기 직전 시점에 커스텀 드라이버를 정확히 등록할 수 있습니다. 이 콜백은 App\Providers\AppServiceProviderregister 메서드 안에 작성합니다:

<?php namespace App\Providers; use App\Extensions\MongoStore; use Illuminate\Contracts\Foundation\Application; use Illuminate\Support\Facades\Cache; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider { /** * 애플리케이션 서비스를 등록합니다. */ public function register(): void { $this->app->booting(function () { Cache::extend('mongo', function (Application $app) { return Cache::repository(new MongoStore); }); }); } /** * 애플리케이션 서비스를 부트스트랩합니다. */ public function boot(): void { // ... } }

extend 메서드의 첫 번째 인자는 드라이버 이름입니다. 이 이름은 config/cache.php 설정 파일의 driver 옵션과 일치해야 합니다. 두 번째 인자는 Illuminate\Cache\Repository 인스턴스를 반환하는 클로저입니다. 클로저에는 서비스 컨테이너 인스턴스인 $app이 전달됩니다.

드라이버 등록이 완료되면, CACHE_STORE 환경 변수 또는 config/cache.phpdefault 옵션 값을 등록한 드라이버 이름으로 변경하면 됩니다.

이벤트

캐시 작업이 실행될 때마다 특정 코드를 수행하려면, 캐시가 디스패치하는 다양한 이벤트를 리스닝하면 됩니다.

이벤트 이름
Illuminate\Cache\Events\CacheFlushed
Illuminate\Cache\Events\CacheFlushing
Illuminate\Cache\Events\CacheFlushFailed
Illuminate\Cache\Events\CacheLocksFlushed
Illuminate\Cache\Events\CacheLocksFlushing
Illuminate\Cache\Events\CacheLocksFlushFailed
Illuminate\Cache\Events\CacheHit
Illuminate\Cache\Events\CacheMissed
Illuminate\Cache\Events\ForgettingKey
Illuminate\Cache\Events\KeyForgetFailed
Illuminate\Cache\Events\KeyForgotten
Illuminate\Cache\Events\KeyWriteFailed
Illuminate\Cache\Events\KeyWritten
Illuminate\Cache\Events\RetrievingKey
Illuminate\Cache\Events\RetrievingManyKeys
Illuminate\Cache\Events\WritingKey
Illuminate\Cache\Events\WritingManyKeys

캐시 이벤트는 모든 캐시 작업마다 디스패치되므로, 트래픽이 많은 환경에서는 성능에 영향을 줄 수 있습니다. 특정 캐시 스토어에서 이벤트 디스패치가 필요하지 않다면, config/cache.php 설정 파일에서 해당 스토어의 events 옵션을 false로 지정하여 비활성화할 수 있습니다.

'database' => [ 'driver' => 'database', // ... 'events' => false, ],

이 문서는 Laravel 공식 문서(MIT)를 한국 개발자를 위해 번역·재구성한 것입니다.

번역일: 2026년 7월 22일