Skip to main content

캐시란

데이터베이스에의 질의나 외부 API의 호출은 CPU나 네트워크의 비용이 높아 처리에 수 초가 걸리는 경우가 있습니다. 같은 데이터를 몇 번이고 취득하는 경우, 결과를 캐시에 보존해 둠으로써 다음 번 이후의 요청을 고속으로 처리할 수 있습니다. Laravel은 Memcached, Redis, DynamoDB, 데이터베이스 등, 다양한 캐시 백엔드에 대응한 통합 API를 제공하고 있습니다.
기본적으로는 database 드라이버가 설정되어 있습니다. Redis나 Memcached로 전환함으로써 더욱 고속의 캐시를 실현할 수 있습니다.

캐시 설정

config/cache.php

캐시 설정은 config/cache.php에 집약되어 있습니다. CACHE_STORE 환경 변수로 기본 드라이버를 전환합니다.

사용 가능한 드라이버

직렬화된 캐시 데이터를 데이터베이스 테이블에 저장합니다. Laravel 11 이후의 신규 프로젝트에는 처음부터 마이그레이션이 포함되어 있습니다.
마이그레이션이 포함되어 있지 않은 경우 Artisan 명령어로 작성합니다.
캐시 데이터를 파일시스템에 저장합니다. 추가의 셋업은 불필요하며, 소규모 애플리케이션에 적합합니다.
인메모리로 동작하는 고속의 캐시 드라이버입니다. 운영 환경에서 가장 자주 사용됩니다. PhpRedis PHP 확장 또는 predis/predis 패키지가 필요합니다.
Memcached PECL 패키지가 필요합니다. config/cache.php에서 서버를 설정합니다.
AWS DynamoDB를 캐시 스토어로 사용합니다. 사전에 DynamoDB 테이블을 작성하고 AWS SDK를 설치합니다.
임의의 파일시스템 디스크를 키/값의 캐시 스토어로 사용합니다. 기존의 S3 디스크를 그대로 캐시로 사용하고 싶은 경우에 편리합니다.
array는 요청 내에서만 유효한 인메모리 캐시입니다. null은 모든 조작을 무시합니다. 둘 다 자동 테스트에서 편리합니다.

캐시 드라이버의 계층 구조

용도나 속도에 따라 드라이버를 구분해서 사용합니다.

기본적인 조작

Cache 파사드 취득

Cache 파사드를 사용해 캐시를 조작합니다.
여러 캐시 스토어를 구분해서 사용하려면 store() 메서드를 사용합니다.

데이터 취득: Cache::get()

get() 메서드로 캐시에서 데이터를 취득합니다. 캐시가 존재하지 않는 경우 null을 반환합니다. 기본값을 지정할 수도 있습니다.

데이터 저장: Cache::put()

put() 메서드로 데이터를 캐시에 저장합니다. 세 번째 인수에 유효 기간(초)을 지정합니다.
캐시가 존재하지 않는 경우에만 저장하는 add() 메서드도 있습니다.
영구적으로 저장하려면 forever()를 사용합니다.

취득 또는 저장: Cache::remember()

가장 자주 사용되는 조작입니다. 캐시에 데이터가 존재하면 그것을 반환하고, 없으면 클로저를 실행하여 그 결과를 저장합니다.
Cache::remember()를 사용함으로써 “캐시 확인 → 없으면 취득 → 캐시에 저장”이라는 3단계를 한 줄로 쓸 수 있습니다. 데이터베이스 쿼리 결과나 외부 API 응답의 캐시에 최적입니다.

remember() 의 플로우

영구 저장 버전의 rememberForever()도 있습니다.
캐시가 “히트”했는지, 클로저에서 새로 취득되었는지를 알고 싶은 경우 rememberWithWarmth() 메서드를 사용합니다. 이 메서드는 캐시 값과 그것이 신선한지(캐시에서 취득)를 나타내는 진위값을 배열로 반환합니다.
rememberWithWarmth()는 캐시의 효율성을 감시하고 싶은 경우에 편리합니다. $warm이 false인 경우가 많다면 캐시의 유효 기간(TTL)을 조정함으로써 개선할 수 있을지도 모릅니다.

Stale While Revalidate(유연한 캐시 업데이트)

Cache::flexible()은 캐시가 “신선한 기간”과 “오래되어도 사용할 수 있는 기간”을 배열로 지정합니다. 오래된 데이터를 사용자에게 반환하면서 백그라운드에서 캐시를 업데이트하는 패턴입니다.

존재 확인: Cache::has()

값의 인크리먼트 / 디크리먼트

정수값의 카운터를 조작할 수 있습니다.

