본문 바로가기
카테고리 없음

redis(1) - 자료구조 활용

by ernest45 2025. 2. 5.

 

redis

  • Redis (Remote Dictionary Server) 개요
    • 고성능의 키-값(key-value) 저장소로, 거대한 맵(Map) 데이터 저장소형태를 가지고 데이터를 메모리에 저장하여 빠른 읽기와 쓰기를 지원
    • 주로 캐싱, 인증 관리, DB동시성 제어 등에서 다양한 목적으로 사용
  • 레디스 주요 특징
    • key-value로 구성된 단순화된 데이터 구조로 sql 쿼리 사용 불필요
    • 빠른 성능
      • 인메모리 NoSQL 데이터베이스로서 빠른 성능
        • rdb는 기본적으로 disk에 저장이고 필요시에 메모리에 캐싱하는 것이므로, rdb보다 훨씬 빠른 성능
        • redis의 메모리상의 데이터는 주기적으로 스냅샷 disk에 저장
      • key-value는 구조적으로 해시 테이블을 사용함으로서 매우 빠른 속도로 데이터 검색 가능
    • Single Thread 구조로 동시성 이슈 발생X
    • 윈도우 서버에서는 지원하지 않고, linux서버 및 macOS등에서 사용 가능
  • 자료구조
    • String, Lists, Sets, Sorted Sets, Hashes 등의 자료 구조를 지원
    • redis에서 모든 key값은 문자열이고, value 또한 문자/숫자 구분 없이 모든 데이터를 문자열 형식으로 저장
    • Strings
      • 데이터를 String형태의 value로 저장
      • 가장 일반적인 key - value 구조의 형태
    • Lists
      • 순서가 있는 문자열 목록
      • deque(double-ended queue)와 유사한 구조
    • Sets
      • 중복을 허용하지 않는 문자열 집합
    • Sorted Sets
      • 점수가 할당된 문자열로 이루어진 집합, score를 기준으로 정렬된 순서로 관리
    • Hashes
      • Hash는 value값이 map자료구조
  • redis 주요 스크립트
  • redis 데이터베이스는 0~15까지로 16개로 구성
      • select 데이터베이스숫자
      • 최초 접속시 default 0번
  • 주요 자료구조별 특징과 주요 명령어
    • 모든 key값 조회
      • keys *
    • 키 삭제
      • DEL key
      • 전체 삭제는 FLUSHDB(현재 데이터베이스의 모든 key삭제)
    • String관련
      • 키에 값을 설정
        • SET key value
      • 키의 값을 가져옴
        • GET key
      • NX 문법
        • key값이 존재하지 않는다면(if not exists) 값 setting
        • set key value nx
      • EX 문법
        • “set key값 value값 nx ex 초단위시간” 형식으로 key유지(만료) 시간 세팅
        • “EXPIRE key값 3600” 이런식으로 별도 부여도 가능
        • TTL(Time To Live)이라 부르기도 함.
          • “ttl key값” 명령어를 통해 남은 만료시간 확인 가능
      • 활용
        • 좋아요 기능 구현
        • 재고 처리(동시성 이슈 해결)
        • 캐싱처리(json형식의 데이터를 value값으로 많이 사용)
    • list
      • deque 또는 double-ended queue 와 유사한 구조
      • 데이터 추가
        • LPUSH key value
        • RPUSH key value
        • 데이터 중간에 삽입 불가
      • 데이터 추출 : LPOP key, RPOP key
      • 데이터 개수 조회 : LLEN key
      • 활용
        • 웹사이트 최근방문, 최근 살펴본 상품 리스트 등
    • SET
      • set은 순서가 없고 중복이 없는 자료구조
      • set(집합)에 멤버 추가
        • SADD myset member
      • set(집합)의 모든 멤버 반환
        • SMEMBERS myset
      • set의 멤버 개수 반환
        • SCARD myset
      • 특정 멤버 삭제
        • SREM myset member1
      • 활용
        • 매일 방문자수 계산
        • 좋아요 수 중복없이 집계
    • zset(정렬된 집합)
      • 정렬의 기준이 되는 score를 가지고 있는 set
      • ZADD key score member
        • score : 멤버를 정렬하는 데 사용되는 점수
      • ZREM key member
        • 특정키의 특정멤버 삭제
      • ZRANK key member
        • 특정멤버의 위치 정보 반환
      • ZRANGE stock_prices 0 -1
        • score기준 오름차순 조회
      • ZREVRANGE stock_prices 0 -1
        • score기준 내림차순 조회
      • ZRANGE my_key 0 -1 WITHSCORES
        • withscores가 없을때는 값만 오름/내림차순으로 반환. withscores가 있을때는 score까지 함께 반환
      • 활용
        • 주식, 코인 등의 실시간 시세저장 또는 게임 등의 사용자의 점수나 순위를 관리
        • 최근 살펴본 상품(리스트 중복제거)
    • hashes
      • value값이 map형태인 자료구조
      • 일반 문자열 저장과의 비교
        • json형식의 객체 데이터를 일반문자열로 set하게 될경우, 특정 요소 수정/삭제시 전체 데이터를 변경
        • hash는 map형식의 자료구조를 활용해 특정 데이터만 수정/삭제 용이
      • 주요 메서드
        • HSET
        • HGET
        • HGETALL
        • HINCRBY
      • 활용
        • 빈번히 변경될 가능성이 있는 객체 형식의 데이터 캐싱
          • hash는 특정 요소값만을 변경하기 용이
          • json형식의 문자열의 경우 데이터를 일일이 parsing 후 재 setting해야 하는 비효율

 

 

 

 

 

 

 

