Redis 실무 활용 사례
7.1 세션 저장소로 Redis 활용하기 (PHP, Python, Node.js 연동)
Redis는 빠르고 효율적인 데이터 저장소로 세션 저장소로 자주 사용됩니다. 웹 애플리케이션에서 사용자 세션 데이터를 Redis에 저장하면, 빠른 속도로 세션을 조회하고 업데이트할 수 있습니다. Redis를 세션 저장소로 사용하는 방법을 PHP, Python, Node.js에서 어떻게 활용할 수 있는지 살펴보겠습니다.
1. PHP에서 Redis 세션 저장소 설정
PHP에서 Redis를 세션 저장소로 사용하려면 php-redis
확장을 설치하고, session.save_handler
를 Redis로 설정하면 됩니다.
sudo apt install php-redis
이후, php.ini
파일에서 다음과 같이 설정합니다:
session.save_handler = redis
session.save_path = "tcp://127.0.0.1:6379"
PHP에서는 기본적으로 $_SESSION
을 사용하여 세션을 처리할 수 있습니다. 이 설정을 통해 Redis에 세션이 저장됩니다.
2. Python에서 Redis 세션 저장소 설정
Python에서는 redis-py
라이브러리를 사용하여 Redis와 연동할 수 있습니다.
pip install redis
Flask와 같은 웹 프레임워크에서는 Flask-Session
을 활용하여 Redis를 세션 저장소로 설정할 수 있습니다.
from flask import Flask, session
from flask_session import Session
import redis
app = Flask(__name__)
app.config['SESSION_TYPE'] = 'redis'
app.config['SESSION_PERMANENT'] = False
app.config['SESSION_USE_SIGNER'] = True
app.config['SESSION_REDIS'] = redis.StrictRedis(host='localhost', port=6379)
Session(app)
3. Node.js에서 Redis 세션 저장소 설정
Node.js에서는 express-session
과 connect-redis
를 사용하여 Redis 세션을 설정할 수 있습니다.
npm install express-session connect-redis redis
그리고 다음과 같이 Redis를 세션 저장소로 설정합니다:
const express = require('express');
const session = require('express-session');
const RedisStore = require('connect-redis')(session);
const redis = require('redis');
const client = redis.createClient();
const app = express();
app.use(session({
store: new RedisStore({ client: client }),
secret: 'secret_key',
resave: false,
saveUninitialized: false
}));
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
7.2 Redis를 캐시(Cache)로 활용하는 방법 (Spring, Django, Express 연동)
Redis는 캐시 저장소로 매우 효율적입니다. 애플리케이션의 성능을 개선하려면 자주 조회되는 데이터를 Redis에 캐시하고, 데이터베이스 조회를 줄여야 합니다.
1. Spring에서 Redis 캐시 사용
Spring에서는 spring-boot-starter-data-redis
를 사용하여 Redis 캐시를 쉽게 설정할 수 있습니다.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
application.properties
에서 Redis 연결 정보를 설정합니다:
spring.redis.host=localhost
spring.redis.port=6379
spring.cache.type=redis
캐시를 사용하려면 @Cacheable
어노테이션을 활용할 수 있습니다:
@Cacheable(value = "items", key = "#itemId")
public Item getItemById(Long itemId) {
return itemRepository.findById(itemId);
}
2. Django에서 Redis 캐시 사용
Django에서는 django-redis
패키지를 사용하여 Redis를 캐시 백엔드로 설정할 수 있습니다.
pip install django-redis
settings.py
에서 캐시 백엔드를 설정합니다:
CACHES = {
'default': {
'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': 'redis://127.0.0.1:6379/1',
'OPTIONS': {
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
}
}
}
3. Express에서 Redis 캐시 사용
Express에서는 redis
패키지와 node-cache
를 사용하여 Redis 캐시를 설정할 수 있습니다.
npm install redis node-cache
Express에서 Redis를 캐시로 설정하는 예시:
const redis = require('redis');
const client = redis.createClient();
app.get('/data', (req, res) => {
client.get('some_key', (err, reply) => {
if (reply) {
return res.json(JSON.parse(reply));
} else {
const data = getDataFromDatabase(); // 예시 데이터베이스 조회
client.setex('some_key', 3600, JSON.stringify(data)); // 1시간 동안 캐시 저장
return res.json(data);
}
});
});
7.3 메시지 큐(Message Queue) 시스템으로 Redis Pub/Sub 활용
Redis는 Pub/Sub 모델을 제공하여 메시지 큐 시스템을 구현할 수 있습니다. 이를 통해 비동기 방식으로 메시지를 처리할 수 있습니다.
1. Redis Pub/Sub 기본 개념
Pub/Sub(Publish/Subscribe)는 메시지를 발행(publish)하고 구독(subscribe)하는 모델입니다. 메시지를 발행한 프로듀서와 이를 구독하는 소비자 간의 통신을 처리할 수 있습니다.
2. Redis Pub/Sub 구현 예시
-
Publisher (메시지 발행자):
const redis = require('redis'); const publisher = redis.createClient(); // 메시지 발행 publisher.publish('news', 'Hello, Redis!');
-
Subscriber (메시지 구독자):
const redis = require('redis'); const subscriber = redis.createClient(); // 채널 구독 subscriber.subscribe('news'); // 메시지 수신 subscriber.on('message', (channel, message) => { console.log(`Received message: ${message} from ${channel}`); });
7.4 Redis를 이용한 Rate Limiting 구현 (API 속도 제한)
API 호출에 대한 속도 제한(Rate Limiting)은 Redis로 효율적으로 구현할 수 있습니다. 사용자가 API를 너무 많이 호출하지 않도록 제한할 수 있습니다.
1. Redis를 활용한 Rate Limiting 구현
API 호출을 제한하기 위해 Redis의 INCR
과 EXPIRE
명령어를 사용할 수 있습니다. 사용자가 API를 호출할 때마다 카운터를 증가시키고, 일정 시간이 지나면 카운터를 리셋합니다.
예시:
const redis = require('redis');
const client = redis.createClient();
const RATE_LIMIT = 5; // 초당 5회 제한
const TIME_WINDOW = 60; // 60초 동안
app.get('/api', (req, res) => {
const userId = req.ip; // 예시로 IP를 사용
const key = `rate_limit:${userId}`;
client.incr(key, (err, count) => {
if (err) {
return res.status(500).send('Internal Server Error');
}
if (count === 1) {
client.expire(key, TIME_WINDOW); // 첫 번째 호출 시 만료 시간 설정
}
if (count > RATE_LIMIT) {
return res.status(429).send('Too Many Requests');
}
res.send('API response');
});
});
7.5 Lua 스크립트 활용 및 트랜잭션 (MULTI
, EXEC
)
Redis에서는 Lua 스크립트를 사용하여 원자적인 작업을 처리할 수 있습니다. 또한, MULTI
와 EXEC
명령어를 사용하여 트랜잭션을 구현할 수 있습니다.
1. Lua 스크립트 예시
Redis에서 Lua 스크립트는 서버에서 실행되므로, 클라이언트와의 네트워크 통신을 최소화할 수 있습니다. 예를 들어, Redis에서 카운터 값을 증가시키는 Lua 스크립트는 다음과 같습니다:
local current = redis.call('GET', KEYS[1])
if current then
return redis.call('SET', KEYS[1], current + 1)
else
return redis.call('SET', KEYS[1], 1)
end
위 스크립트를 실행하려면 EVAL
명령어를 사용합니다:
redis-cli EVAL "local current = redis.call('GET', KEYS[1]) if current then return redis.call('SET', KEYS[1], current + 1) else return redis.call('SET', KEYS[1], 1) end" 1 counter
2. **
트랜잭션 예시**
Redis에서 트랜잭션을 구현하려면 MULTI
, EXEC
명령어를 사용하여 여러 명령어를 원자적으로 실행할 수 있습니다.
const redis = require('redis');
const client = redis.createClient();
client.multi()
.set('key1', 'value1')
.set('key2', 'value2')
.exec((err, replies) => {
if (err) {
console.log('Error:', err);
} else {
console.log('Transaction replies:', replies);
}
});