취득과 삭제: Cache::pull()

취득 후에 캐시에서 삭제합니다. 원타임 데이터의 관리에 편리합니다.

데이터 삭제: Cache::forget()

Cache::flush()는 캐시의 “프리픽스” 설정과 관계없이 모든 엔트리를 삭제합니다. 여러 애플리케이션이 공유하고 있는 캐시의 경우 주의해 주십시오.
Cache::flushLocks()를 사용하면 캐시 내의 모든 원자 락을 클리어할 수 있습니다.

TTL 의 연장: Cache::touch()

기존 캐시 아이템의 유효 기간을 연장합니다.

캐시 메모화

memo 드라이버를 사용하면 동일 요청 내에서의 캐시 접근을 메모리에 캐시합니다. 같은 키에의 반복 접근이 많은 경우, 캐시 스토어에의 라운드트립을 삭감할 수 있습니다.

캐시 태그

관련된 캐시 아이템을 태그로 그룹화하여 함께 삭제할 수 있습니다.
캐시 태그는 file, dynamodb, database, storage 드라이버에서는 사용할 수 없습니다. redismemcached 드라이버가 필요합니다.

태그 부착 캐시의 구조

여러 태그를 붙인 캐시 아이템은 어느 태그로든 함께 삭제할 수 있습니다.

태그 부착 캐시의 저장과 취득

태그 부착 캐시의 삭제

사용자별이나 기사별 등, 그룹 단위로 캐시를 무효화하고 싶은 경우에 태그가 도움이 됩니다. 예: Cache::tags(['user', "user:{$userId}"])->flush()로 그 사용자에 관한 모든 캐시를 클리어할 수 있습니다.

원자 조작(락)

Cache::lock()을 사용하면 분산 락을 구현할 수 있으며, 여러 프로세스나 병렬 요청으로부터의 경합 상태를 방지합니다.
이 기능은 memcached, redis, dynamodb, database, file, array 캐시 드라이버에서 이용할 수 있습니다. 모든 서버가 같은 중앙 캐시 서버와 통신하고 있어야 합니다.

기본적인 락

클로저를 전달하면 처리 완료 후에 자동으로 락을 해방합니다.

락 대기

락을 취득할 수 있을 때까지 최대 지정 초 수 대기합니다. 타임아웃되면 LockTimeoutException이 던져집니다.
클로저를 사용하면 단순하게 쓸 수 있습니다.

중복 실행 방지: withoutOverlapping()

동일 처리의 다중 실행을 방지하는 단순한 방법입니다.

동시 실행 수 제한: funnel()

동시에 실행할 수 있는 처리 수를 제한합니다.

프로세스 간에서의 락 이양

Web 요청에서 락을 취득하고 큐 잡에서 해방하는 케이스입니다.
현재의 오너에 관계없이 락을 강제 해방하려면 forceRelease 메서드를 사용합니다.

락 리프레시

현재 보유하고 있는 락의 유효 기간을 연장하려면 refresh 메서드를 사용합니다. 초 수를 지정하지 않는 경우는 락 취득 시의 원래 유효 기간이 사용됩니다. 장시간 처리에서 짧은 락을 정기적으로 연장하고 싶은 경우에 편리하며, 처음부터 매우 긴 유효 기간을 설정할 필요가 없어집니다.

캐시 헬퍼

cache() 헬퍼 함수를 사용하면 Cache 파사드와 같은 조작을 보다 단순하게 쓸 수 있습니다.

실전 예시

데이터베이스 쿼리 결과의 캐시

1

컨트롤러에서 쿼리 결과를 캐시

2

데이터가 업데이트되면 캐시를 삭제

Eloquent 모델의 캐시

API 응답의 캐시

캐시 태그를 사용한 그룹 관리

정리

  • 개발·소규모: file 또는 database
  • 운영·고트래픽: redis(Laravel Horizon과 조합하면 감시도 용이)
  • AWS 환경: dynamodb 또는 storage(S3 디스크를 유용하는 경우)
  • 테스트: array 또는 null
  • 캐시 키는 앱 전체에서 유니크해지도록 명명한다(예: users:1:profile)
  • 데이터가 업데이트되면 Cache::forget() 또는 Cache::tags()->flush()로 캐시를 무효화한다
  • 캐시의 TTL은 너무 짧지도 너무 길지도 않도록, 데이터의 업데이트 빈도에 맞춰 설정한다
  • Cache::remember()를 사용함으로써 캐시 미스 시의 처리를 간결하게 쓸 수 있다
  • 운영 환경에서는 Redis를 사용하고 페일오버 설정도 검토한다
마지막 수정일 2026년 7월 13일