본문 바로가기
🌱 Computer Science/Database

[Redis] 레디스와 캐시 그리고 데이터구조

by 카프리썬_ 2022. 2. 7.
728x90
728x90

이번에 회사에서 프로젝트를 맡으면서 redis를 접할기회가 생겼다. 근데 익숙하지 않은 데이터베이스라서 한번 정리해보려고 한다. 

그리고 시작하기 전에 레디스를 살펴볼 gui툴로 medis도 설치했다.

2022.02.06 - Mac M1에서 가능한 Redis GUI Client 프로그램 : Medis2

 

반응형

지금까지 레디스를 단순히 캐쉬용으로 쓰이는 데이터베이스라고만 알고 있었다. 

이번기회에 캐쉬용이 어떤건지, 그래서 레디스가 어떤 특징이 있는지 자세히 알아보려고 한다.


Cache

나중에 요청할 결과를 미리 저장해둔 후 빠르게 서비스해주는 것

즉, 미리 결과를 저장하고 나중에 요청이 오면 그 요청에 대해서 DB 또는 API를 참조하지 않고 캐시에 접근해서 요청을 처리하는 것.

예를 들어, 캐쉬는 아래와 같은 flow로 동작한다.

  • 클라이언트로부터 요청을 받는다.
  • 캐쉬와 작업을 한다.  -> 즉, 캐쉬에서 이미 들어왔던 작업인지 확인
  • 실제 db와 작업한다 -> 캐쉬에 잇으면 캐쉬내용 리턴, 없으면 디비접근
  • 다시 캐쉬와 작업한다 -> 디비접근했으니까 한번들어온거라서 캐쉬에 저장

 

Redis

Redis란 REmote DIctionary Server의 약자다. 직역하면 '원격 사전 서버'이다. 

사전은 단어에 대한 의미를 보여주는 것인데, 즉 key(단어),value(의미)형태로 데이터가 저장되어 있는 원격서버라고 볼 수 있다. 

  • in-memory 데이터베이스로 read/write가 빠른 NoSQL 
  • 영속성(Persistence) 지원해서 서버가 꺼지더라도 다시 데이터를 불러들일 수 있다.
  • key-value 형태로 데이터를 저장해서 별도의쿼리 없이 key로 value를 찾을 수 있다.
  • Single Thread로 원자성(Atomic)을 보장하기 때문에 Race Condition 발생가능성이 낮다.
  • 마스터-슬레이브 아키텍쳐를 사용해서 비동기식 복제지원 -> 슬레이브 서버에 복제될 수 있어서 분산지원
  • 데이터구조(Collection) : String, List, Set, Sorted Set, Hash

미리 읽어두었다가 요청이 올 경우 빠르게 응답 하기 위한 '캐쉬'용으로 사용할 수 있다.

이 경우 전체 데이터가 필요없고, 데이터가 항상 유지될 필요가 없기 때문에 redis 같은 적은 공간의 데이터베이스가 최적이다.

 

또한 메모리기반의 디비이기 때문에 get,put을 이용해서 데이터를 넣고 뺄 수 있다. 

redis의 경우 value가 단순한 object가 아니라 여러가지 자료구조를 갖는게 특징이다. 

 

728x90

Redis 자료구조 

String

단순한 key-value 1:1 매핑구조 

  • get : key에 해당하는 value 리턴
  • set : key에 value저장
  • del : key 삭제 

명령어 사용 예시 보기

더보기
127.0.0.1:6379> get a //key'a'의 value조회
(nil) 
127.0.0.1:6379> set a b //key'a'에 value로 'b' 저장
OK
127.0.0.1:6379> get a //key'a'의 value조회
"b"
127.0.0.1:6379> del a //key'a' 삭제-> 삭제한 갯수 반환
(integer) 1

List

순서가 있는 String의 묶음

array 형식의 데이터구조 (자바의 linked list와 유사)

처음(first)과 끝(last)에 데이터 삽입/삭제는 빠르지만, 중간에 데이터를 삽입할때 어려움

  • lpush <key> <value> : left 즉, 첫번째(index:0)에 데이터삽입
  • rpush <key> <value> : right 즉, 마지막(index:-1)에 데이터삽입
  • lpop <key> <value> : left 즉, 첫번째(index:0)에 데이터 삭제
  • rpop <key> <value> : right 즉,  마지막(index:-1)에 데이터 삭제
  • lrange <key> <s> <e> : s부터 e index의 데이터 반환

명령어 사용 예시 보기

더보기
127.0.0.1:6379> lpush a 1 # 추가된 value 갯수 리턴
(integer) 1
127.0.0.1:6379> rpush a 2
(integer) 2
127.0.0.1:6379> lpush a 3
(integer) 3
127.0.0.1:6379> lpush a 4
(integer) 4
127.0.0.1:6379> rpush a 5
(integer) 5
127.0.0.1:6379> lrange a 0 -1 # 첫 번째 인덱스 : 0 / 마지막 인덱스 : -1 / 마지막에서 2번째 인덱스 : -2...
1) "4"
2) "3"
3) "1"
4) "2"
5) "5"
127.0.0.1:6379> lrange a 0 3
1) "4"
2) "3"
3) "1"
4) "2"
127.0.0.1:6379> llen a
(integer) 5
127.0.0.1:6379> rpop a 3 # 끝에서 3개 반환
1) "5"
2) "2"
3) "1"

 

Sets

순서가 없는 String의 묶음

중복되지 않은 array 형식의 데이터구조 , Set의 value는 member