1) redis 활용

 

 

 

일반 rdb를 쓸 경우 멀티쓰레드이기에 동시성 이슈가 발생할 수 있다.

redis는 단일스레드이며 성능또한 좋기에 동시성 이슈를 아예 배제하고 사용할 수 있기에 활용도가 높다

 

1. 좋아요 기능

 

 

 

 

key 등록

 

 

set likes:posting:1 0 

 

key값      likes:posting:1 

value값  0

 

 

 

incr likes:posting:1 

 

   "likes:posting:1 값을 증가"

 

 

 

decr likes:posting:1 

    "likes:posting:1 값을 감소"

 

 

 

 

2. 재고관리 기능

 

 

 

 

 

3. 캐싱(임시저장) 기능

 

임시저장된 사이트를 예를 들어 rdb에 저장한다고 하면, 조회 속도가 엄청 느림

redis는 storage에 정기적으로 저장하지만, rdb보단 불안정하다. 

그래서 모든 데이터를 redis에 저장할 순 없음

 

인기글의 경우(빈번하게 조회되는 경우)

최초 조회 시 return 전 redis에 저장 후 응답하고, 다음 사용자가 조회 요청 시 redis에 임시 저장된 것이 있는 지

확인 후 응답하면 응답 속도가 훨씬 높다.

but 만료기간을 저장해주는 것이 적절하게 캐싱을 활용할 수 있다.

 

 

 

 

posting된 게시글을 json 형태로 저장

 

 

 

2) redis의 list

 

 

 

일반적으로 deque와 유사함

 

 

 

 

lpush와 rpush 후 hongildongs에 저장된 list 확인

 

 

"lrange key start end" 로 list에 저장된 key에 대한 시작 지점과 끝 지점을 선택해 확인할 수 있다.

 

 

 

 

 

rpop 후에 확인 

오른 쪽에 담겨있는 hong3가 빠져나감

 

 

 

 

 

 

 

list 조회 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

llen는 데이터의 갯수 조회

 

expire는 이미 만들어진 key 에다가 ttl 적용 가능

 

ttl로 ttl 시간 조회 가능

 

 

 

 

주의

 

만료시간이 지나면 키 자체가 다 사라짐

 

 

 

 

 

list 활용

 

 

 

최근 방문한 페이지, 최근 조회한 상품목록

 

예를 들어 최근 방문한 페이지를 2개를 return 하고 싶을 때 list를 사용하게 되면

 

"lrange key -2 -1"로 반환해주면 될 듯

 

 

 

예시)

 

최근 사용한 페이지 5개를 활용

 

 

 

 

 

확인 결과

 

 

 

 

 

문제점

 

페이지의 경우 상관없지만, 최근 조회된 상품의 경우 중복도 없고, 중복일 시 순서가 유지되고 싶다.

기본적으로 list는 중복을 허용하기에 위에 daum.com 의 경우 중복허용

 

이럴 땐 zset을 활용!

 

 

 

 

 

 

 

 

3) redis의 set

 

 

 

 

 

set에 추가 "sadd 키 value"

 

 

 

 

set의 값을 확인하고 싶을 땐

"smembers 키"

 

