본문 바로가기
🌱 Computer Science/Database

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

by 카프리썬 2022. 2. 7.
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

 

반응형

$(document).ready(function() { var $toc = $("#toc"); $toc.toc({content: ".tt_article_useless_p_margin", headings: "h2,h3,h4"}); });