set 간의 연산을 지원해서 교집합,합집합, 차이를 뽑아낼수 있다.

  • sadd <key> <value> : key에 value(member)삽입
  • srem <key> <value> : value(member)삭제
  • smembers <key> : 모든 value (member)조회 
  • scard <key> : member count 조회
  • spop <key> : 무작위로 member 삭제

명령어 사용 예시 보기

더보기
127.0.0.1:6379> sadd myset a # 추가된 member 갯수 반환
(integer) 1
127.0.0.1:6379> sadd myset a
(integer) 0
127.0.0.1:6379> sadd myset b
(integer) 1
127.0.0.1:6379> sadd myset c
(integer) 1
127.0.0.1:6379> srem myset c # 삭제된 member 갯수 반환
(integer) 1
127.0.0.1:6379> smembers myset
1) "b"
2) "a"
127.0.0.1:6379> scard myset
(integer) 2
127.0.0.1:6379> sadd myset c d e f # 여러 member 삽입 가능
(integer) 4
127.0.0.1:6379> smembers myset
1) "d"
2) "c"
3) "a"
4) "f"
5) "b"
6) "e"
127.0.0.1:6379> spop myset 3 # 랜덤 member 삭제
1) "d"
2) "c"
3) "f"
127.0.0.1:6379> smembers myset
1) "a"
2) "b"
3) "e"

 

Sorted Set

set과 마찬가지로 순서가 없는 String의 묶음 

하지만 score를 통해 순위를 매겨 정렬이 가능하다. (오름차순) , Set의 value는 member

  • score값이 같으면 value로 정렬한다.
  • value는 중복이 불가능하지만, score값은 중복이 가능하다. 

 

score값은 일종의 가중치로 볼 수 있고,

정렬이 되어 있기 때문에 score값 범위에 따른 쿼리(range query), top rank에 따른 쿼리가 가능하다. 

 

  • zadd <key> <score> <member> : key에 score와 member 추가
  • zcard <key> : member count 조회
  • zrange <key> <s> <e> : s부터  e까지 index의 member 반환
  • zrangebyscore <key> <min> <max> : min부터 max까지 해당하는 scroe값을 갖는 member 반환
  • zrem <key> <member> : member 삭제

명령어 사용 예시 보기

더보기
127.0.0.1:6379> zadd ss 5 e # 추가된 value 갯수
(integer) 1
127.0.0.1:6379> zadd ss 3 c
(integer) 1
127.0.0.1:6379> zadd ss 1 a
(integer) 1
127.0.0.1:6379> zadd ss 2 b
(integer) 1
127.0.0.1:6379> zadd ss 4 d
(integer) 1
127.0.0.1:6379> zcard ss # value count
(integer) 5
127.0.0.1:6379> zrange ss 0 -1 //처음부터 끝까지 'ss'key의 member 반환
1) "a"
2) "b"
3) "c"
4) "d"
5) "e"
127.0.0.1:6379> zrangebyscore ss 2 4 //index 2부터 4까지 'ss'key의 member 반환
1) "b"
2) "c"
3) "d"
127.0.0.1:6379> zrem ss b # 삭제된 value 갯수
(integer) 1
127.0.0.1:6379> zrange ss 0 -1 //삭제된 후, 처음부터 끝까지 'ss'key의 member 반환
1) "a"
2) "c"
3) "d"
4) "e"

 

Hash

key내부에 key-value가 존재하는 자료구조

key의 Filed는 subkey로 갯수에 제한이 없다.

여러가지 object타입을 저장하기 좋고, 하나의 key에 약 40억개의 key-value 저장가능

  • hset <key> <field> <value> <field> <value> .. : 하나의 key에 여러 field-value 저장
  • hget <key> <field> : key와 field에 해당하는 value 리턴 
  • hdel <key> <field>  : field 삭제
  • hlen <key>  : field count 리턴
  • hgetAll <key> : 모든 field-value 쌍 반환 
  • hkeys <key> : 모든 field 리턴 
  • hvals <key> : 모든 value 리턴

명령어 사용 예시 보기

더보기
# field - value : name - jinmin / year - 1995 / month - 3
127.0.0.1:6379> hset hh name jinmin year 1995 month 3
(integer) 3
127.0.0.1:6379> hget hh name
"jinmin"
127.0.0.1:6379> hget hh year
"1995"
127.0.0.1:6379> hdel hh year
(integer) 1
127.0.0.1:6379> hlen hh
(integer) 2
127.0.0.1:6379> hgetAll hh
1) "name"
2) "jinmin"
3) "month"
4) "3"
127.0.0.1:6379> hkeys hh
1) "name"
2) "month"
127.0.0.1:6379> hvals hh
1) "jinmin"
2) "3"

 

 

참고

https://velog.io/@jinmin2216/Redis-3.-Redis-%EB%AA%85%EB%A0%B9%EC%96%B4-%EC%9E%90%EB%A3%8C-%EA%B5%AC%EC%A1%B0-%EC%8B%A4%EC%8A%B5

 

[Redis] 3. Redis 명령어 (자료 구조 실습)

Redis에서 자료 구조가 어떻게 사용되는지 명령어로 확인

velog.io

https://sabarada.tistory.com/103

 

[Redis] 캐시(Cache)와 Redis

[Redis] 캐시(Cache)와 Redis [Redis] Redis의 기본 명령어 [Java + Redis] Spring Data Redis로 Redis와 연동하기 - RedisTemplate 편 [Java + Redis] Spring Data Redis로 Redis와 연동하기 - RedisRepository..

sabarada.tistory.com

 

728x90
반응형