Redis
업데이트됨번역일: 2026년 9월 29일
이 페이지는 원문이 업데이트되어 번역이 갱신되었습니다.
- 원문 수정
- 2026년 9월 29일
- 번역 갱신
- 2026년 9월 29일
Redis
소개
Redis는 오픈소스로 제공되는 고급 키-값 저장소입니다. 키에 문자열, 해시, 리스트, 셋, 정렬된 셋 등 다양한 자료구조를 저장할 수 있어 흔히 "데이터 구조 서버"라고도 불립니다.
Laravel에서 Redis를 사용하기 전에, PECL을 통해 PhpRedis PHP 확장 모듈을 설치해서 사용하는 것을 권장합니다. 이 확장 모듈은 순수 PHP로 작성된 패키지보다 설치가 다소 복잡하지만, Redis를 활발히 사용하는 애플리케이션에서는 더 나은 성능을 기대할 수 있습니다. Laravel Sail을 사용 중이라면 애플리케이션의 Docker 컨테이너에 이 확장 모듈이 이미 설치되어 있습니다.
PhpRedis 확장 모듈을 설치할 수 없는 환경이라면, Composer를 통해 predis/predis 패키지를 설치해도 됩니다. Predis는 순수 PHP로 작성된 Redis 클라이언트로, 별도의 확장 모듈 설치 없이 사용할 수 있습니다:
composer require predis/predis설정
애플리케이션의 Redis 설정은 config/database.php 설정 파일에서 관리합니다. 이 파일에는 애플리케이션이 사용할 Redis 서버 정보를 담은 redis 배열이 있습니다:
'redis' => [
'client' => env('REDIS_CLIENT', 'phpredis'),
'options' => [
'cluster' => env('REDIS_CLUSTER', 'redis'),
'prefix' => env('REDIS_PREFIX', Str::slug((string) env('APP_NAME', 'laravel')).'-database-'),
],
'default' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'username' => env('REDIS_USERNAME'),
'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_DB', '0'),
],
'cache' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'username' => env('REDIS_USERNAME'),
'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_CACHE_DB', '1'),
],
],설정 파일에 정의하는 각 Redis 서버는 이름, 호스트, 포트를 지정해야 합니다. 다만 Redis 연결 정보를 하나의 URL로 표현하는 경우는 예외입니다:
'redis' => [
'client' => env('REDIS_CLIENT', 'phpredis'),
'options' => [
'cluster' => env('REDIS_CLUSTER', 'redis'),
'prefix' => env('REDIS_PREFIX', Str::slug((string) env('APP_NAME', 'laravel')).'-database-'),
],
'default' => [
'url' => 'tcp://127.0.0.1:6379?database=0',
],
'cache' => [
'url' => 'tls://user:password@127.0.0.1:6380?database=1',
],
],연결 스킴(Scheme) 설정하기
Redis 클라이언트는 기본적으로 Redis 서버에 연결할 때 tcp 스킴을 사용합니다. TLS / SSL 암호화를 사용하고 싶다면 Redis 서버 설정 배열에 scheme 옵션을 지정하면 됩니다:
'default' => [
'scheme' => 'tls',
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'username' => env('REDIS_USERNAME'),
'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_DB', '0'),
],클러스터
애플리케이션이 여러 대의 Redis 서버로 구성된 클러스터를 사용한다면, Redis 설정의 clusters 키 아래에 이 클러스터 정보를 정의해야 합니다. 이 설정 키는 기본적으로 존재하지 않으므로 config/database.php 파일에 직접 추가해야 합니다:
'redis' => [
'client' => env('REDIS_CLIENT', 'phpredis'),
'options' => [
'cluster' => env('REDIS_CLUSTER', 'redis'),
'prefix' => env('REDIS_PREFIX', Str::slug((string) env('APP_NAME', 'laravel')).'-database-'),
],
'clusters' => [
'default' => [
[
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'username' => env('REDIS_USERNAME'),
'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_DB', '0'),
],
],
],
// ...
],options.cluster 설정 값이 기본적으로 redis로 지정되어 있기 때문에, Laravel은 기본적으로 Redis의 네이티브 클러스터링 기능을 사용합니다. Redis 클러스터링은 장애 조치(failover)를 매끄럽게 처리해주므로 대부분의 경우 좋은 기본 선택지입니다.
Laravel은 Predis를 사용할 때 클라이언트 사이드 샤딩(client-side sharding)도 지원합니다. 다만 클라이언트 사이드 샤딩은 장애 조치를 처리하지 못하므로, 다른 주 데이터 저장소에서 언제든 다시 가져올 수 있는 일시적인 캐시 데이터에 주로 적합합니다.
네이티브 Redis 클러스터링 대신 클라이언트 사이드 샤딩을 사용하고 싶다면, config/database.php 파일에서 options.cluster 설정 값을 제거하면 됩니다:
'redis' => [
'client' => env('REDIS_CLIENT', 'phpredis'),
'clusters' => [
// ...
],
// ...
],Predis
Predis 패키지를 통해 Redis와 통신하고 싶다면, REDIS_CLIENT 환경 변수 값을 predis로 설정해야 합니다:
'redis' => [
'client' => env('REDIS_CLIENT', 'predis'),
// ...
],기본 설정 옵션 외에도, Predis는 각 Redis 서버에 대해 추가로 연결 파라미터를 지정할 수 있도록 지원합니다. 이러한 추가 옵션을 사용하려면 config/database.php 파일의 Redis 서버 설정에 다음과 같이 추가하면 됩니다:
'default' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'username' => env('REDIS_USERNAME'),
'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_DB', '0'),
'read_write_timeout' => 60,
],PhpRedis
Laravel은 기본적으로 PhpRedis 확장 모듈을 사용해 Redis와 통신합니다. Laravel이 사용할 클라이언트는 redis.client 설정 값에 따라 결정되며, 이 값은 보통 REDIS_CLIENT 환경 변수 값을 그대로 반영합니다:
'redis' => [
'client' => env('REDIS_CLIENT', 'phpredis'),
// ...
],기본 설정 옵션 외에도, PhpRedis는 다음과 같은 추가 연결 파라미터를 지원합니다: name, persistent, persistent_id, prefix, read_timeout, retry_interval, max_retries, backoff_algorithm, backoff_base, backoff_cap, timeout, context. 이 옵션들은 config/database.php 파일의 Redis 서버 설정에 자유롭게 추가할 수 있습니다:
'default' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'username' => env('REDIS_USERNAME'),
'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_DB', '0'),
'read_timeout' => 60,
'context' => [
// 'auth' => ['username', 'secret'],
// 'stream' => ['verify_peer' => false],
],
],재시도 및 백오프(Backoff) 설정
retry_interval, max_retries, backoff_algorithm, backoff_base, backoff_cap 옵션을 사용하면 PhpRedis 클라이언트가 Redis 서버에 재연결을 시도하는 방식을 세밀하게 조정할 수 있습니다. 지원되는 백오프 알고리즘은 default, decorrelated_jitter, equal_jitter, exponential, uniform, constant입니다:
'default' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'username' => env('REDIS_USERNAME'),
'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_DB', '0'),
'max_retries' => env('REDIS_MAX_RETRIES', 3),
'backoff_algorithm' => env('REDIS_BACKOFF_ALGORITHM', 'decorrelated_jitter'),
'backoff_base' => env('REDIS_BACKOFF_BASE', 100),
'backoff_cap' => env('REDIS_BACKOFF_CAP', 1000),
],Laravel은 일시적인 연결 오류가 발생하면 안전한(읽기 전용) 명령어에 한해 자동으로 한 번 재시도합니다. 모든 Redis 명령어에 대한 재시도 횟수를 조정하고 싶다면 command_retries 옵션을 사용하세요:
'default' => [
// ...
'command_retries' => env('REDIS_COMMAND_RETRIES', 0),
],Predis 3.4.0 이상 버전에서는 Retry 클래스를 통해 재시도 및 백오프 설정을 내장 기능으로 지원합니다. max_retries 옵션으로 재시도 횟수를, retry 옵션으로 백오프 전략을 설정할 수 있습니다. retry 옵션은 다음 전략 클래스 중 하나를 키로 갖는 배열이어야 합니다: NoBackoff, EqualBackoff, ExponentialBackoff:
use Predis\Retry\Strategy\ExponentialBackoff;
'default' => [
'url' => env('REDIS_URL'),
// ...
'retry' => [
ExponentialBackoff::class => [
env('REDIS_BACKOFF_BASE', 100),
env('REDIS_BACKOFF_CAP', 1000),
true, // 지터(jitter) 활성화...
],
],
'max_retries' => env('REDIS_MAX_RETRIES', 3),
],Redis 클러스터와 함께 Predis를 사용하는 경우, 클러스터 설정의 parameters 옵션 안에 재시도 설정을 정의할 수 있습니다:
use Predis\Retry\Strategy\NoBackoff;
'clusters' => [
'default' => [
// ...
],
],
'options' => [
'cluster' => env('REDIS_CLUSTER', 'redis'),
'parameters' => [
'retry' => [
NoBackoff::class => [],
],
'max_retries' => env('REDIS_MAX_RETRIES', 3),
],
],유닉스 소켓 연결
Redis 연결은 TCP 대신 유닉스 소켓을 사용하도록 설정할 수도 있습니다. 애플리케이션과 같은 서버에 Redis 인스턴스가 있는 경우, TCP 오버헤드를 없애 성능을 개선할 수 있습니다. 유닉스 소켓을 사용하려면 REDIS_HOST 환경 변수에 Redis 소켓 경로를 지정하고, REDIS_PORT 환경 변수를 0으로 설정하면 됩니다:
REDIS_HOST=/run/redis/redis.sock
REDIS_PORT=0PhpRedis 직렬화와 압축
PhpRedis 확장 모듈은 다양한 직렬화(serializer) 방식과 압축 알고리즘도 지원합니다. 이러한 알고리즘은 Redis 설정의 options 배열을 통해 설정할 수 있습니다:
'redis' => [
'client' => env('REDIS_CLIENT', 'phpredis'),
'options' => [
'cluster' => env('REDIS_CLUSTER', 'redis'),
'prefix' => env('REDIS_PREFIX', Str::slug((string) env('APP_NAME', 'laravel')).'-database-'),
'serializer' => Redis::SERIALIZER_MSGPACK,
'compression' => Redis::COMPRESSION_LZ4,
],
// ...
],현재 지원되는 직렬화 방식은 다음과 같습니다: Redis::SERIALIZER_NONE(기본값), Redis::SERIALIZER_PHP, Redis::SERIALIZER_JSON, Redis::SERIALIZER_IGBINARY, Redis::SERIALIZER_MSGPACK.
지원되는 압축 알고리즘은 다음과 같습니다: Redis::COMPRESSION_NONE(기본값), Redis::COMPRESSION_LZF, Redis::COMPRESSION_ZSTD, Redis::COMPRESSION_LZ4.
Redis 사용하기
Redis 파사드의 다양한 메서드를 호출해서 Redis와 상호작용할 수 있습니다. Redis 파사드는 동적 메서드 호출을 지원하므로, 어떤 Redis 명령어든 파사드에서 그대로 호출하면 됩니다. 호출한 명령어는 그대로 Redis 서버에 전달됩니다. 다음 예시는 Redis 파사드의 get 메서드를 호출해 Redis의 GET 명령어를 실행하는 예시입니다:
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Redis;
use Illuminate\View\View;
class UserController extends Controller
{
/**
* 지정된 사용자의 프로필을 보여줍니다.
*/
public function show(string $id): View
{
return view('user.profile', [
'user' => Redis::get('user:profile:'.$id)
]);
}
}위에서 언급했듯, Redis 파사드에서는 Redis의 어떤 명령어든 호출할 수 있습니다. Laravel은 매직 메서드를 이용해 이러한 명령어 호출을 Redis 서버로 전달합니다. Redis 명령어가 인자를 필요로 한다면 해당 파사드 메서드에 그대로 전달하면 됩니다:
use Illuminate\Support\Facades\Redis;
Redis::set('name', 'Taylor');
$values = Redis::lrange('names', 5, 10);또는, Redis 파사드의 command 메서드를 사용해 명령어를 전달할 수도 있습니다. 이 메서드는 첫 번째 인자로 명령어 이름을, 두 번째 인자로 값의 배열을 받습니다:
$values = Redis::command('lrange', ['name', 5, 10]);여러 개의 Redis 연결 사용하기
config/database.php 설정 파일을 통해 여러 개의 Redis 연결(서버)을 정의할 수 있습니다. 특정 Redis 연결의 인스턴스를 가져오려면 Redis 파사드의 connection 메서드를 사용하세요:
$redis = Redis::connection('connection-name');기본 Redis 연결의 인스턴스를 가져오려면 인자 없이 connection 메서드를 호출하면 됩니다:
$redis = Redis::connection();트랜잭션
Redis 파사드의 transaction 메서드는 Redis의 네이티브 MULTI, EXEC 명령어를 편리하게 감싼 래퍼입니다. transaction 메서드는 유일한 인자로 클로저를 받습니다. 이 클로저는 Redis 연결 인스턴스를 전달받으며, 이 인스턴스를 통해 원하는 명령어를 자유롭게 실행할 수 있습니다. 클로저 안에서 실행한 모든 Redis 명령어는 하나의 원자적(atomic) 트랜잭션으로 처리됩니다:
use Redis;
use Illuminate\Support\Facades;
Facades\Redis::transaction(function (Redis $redis) {
$redis->incr('user_visits', 1);
$redis->incr('total_visits', 1);
});WARNING
Redis 트랜잭션을 정의할 때는 Redis 연결에서 값을 조회할 수 없습니다. 트랜잭션은 하나의 원자적 연산으로 실행되며, 클로저 안의 모든 명령어 실행이 끝나야만 실제 연산이 수행되기 때문입니다.
Lua 스크립트
eval 메서드는 여러 Redis 명령어를 하나의 원자적 연산으로 실행하는 또 다른 방법입니다. transaction 메서드와 달리, eval 메서드는 연산 도중 Redis 키의 값을 조회하고 그 값을 바탕으로 로직을 분기할 수 있다는 장점이 있습니다. Redis 스크립트는 Lua 프로그래밍 언어로 작성합니다.
eval 메서드는 처음 접하면 다소 낯설게 느껴질 수 있지만, 간단한 예시로 차근차근 살펴보겠습니다. eval 메서드는 여러 인자를 받습니다. 첫 번째 인자로는 Lua 스크립트(문자열)를, 두 번째 인자로는 스크립트가 다루는 키의 개수(정수)를, 세 번째 인자로는 해당 키들의 이름을 전달합니다. 마지막으로, 스크립트 안에서 사용할 추가 인자가 있다면 이어서 전달하면 됩니다.
다음 예시는 카운터 값을 하나 증가시킨 뒤 그 값을 확인하고, 만약 첫 번째 카운터 값이 5보다 크면 두 번째 카운터도 증가시킵니다. 마지막으로 첫 번째 카운터의 값을 반환합니다:
$value = Redis::eval(<<<'LUA'
local counter = redis.call("incr", KEYS[1])
if counter > 5 then
redis.call("incr", KEYS[2])
end
return counter
LUA, 2, 'first-counter', 'second-counter');WARNING
Redis 스크립팅에 대한 더 자세한 내용은 Redis 공식 문서를 참고하세요.
명령어 파이프라이닝
때로는 수십 개의 Redis 명령어를 연달아 실행해야 할 때가 있습니다. 이럴 때 명령어 하나하나마다 Redis 서버로 네트워크 요청을 보내는 대신, pipeline 메서드를 사용할 수 있습니다. pipeline 메서드는 Redis 인스턴스를 전달받는 클로저를 인자로 받습니다. 이 Redis 인스턴스에 원하는 명령어를 모두 실행하면, 해당 명령어들이 한 번에 Redis 서버로 전송되어 네트워크 왕복 횟수를 줄일 수 있습니다. 명령어는 실행한 순서대로 처리됩니다:
use Redis;
use Illuminate\Support\Facades;
Facades\Redis::pipeline(function (Redis $pipe) {
for ($i = 0; $i < 1000; $i++) {
$pipe->set("key:$i", $i);
}
});Pub / Sub
Laravel은 Redis의 publish, subscribe 명령어를 편리하게 사용할 수 있는 인터페이스를 제공합니다. 이 명령어들을 이용하면 특정 "채널"에서 발행되는 메시지를 수신 대기할 수 있습니다. 다른 애플리케이션에서, 혹은 완전히 다른 프로그래밍 언어로 작성된 애플리케이션에서도 해당 채널로 메시지를 발행할 수 있어, 애플리케이션과 프로세스 간의 통신을 손쉽게 구현할 수 있습니다.
먼저 subscribe 메서드를 이용해 채널 리스너를 만들어 보겠습니다. subscribe 메서드는 호출되면 오랫동안 실행 상태를 유지하는 프로세스이므로 Artisan 명령어 안에 작성하는 것이 일반적입니다:
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Redis;
class RedisSubscribe extends Command
{
/**
* 콘솔 명령어의 이름 및 시그니처.
*
* @var string
*/
protected $signature = 'redis:subscribe';
/**
* 콘솔 명령어 설명.
*
* @var string
*/
protected $description = 'Subscribe to a Redis channel';
/**
* 콘솔 명령어를 실행합니다.
*/
public function handle(): void
{
Redis::subscribe(['test-channel'], function (string $message) {
echo $message;
});
}
}이제 publish 메서드를 사용해 해당 채널로 메시지를 발행할 수 있습니다:
use Illuminate\Support\Facades\Redis;
Route::get('/publish', function () {
// ...
Redis::publish('test-channel', json_encode([
'name' => 'Adam Wathan'
]));
});와일드카드 구독
psubscribe 메서드를 사용하면 와일드카드 채널을 구독할 수 있습니다. 모든 채널에서 발행되는 모든 메시지를 한꺼번에 받아야 할 때 유용합니다. 이 경우 채널 이름은 전달된 클로저의 두 번째 인자로 함께 넘어옵니다:
Redis::psubscribe(['*'], function (string $message, string $channel) {
echo $message;
});
Redis::psubscribe(['users.*'], function (string $message, string $channel) {
echo $message;
});