https://www.youtube.com/watch?v=jgpVdJB2sKQ
이 유튜브 강의를 정리한 내용이다.
redis는 key-value 쌍의 데이터를 저장하는 데이터베이스. 때문에 하나의 거대한 json 객체라고 생각해도 된다.
많은 양의 구조화된 데이터를 저장하기에는 부적절하지만, 각 키에 대한 데이터 정도를 가져오는 형태로 DB를 사용하고자 한다면 좋은 선택지이다.
디스크에 저장하지 않고 메모리(RAM)에 저장한다. 이 특징 때문에 빠른 속도를 기대할 수 있지만, 휘발성 메모리이기 때문에 시스템 오류시 데이터가 삭제될 수 있다.
영구적인 데이터 저장을 위해서 사용하기 보다는 캐시와 같은 특정한 목적을 위해서 사용하는 경우가 많다.
# redis 설치
$ brew install redis
# redis server 실행
$ redis-server
# redis cli 실행 (redis server를 실행시킨 터미널과 다른 터미널에서 실행)
$ redis-cli
명령어는 대소문자를 구분하지 않는다.
띄어쓰기가 없는 문자열은 그대로 사용하면 되지만, 띄어쓰기가 있는 경우 큰따옴표로 묶어주어야 한다.
SET [KEY] [VALUE]
value에 들어가는 내용은 기본적으로 string 타입으로 저장된다.

GET [KEY]
DEL [KEY]
EXISTS [KEY]
존재하는 경우 => 1
존재하지 않는 경우 => 0
KEYS *
전체 키 노출
FLUSHALL
전체 키 삭제
TTL [KEY]
TTL 설정이 되지 않은 경우 => -1
TIME이 끝나서 키가 제거된 경우 => -2
남은 TIME => 0 이상
EXPIRE [KEY] [TIME]
기존에 존재하는 KEY에 TIME 부여
SETEX [KEY] [TIME] [VALUE]
KEY를 생성하면서 TIME 부여
LPUSH [KEY] [VALUE]
자바스크립트의 shift
RPUSH [KEY] [VALUE]
자바스크립트의 push
LPOP [KEY]
자바스크립트의 unshift
RPOP [KEY]
자바스크립트의 pop
LRANGE [KEY] [START INDEX] [END INDEX]
start부터 end까지의 배열 조회
전체 배열 조회 =>
LRANGE [KEY] 0 -1
array와 기능이 거의 동일하지만, value가 유니크하게 관리된다는 특징이 있다.
SADD [KEY] [VALUE]
동일한 VALUE가 존재하지 않는 경우 => 1을 반환하면서 값 설정
동일한 VALUE가 존재하는 경우 => 0을 반환하면서 값 설정 X
SREM [KEY] [VALUE]
KEY에 해당하는 SET에서 VALUE 제거
SMEMBERS [KEY]
KEY에 해당하는 SET 조회
중첩된 형태의 KEY-VALUE 쌍을 저장할 수 있는 데이터 구조
HSET [OBJECT KEY] [KEY] [VALUE]
// HSET person name miro const person = { name: "miro" }
HGET [OBJECT KEY] [KEY]
특정 객체의 KEY 값을 조회
HGETALL [OBJECT KEY]
특정 객체의 모든 KEY, VALUE 출력
HDEL [OBJECT KEY] [KEY]
특정 객체의 KEY 값을 삭제
HEXISTS [OBJECT KEY] [KEY]
특정 객체의 KEY 값이 존재하는지 확인
존재 => 1
존재 X => 0
// 별도의 처리가 없기 때문에 매번 api를 다시 호출한다.
app.get("/photos", async (req, res) => {
const albumId = req.query.albumId;
const { data } = await axios.get("URL", { params: { albumId } });
res.json(data);
})
// redis를 사용하는 예제 (with Cache)
const { createClient } = require('redis');
const client = createClient();
const DEFAULT_EXPIRATION = 3000;
app.get("/photos", async (req, res) => {
const albumId = req.query.albumId;
client.get("photos", async (error, photos) => {
if (error) console.error(error);
if (photos) return res.json(JSON.parse(photos));
const { data } = await axios.get("URL", { params: { albumId } });
client.setex("photos", DEFAULT_EXPIRATION, JSON.stringify(data));
res.json(data);
})
}
// util화 예시
const getOrSetCache = (key, cb) => {
return new Promise((resolve, reject) => {
client.get(key, async (error, data) => {
if (error) return reject(error);
if (data) return resolve(JSON.parse(data));
const refreshData = await cb();
client.setex(key, DEFAULT_EXPIRATION, JSON.stringify(refreshData));
resolve(refreshData);
})
})
};
app.get("/photos", async (req, res) => {
const albumId = req.query.albumId;
const photos = await getOrSetCache("photos", () => {
const { data } = await axios.get("URL", { params: { albumId } });
return data;
})
res.json(photos)
})
ㅋㅋ