파이널 프로젝트 중에, 백엔드 sequelize와 api로 controller 작성 후, 뭘 더할께 없나 찾아보다가 redis라는 걸 알게되었습니다.
redis란 간단하게 말해서 빨리반응하기 위한 데이터베이스 입니다.
좀 더 디테일하게 들어가보겠습니다.
데이터베이스가 있는데도 불구하고 이 redis를 사용하는 이유는, 데이터베이스 부담을 줄여주기 위해서입니다.
redis는 In-Memory 기반 입니다. 이 redis Cache는 여기에 위치합니다.
cache란 나중에 요청할 결과를 미리 저장해둔 후 빠르게 서비스해 주는 걸 의미합니다. 자주 사용하는 걸 cache에 저장함으로써, 데이터베이스의 부담을 줄여주고 더 빨리 반응해줄 수 있는 것입니다.
- 클라이언트 요청을 받은 Web Server는 데이터가 존재하는 지 먼저 Cache를 확인합니다.
- Cache에 데이터가 있다면 Cache에서 가져옵니다.
- Cahce에 데이터가 없다면 DB에 가져온 후 Cache에 다시 저장합니다.
- 클라이언트의 요청을 받은 Web Server는 모든 데이터를 Cache를 저장합니다.
write back은 INSERT 쿼리를 일일히 날리지않고 한꺼번에 처리하기위해 사용합니다. 예를 들어, 영어 듣기 평가를 진행하는 서비스 경우 여러 항시에 동시에 제출버튼을 눌렀을 때, DB에 갑작스럽게 엄청난 요청이 몰리면 DB서버에 부하가 발생하기 떄문에, write back장식을 사용해서 캐시 메모리에 데이터를 저장해놓고, 이후 DB에 디스크 업데이트 하는 것입니다.
DB에 접근하는 횟수가 줄어들지만, DB에 저장하기 전에 캐시 서버가 죽으면 데이터가 유실될 수도 있습니다.
redis와 같이 꼭 나오는게 있는데 Memocache입니다. Memocached는 분산 메모리 캐싱 시스템입니다. Memocaced는 key-value 형태로 메모리에 저장히지만 redis는 Collection을 지원합니다.
String
: 가장 일반적 형태로, key-value로 저장하는 형태입니다.Set
: 중보된 데이터를 담지 않기위해 사용하는 자료구조입니다.List
: Array 형식의 데이터 구조입니다. List를 사용하면 처음과 긑에 데이터를 넣고 빼는 건 속도가 빠르지만 중간에 데이터를 삽입하거나 삭제하는건 어려움이 있습니다.Sorted Set
: 유저 랭킹 보드서버 같은 구현에서 사용할 수 있습니다. 이때 데이터 삽입은 ZADD key 점수 value
명령어로 수행하고 정렬된 값은 zrange
를 통해 가져올 수 있습니다.이런 다양한 구조체를 지원함으로 DB, Cache, Message Queue, Shared Memory용도로 사용될 수 있습니다.
Redis와 Memocache 차이
AOF
Redis의 모든 write/update 연산 자체를 모두 log파일에 기록하는 형태입니다. 서버가 재시작 시 write/update를 순차적으로 재실행하고 데이터를 복구합니다.
Snapshot
RDB와 비슷하게 어떤 특정 시점의 데이터를 Dist에 담는 방식을 뜻합니다. Blocking 방식의 SAVE와 Non-blocking 방식의 BGSAVE 방식이 있습니다.(1) 장점
AOF
Redis의 모든 write/update 연산 자체를 모두 log파일에 기록하는 형태
npm i redis
const express = require('express');
const redis = require('redis');
const axios = require('axios');
const bodyParser = require('body-parser');
// 서비스 포트 선언
const port_redis = 6379;
const port = 3005;
// Redis 포트를 6379로 설정
const redis_client = redis.createClient(port_redis);
// express 서버 설정
const app = express();
// Body Parser 미들웨어
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
// express 서버를 3005번 포트로 실행;
app.listen(port, () => console.log(`Server running on Port ${port}`));
createClient
메서드는 RedisClient 객체를 생성합니다. redis서버와 express 서버가 같은 호스트라면 createClient()
에 별도의 설정을 해주지않아도 됩니다. 만약 호스트가 다르다면 포트 번호드의 설정을 추가해야합니다.
checkCache = (req, res, next) => {
redis_client.get(req.url, (err, data) => {
if (err) {
console.log(err);
res.status(500).send(err);
}
// Redis에 저장된게 존재한다.
if (data != null) {
res.send(data);
} else {
// Redis에 저장된게 없기 때문에 다음 로직 실행
next();
}
});
};
미들웨어 형태로 만들어서 매 요청마다 캐시가 있는지 없는지 체크하여 Redis 값을 꺼내어 줄 수 있습니다.
express-session
connect-redis
const session = require('express-session');
const redis = require('redis');
const redisStore = require('connect-redis')(session);
const client = redis.createClient();
app.use(session({
store: new redisStore({
client: redis,
host: 'localhost',
port: 6379,
prefix : "session:",
db : 0,
saveUninitialized: false,
resave: false
}),
secret: "secret_key",
cookie: { maxAge: 3000 }
}));
client.set('key', 'value');
client.get('key', (err) => {
});
set으로 설정하고 get으로 key-value값을 가져올 수 있습니다.
https://velog.io/@hyeondev/Redis-%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C
https://rlawls1991.tistory.com/entry/Redis%EB%9E%80
https://steady-coding.tistory.com/586
https://goodgid.github.io/Redis/
https://haeunyah.tistory.com/78
https://charming-kyu.tistory.com/37
https://azderica.github.io/01-db-nosql-redis/