결과로 중복이 허용 안된 것을 볼 수 있다.

 

 

 

 

 

 

 

 

 

 

요소의 크기를 확인하고 싶을 때 (cardinality)

"scard 키" 

 

 

 

set 요소를 삭제하고 싶을 때 (remove)

 

"srem 키 값"

 

 

set 요소에 있는 지 확인하고 싶을 때

 

"sismember 키 값"

 

return 값은 0 or 1

 

 

 

 

 

1. set의 활용

 

중복이 되지 않는 방문자 수, 좋아요 등

 

 

 

 

좋아요 시 한 사람이 중복해서 누를 수 없게 하기 위해 값에다 member에 대한 정보를 넣어주면

중복으로 좋아요를 할 수 없게끔 활용 가능

 

 

 

 

 

redis의 zset

 

중복이 없는 정렬된 집합 

 

 

 

 

1. 요소 추가

 

 

zset에 추가하고 싶을 때

 

"zadd 키 스코어 값"

 

score는 정렬을 할 기준 값

 

 

 

기본적으로 score를 기준으로오름차순으로 정렬함

 

"zrange 키 시작 종료"

오름차순 정렬

 

"zrevrange 키 시작 종료" (reverse)

내림차순 정렬

 

 

 

 

 

2. 요소 삭제

 

 

 

"zrem 키 값"

 

요소를 삭제하는 것이기에 score를 직접 지정할 필요는 없다.

 

 

 

 

3. 특정 멤버 순서 출력

 

 

 

 

"zrank 키 값"

 

특정 키에 대한 값이 몇 번째인지 확인할 수 있다.

특징적으로 오름차순으로 기준

 

 

 

 

 

 

4. zset 활용

 

list를 활용 시 최근 방문한 페이지, 최근 조회한 상품목록을 조회 했을 때 중복된 페이지를

제거할 수 없는 문제점이 있었다.

 

 

이 것을 zset으로 해결!

 

(set을 활용하기 힘든 게 순서가 필요하다.)

 

score를 조회한 시간을 기준으로 주면 정렬이 가능

 

 

 

 

ex) 최근 조회한 상품목록

 

 

 

 

 

 

 

최근 본 상품에 스코어는 시간기준으로 파인애플, 바나나, 오렌지, 사과를 넣어줌

 

중복을 넣고 확인했더니 먼저 넣은 152230 사과는 사라지고 뒤에 넣은  152330 사과로 덮어쓰기!

(zset : 시간이 업데이트되고, 덮어쓰기 기억)

 

 

 

 

최근 목록으로 뽑아보니, 시간 순으로 나중에 들어간 것이 확인 가능(apple도 중복제거 됨을 확인)

 

 

 

 

 

range로 확인할 때 마지막에 "withscores" 로 스코어까지 확인 가능!

 

 

또 다른 예제로 주식의 실시간 시세게이머 별 점수나 순위를 관리에도 유용!

 

 

 

 

 

 

 

 

redis의 hashes

map형태의 자료구조이고,

value 값이 map 형태로 되어 있는 구조 키{ ..} : 값{key : value, key : value ...}

(자바에서 value 값에 map을 넣는 구조)

 

 

"hset 키 {키 값} {키 값} .."

 

 

 

 

 

1. hset 조회

 

"hget 키 키"

 

 

 

member:info:1에 해당하는 값의 키들은 name, email, age가 있고,

name을 조회 했을 때, "hong"

email을 조회 했을 때, "hong@naver.com"

age를 조회 했을 때, "30"

 

 

모든 값을 조회 하고 싶다면

"hgetall member:info:1"

 

 

 

2. hset 수정

 

 

특정 값에 대해 수정 가능
hset으로 기존처럼 덮어쓰고, 다시 조회했을 때 name이 바뀐 것을 확인

 

 

 

 

 

3. hset의 값을 증가/감소

 

 

age에 3을 증가 or 감소시키고 싶다면?

 

 

 

"hincrby 키 키 증가요소" 

 

(양수나 음수에 따라 증가/감소)

 

 

 

4. hset 활용

 

 

list나 set으로 값을 그냥 json형태로 넣게 된다면 값 요소 하나를 수정할 때 전체를 다 파싱해서 통째로 수정해야하지만,

값을 map 형태로 넣게 된다면 위처럼 하나의 값만 쉽게 바꿀 수 있다.

 

그래서 요소의 값들이 빈번하게 변경된다면? hset 활용 객체로 활용함