Redis
번역일: 2026년 6월 20일
Redis
소개
Redis는 오픈 소스 고성능 키-값 저장소입니다. 키에 문자열, 해시, 리스트, 셋, 정렬된 셋 등 다양한 자료구조를 저장할 수 있어 "데이터 구조 서버"라고도 불립니다.
Laravel에서 Redis를 사용하기 전에, PECL을 통해 PhpRedis PHP 확장을 설치하는 것을 권장합니다. 순수 PHP로 작성된 패키지보다 설치 과정이 다소 복잡하지만, Redis를 많이 사용하는 애플리케이션에서 더 나은 성능을 기대할 수 있습니다. Laravel Sail을 사용 중이라면 Docker 컨테이너에 이미 설치되어 있습니다.
PhpRedis 확장을 설치하기 어려운 경우, Composer를 통해 predis/predis 패키지를 설치할 수 있습니다. Predis는 순수 PHP로 작성된 Redis 클라이언트로, 별도의 PHP 확장이 필요하지 않습니다:
composer require predis/predis:^2.0설정
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.php의 Redis 설정 안에 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 클러스터링을 사용합니다. 네이티브 클러스터링은 장애 조치(failover)를 자동으로 처리하므로 프로덕션 환경에 적합한 선택입니다.
Predis를 사용할 때는 클라이언트 측 샤딩(client-side sharding)도 지원하지만, 이 방식은 장애 조치를 지원하지 않습니다. 따라서 다른 주 데이터 저장소에서 쉽게 복구 가능한 임시 캐시 데이터에만 주로 활용합니다.
클라이언트 측 샤딩을 사용하려면 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의 서버 설정에 추가하면 됩니다:
'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.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],
],
],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 서버에 전달됩니다. 아래 예시는 Redis 파사드의 get 메서드를 통해 Redis GET 명령을 실행합니다:
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
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 파사드에서 메서드로 호출할 수 있습니다. 명령어에 인수가 필요하다면 해당 메서드에 그대로 넘기면 됩니다:
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 스크립트
eval 메서드를 사용하면 여러 Redis 명령을 단일 원자적 작업으로 실행하면서, 실행 도중 Redis 키 값을 읽거나 조작하는 것도 가능합니다. Redis 스크립트는 Lua 언어로 작성합니다.
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 명령을 실행할 때 명령마다 네트워크 왕복이 발생합니다. 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;
});