본문 바로가기

Redis

번역일: 2026년 6월 20일

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(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 서버 설정에는 이름, 호스트, 포트가 필요합니다. 단, 아래처럼 연결 URL 하나로 대신할 수도 있습니다.

'redis' => [ 'client' => env('REDIS_CLIENT', 'phpredis'), 'options' => [ 'cluster' => env('REDIS_CLUSTER', 'redis'), 'prefix' => env('REDIS_PREFIX', Str::slug(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', ], ],

연결 스킴 설정

기본적으로 Redis 클라이언트는 tcp 스킴으로 연결합니다. TLS/SSL 암호화 연결이 필요하다면 서버 설정 배열에 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 서버를 클러스터로 운영한다면, config/database.phpredis 설정 안에 clusters 키를 추가합니다. 이 키는 기본적으로 존재하지 않으므로 직접 작성해야 합니다.

'redis' => [ 'client' => env('REDIS_CLIENT', 'phpredis'), 'options' => [ 'cluster' => env('REDIS_CLUSTER', 'redis'), 'prefix' => env('REDIS_PREFIX', Str::slug(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 네이티브 클러스터링을 사용합니다. 네이티브 클러스터링은 장애 발생 시 자동으로 페일오버를 처리하므로 일반적으로 권장되는 방식입니다.

Predis를 사용할 경우 클라이언트 사이드 샤딩도 지원하지만, 이 방식은 페일오버를 처리하지 않습니다. 따라서 별도의 기본 데이터 저장소에서 복구 가능한 임시 캐시 데이터에 한정해서 사용하는 것이 적합합니다.

클라이언트 사이드 샤딩을 사용하려면 config/database.php에서 options.cluster 설정을 제거하면 됩니다.

'redis' => [ 'client' => env('REDIS_CLIENT', 'phpredis'), 'clusters' => [ // ... ], // ... ],

Predis

Predis 패키지를 사용하려면 REDIS_CLIENT 환경 변수를 predis로 설정하세요.

'redis' => [ 'client' => env('REDIS_CLIENT', 'predis'), // ... ],

Predis는 기본 설정 외에도 서버별로 추가 연결 파라미터를 지정할 수 있습니다. 필요한 옵션을 config/database.php의 서버 설정 배열에 추가하면 됩니다.

'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와 통신합니다. 사용할 클라이언트는 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의 서버 설정에 필요한 옵션을 추가하면 됩니다.

'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], ], ],

재시도 및 백오프 설정

Redis 서버 연결이 끊어졌을 때 재시도 동작은 retry_interval, max_retries, backoff_algorithm, backoff_base, backoff_cap 옵션으로 제어할 수 있습니다. 지원하는 백오프 알고리즘은 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), ],

Predis 3.4.0 이상에서는 Retry 클래스를 통한 재시도·백오프 설정을 기본 지원합니다. retry 옵션에 NoBackoff, EqualBackoff, ExponentialBackoff 중 하나의 전략을 지정하면 됩니다.

use Predis\Retry; use Predis\Retry\Strategy\ExponentialBackoff; 'default' => [ 'url' => env('REDIS_URL'), // ... 'retry' => new Retry( new ExponentialBackoff( env('REDIS_BACKOFF_BASE', 100), env('REDIS_BACKOFF_CAP', 1000), true, // 지터(jitter) 활성화 ), env('REDIS_MAX_RETRIES', 3) ) ],

Unix 소켓 연결

애플리케이션과 Redis가 같은 서버에 있다면 TCP 대신 Unix 소켓으로 연결하여 오버헤드를 줄일 수 있습니다. REDIS_HOST에 소켓 경로를, REDIS_PORT0을 지정하면 됩니다.

REDIS_HOST=/run/redis/redis.sock REDIS_PORT=0

PhpRedis 직렬화 및 압축

PhpRedis 확장 모듈은 다양한 직렬화 방식과 압축 알고리즘을 지원합니다. Redis 설정의 options 배열에 원하는 옵션을 지정하면 됩니다.

'redis' => [ 'client' => env('REDIS_CLIENT', 'phpredis'), 'options' => [ 'cluster' => env('REDIS_CLUSTER', 'redis'), 'prefix' => env('REDIS_PREFIX', Str::slug(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 서버로 전달됩니다.

다음은 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) ]); } }

인수가 필요한 명령어는 해당 메서드에 그대로 전달하면 됩니다.

use Illuminate\Support\Facades\Redis; Redis::set('name', '홍길동'); $values = Redis::lrange('names', 5, 10);

command 메서드를 사용하면 명령어 이름과 인수 배열을 직접 지정할 수도 있습니다.

$values = Redis::command('lrange', ['name', 5, 10]);

여러 Redis 연결 사용하기

config/database.php에 여러 Redis 연결을 정의한 경우, connection 메서드에 연결 이름을 전달하여 특정 연결 인스턴스를 가져올 수 있습니다.

$redis = Redis::connection('connection-name');

인수 없이 호출하면 기본 연결 인스턴스를 반환합니다.

$redis = Redis::connection();

트랜잭션

Redis 파사드의 transaction 메서드는 Redis의 MULTI / EXEC 명령을 편리하게 래핑해줍니다. 클로저를 인수로 받으며, 클로저 안에서 발행한 모든 Redis 명령은 하나의 원자적 트랜잭션으로 실행됩니다.

use Redis; use Illuminate\Support\Facades; Facades\Redis::transaction(function (Redis $redis) { $redis->incr('user_visits', 1); $redis->incr('total_visits', 1); });

WARNING

Redis 트랜잭션 안에서는 값을 조회해도 즉시 결과를 받을 수 없습니다. 트랜잭션은 클로저 내 모든 명령이 쌓인 뒤 한 번에 원자적으로 실행되기 때문입니다. 실행 도중 중간 값을 읽어야 한다면 아래의 Lua 스크립트 방식을 사용하세요.

Lua 스크립트

eval 메서드를 사용하면 여러 Redis 명령을 하나의 원자적 작업으로 실행하면서, 중간에 Redis 키 값을 읽고 분기 처리하는 것도 가능합니다. 스크립트는 Lua 언어로 작성합니다.

eval 메서드는 순서대로 다음 인수를 받습니다.

  1. Lua 스크립트 문자열
  2. 스크립트가 참조하는 키의 개수 (정수)
  3. 키 이름들
  4. 스크립트 내부에서 사용할 추가 인수 (선택)

아래 예시는 카운터를 증가시키고, 값이 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 명령을 실행해야 할 때, 명령마다 네트워크 왕복이 발생하면 성능 저하로 이어질 수 있습니다. pipeline 메서드를 사용하면 여러 명령을 한 번에 묶어 Redis 서버로 전송할 수 있습니다. 명령은 작성한 순서대로 실행됩니다.

use Redis; use Illuminate\Support\Facades; Facades\Redis::pipeline(function (Redis $pipe) { for ($i = 0; $i < 1000; $i++) { $pipe->set("key:$i", $i); } });

NOTE

트랜잭션(transaction)은 원자성을 보장하지만, 파이프라이닝(pipeline)은 단순히 네트워크 왕복 횟수를 줄이는 최적화 수단입니다. 원자적 실행이 필요하지 않고 성능만 개선하고 싶을 때 파이프라이닝을 사용하세요.

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 = 'Redis 채널 구독'; /** * 콘솔 커맨드 실행 */ 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' => '홍길동' ])); });

와일드카드 구독

psubscribe 메서드를 사용하면 와일드카드 패턴으로 여러 채널을 한 번에 구독할 수 있습니다. 클로저의 두 번째 인수로 실제 채널 이름이 전달됩니다.

Redis::psubscribe(['*'], function (string $message, string $channel) { echo $message; }); Redis::psubscribe(['users.*'], function (string $message, string $channel) { echo $message; });

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

번역일: 2026년 6월 20일