Redis
- In Memory DB.
- Data Structure Store
Cashe
- 나중에 요청된 결과를 DB에 저장 해두었다가 빠르게 제공함
- EX) 팩토리얼 : 20881! 은 20880! 까지 계산해두고 DB에 저장해두었다가 20881!이 계산될때 사용함
CPU Cashe
- Redis는 In memory DB이기 때문에 메모리에 위치함
- DISK에 가가워 질수록 용량은 커지고 속도는 느려짐
- 전체 요청의 80%는 20%의 사용자가 결정함
Cashe 구조
1. webserver는 데이터가 존재하는지 cashe먼저 확인(Redis)
2. cashe에 데이터가 있으면 cashe에서 데이터를 가져옴
3. cashe에 데이터가 없다면 DB(mysql,postgre sql, oracle 등)에서 얻어옴
4. DB에 얻어온 데이터를 cashe에 저장
- INSERT 쿼리 1개를 500번 실행?
- INSERT 쿼리 500개를 1번씩 실행?
5. memory cashe를 이용하게 되면 훨씬 더 빠른 속도로 데이터를 제공할 수 있음
Redis의 사용처
- Remote Data Store => A서버, B서버, C서버 다른서버에서 같은 데이터를 공유하고 싶을때
- 서버한대에서만 필요하다면 전역변수로 설정해서 관리 가능? => Redis 자체가 Atomic을 보장함(싱글 스레드)
주로 많이 쓰이는곳
- 인증토큰 저장 (strings or hash)
- ranking 보드 (sorted set)
- 유저 api limit
- 좌표
하나의 collection 안에 만개 이하의 아이템만 존재해야 성능이 안나빠짐
Redis 운영
- 메모리 관리를 잘하자
- o(n)명령어 주의
- Replication
- 권장설정
1. 메모리 관리를 잘하자
- swap?
- maxmemory = 특정 메모리 이상 사용시 전환
- 적은 메모리를 여러개 사용하는 인스턴스가 안전함 ex) 24gb => 8gb + 8gb + 8gb
- hash
- zipList
2. o관련 명령어 주의
- Redis는 single Thread => 싱글스레드, 싱글스레드는 한번에 1개의 데이터처리 단순 get/set은 초당 10만 TPS이상 가능 그 이상은 CPU에 영향
대표적 O(N)명령어 (한번에 많은 명령어 보내는 명령)
- KEYS
- FLUSHALL,FLUSHDB
- DeleteColletions
Redis Replication
- 여러서버와 DB공유\
- replication of
- slave of
- 모듈러 vs consistant hashing
- sharding 데이터를 어떻게 나눌것인가, 어떻게 찾을것인가
- Range => id를 기준으로 자기보다 큰 range서버로 데이터를 보내고 처리
Redis 세션 설정
const express = require('express');
const session = require('express-session')
app.use(session({
secret: 'session-sercetkey',
resave: false,
saveUninitialized: false,
}));
secret
session에 사용할 암호입니다. 해당 암호는 절대 외부에 공개되어서는 안 되며, 어차피 별도로 사용할 일도 없으니 예측이 전혀 불가능한 암호로 하는 것이 좋습니다.
지금은 편의상 app.js 소스 내에 바로 적었지만, 따로 config 파일같은 곳에 변수로 저장해 사용하는 것이 맞습니다.
resave
true일 경우 클라이언트 요청 시 기존에 있던 session에 변경사항이 없을 경우에도 해당 session을 다시 저장한다.
false일 경우 클라이언트 요청 시 기존에 있던 session에 변경사항이 없으면 해당 session은 그대로 둔다.
기본값은 true입니다.
saveUninitialized
true일 경우 요청 시 session에 저장할 내용이 없더라도 session을 저장한다.
false일 경우 요청 시 session에 저장할 내용이 없으면 session을 저장하지 않는다.
즉, session을 수정하면 저장되고, session을 수정하지 않으면 저장하지 않는다.
공식적으로는 false로 사용할 것을 권유하고 있습니다. 서버의 저장공간도 아낄 수 있습니다.
아마 클라이언트의 서버 접근 횟수를 추적하는 목적으로 true를 사용할 수도 있겠네요.
기본값은 true입니다.
세션에 데이터 저장하기
- express-session 활용
router.post('/login_process', (req, res, next) => {
const post = req.body;
const email = post.email;
const password = post.password;
req.session.is_logined = true;
req.session.ss_email = email;
console.log(req.session);
res.send('res login_process');
});
로그인 체크하기
router.get('/', function(req, res, next) {
// res.render('index', { title: 'Express' });
const is_logined = req.session.is_logined;
const ss_email = req.session.ss_email;
res.render('index', {
title: 'Express',
is_logined: is_logined,
ss_email: ss_email
})
});
로그아웃
router.get('/logout_process', (req, res, next) => {
req.session.destroy(function(err){
res.redirect('/');
});
});
세션 저장하기
- express-session은 기본적으로 메모리 저장소에 세션을 보관함
- 세션이 끊기는걸 방지하기 위해 서버측에 세션을 물리적으로 저장해야함
- session-file-store , express-mysql-session
session-file-store 패키지설치
$ npm install session-file-store
미들웨어 추가
const session = require('express-session')
const FileStore = require('session-file-store')(session)
...
app.use(session({
secret: 'session-secret123!@#',
resave: false,
saveUninitialized: false,
store:new FileStore(),
}));
미들웨어에 스토어 옵션추가
store:new FileStore(),