Key와 Value
Key
- binary와 text 저장 가능
- ex) "name", "123", "#!:()"
- 하나의 Key에 대해서 최대 512MB까지 설정이 가능
Value
- Strings
- Lists
- Sets
- Sorted sets
- Hashes
- Geospatial
- Bitmap
Key 관련 명령어
- SET key value
- 특정 key에 value를 설정
- 이미 key가 존재하면 기존 값을 덮어씀
- GET key
- 특정 key의 값을 가져옴
- key가 존재하지 않으면 nil을 반환
- DEL key [key ...]
- 하나 이상의 key를 삭제함
- 성공적으로 삭제된 key의 수 반환
- 동기적으로 삭제 진행
- 데이터를 모두 삭제하고 난 뒤에 응답이 온다.
- 큰 데이터 구조를 삭제할 때 메모리 해제에 시간이 걸리기 때문에, 삭제 작업이 완료될 때까지 블로킹이 발생할 수 있다.
- UNLINK key [key ...]
- Redis 4.0에 도입
- 비동기적으로 삭제 진행
- Lists, Sets와 같이 내부적으로 지워야 하는 대상 개수가 많다면 동기적인 삭제를 진행하는 데에 꽤 많은 시간이 소요될 수 있다.
- 뒤에 대기하고 있던 요청들은 처리되지 못하고 응답 지연이 될 것이기 때문에, 이 명령어를 호출한 서비스나 웹 애플리케이션도 자연스럽게 지연된다.
- 별도 스레드에서 삭제가 진행되므로, 메인 스레드가 블로킹되지 않는다.
- Redis 서버의 응답성을 유지하는 데 매우 유리하다!
- EXISTS key
- 특정 키가 존재하는지 확인
- 존재하면 1, 존재하지 않으면 0을 반환
- EXPIRE key seconds
- 특정 key에 대해 초 단위의 만료 시간을 설정
- TTL key
- 특정 key의 TTL(Time To Live, 초 단위 만료 시간)을 반환
- key가 만료되지 않도록 설정되어 있으면 -1, key가 존재하지 않으면 -2를 반환
- PERSIST key
- key에 설정된 만료 시간을 제거하여 영구적으로 만듦
- RENAME oldkey newkey
- 기존 key의 이름을 새로운 key로 변경함
- MEMORY USAGE key [SAMPLES count]
- key: 메모리 사용량을 확인하고자 하는 Redis 키를 지정
- SAMPLES count: 이 옵션은 큰 데이터 구조에서 메모리 사용량을 샘플링하여 추정하는 데 사용되며, 샘플 수를 지정하여 추정의 정확도를 조정할 수 있다. 기본적으로 이 옵션이 지정되지 않으면 Redis는 내부적으로 결정한 샘플링 개수를 사용한다.
실습
Strings
- 대표 기본 타입으로 바이너리, 문자 데이터를 저장
- 바이너리 저장이 가능하므로, 이미지 저장이 가능
- 백엔드에서 주로 JSON 포맷의 text 데이터를 저장
- 애플리케이션에서 객체를 직렬화한 Serialized Object 저장하고 다루기도 좋다!
- 최대 512MB
- 증가, 감소에 대한 원자적 연산
주요 명령어
SETNX key value
- key가 존재하지 않을 경우에만 value를 설정
- NX: Not eXists
MGET key [key ...]
- 여러 key의 값을 한 번에 가져옴
- 한 번에 가져올 수 있다면, 한 번에 가져오는 것이 성능상 이득!
MSET key [key ...]
- 여러 key에 대해 한 번에 값을 설정함
INCR key
- key의 값을 1 증가시킴
- key의 값이 정수일 때만 사용 가능
INCRBY key increment
- key의 값을 increment 만큼 증가시킴
DECR key
- key의 값을 1 감소시킴
- key의 값이 정수일 때만 사용 가능
- DECRBY key decrement
- key의 값을 decrement 만큼 감소시킴
실습
- 키에 여러 가지 정보를 함께 저장하기 위해 :를 사용
- ex) users:{ID 1번 유저}:email
- 다른 구분자를 사용해도 되나, 관용적으로 :이 많이 사용됨
- 증가, 감소에 대한 원자적 연산을 제공하기 위해 INCR, DECR 제공
예를 들어, 여러 클라이언트가 동시에 같은 counter 값을 증가시키려고 할 때, 원자적 연산이 없다면 다음과 같은 문제가 발생할 수 있다.
(의도는 counter를 2로 만드는 것이다.)
1. 클라이언트 A가 현재 값을 읽음 (ex. 0)
2. 클라이언트 B가 현재 값을 읽음 (ex. 0)
3. 클라이언트 A가 값을 1 증가시키고 저장함 (11)
4. 클라이언트 B가 이전에 읽은 값을 기반으로 1 증가시키고 저장함 (11, A의 변경이 덮어짐)
Lists
- 순서가 있는 문자열의 컬렉션
- 기본적으로 이중 연결 리스트로 구현되어 있음
- 순서가 유지되고, 양쪽 끝에서 요소를 빠르게 추가하거나 제거할 수 있음
- 중복된 요소를 허용
- Queue, Stack을 구현하는 데 사용
사용 사례
- 작업 큐
- Redis Lists는 작업 큐를 구현하는 데 자주 사용
- 작업을 리스트의 끝에 추가하고(LPUSH), 처리할 때 리스트의 다른 쪽에서 제거(RPOP)하여 FIFO 방식으로 큐를 처리할 수 있음
- 피드
- SNS의 뉴스 피드와 같은 타임 라인 구현에 적합
- 최신 업데이트를 리스트의 앞쪽에 추가하고, 과거 데이터는 뒤로 밀리는 구조를 구성할 수 있음
- 캐시
- 특정 크기의 캐시를 유지하고, 초과할 경우 오래된 데이터를 삭제하는 용도로 사용할 수 있음
주요 명령어
LPUSH list_key value1 value2 ... valueN
- 리스트의 왼쪽으로 하나 이상의 요소를 추가
LPUSH mylist "world" "hello"
RPUSH list_key value1 value2 ... valueN
- 리스트의 오른쪽으로 하나 이상의 요소를 추가
RPUSH mylist "hello" "world"
LPOP list_key
- 리스트의 왼쪽에서 요소를 제거하고 반환
RPOP list_key
- 리스트의 오른쪽에서 요소를 제거하고 반환
LRANGE list_key start stop
- 리스트의 특정 범위 내 요소들을 반환
LRANGE mylist 0 -1 # 리스트의 모든 요소가 반환
LLEN list_key
- 리스트의 길이를 반환
LSET list_key index value
- 리스트의 특정 위치에 있는 요소를 새로운 값으로 설정
LREM list_key count value
- 리스트에서 지정된 값과 같은 요소를 제거
LTRIM list_key start stop
- 리스트를 지정된 범위로 잘라냄
- 지정된 범위 이외의 요소는 모두 삭제됨
실습
Sets
- 순서 없음: Sets는 순서를 보장하지 않으며, 요소들은 무작위로 저장
- 데이터 타입: Sets는 문자열을 요소로 가지며, 각 요소는 고유
사용 사례
- SNS 친구 목록, 팔로워 목록
- 블랙리스트
- 추천 시스템
- Tags
주요 명령어
SADD: 하나 이상의 요소를 집합에 추가
SADD myset "hello" "world"
SREM: 집합에서 하나 이상의 요소를 제거
SREM myset "hello"
SMEMBERS: 집합의 모든 요소를 반환
SMEMBERS myset
SISMEMBER: 특정 요소가 집합에 있는지 확인
SISMEMBER myset "world"
SUNION: 두 개 이상의 집합의 합집합을 반환
SUNION myset myotherset
SINTER: 두 개 이상의 집합의 교집합을 반환
SINTER myset myotherset
SDIFF: 두 개 이상의 집합의 차집합을 반환
SDIFF myset myotherset
SRANDMEMBER: 집합에서 무직위로 하나 또는 여러 개의 요소를 반환
SRANDMEMBER myset 2
SPOP: 집합에서 무직위로 하나의 요소를 제거하고 반환
SPOP myset
SCARD: 지정된 집합의 요소 수를 반환(CARD: Cardinality, 집합의 크기)
SADD myset "apple" "banana" "cherry"
실습
Sorted sets
- 중복이 없는 값: Sorted Sets는 Set과 같이 중복을 허용하지 않는 유일한 값들을 저장
- 점수 기반 정렬: 값들은 점수에 따라 자동으로 오름차순으로 정렬되며, 동일한 점수의 값들은 사전순으로 정렬
- 빠른 조회: 특정 점수 범위의 값들을 빠르게 조회할 수 있음
사용 사례
- Leader Board
- Rate limit
주요 명령어
ZADD key [NX|XX] [CH] [INCR] score member [score member ...]
- 요소를 추가하거나, 이미 존재하는 요소의 점수를 업데이트
ZADD leaderboard 100 "user1" 200 "user2"
ZREM key member [member ...]
- 하나 이상의 요소를 삭제
ZREM leaderboard "user1"
ZSCORE key member
- 특정 요소의 점수를 반환
ZSCORE leaderboard "user2"
ZRANK key member
- 요소의 순위를 반환(오름차순)
ZRANK leaderboard "user2"
ZREVRANK key member
- 요소의 순위를 반환(내림차순)
ZREVRANK leaderboard "user2"
ZRANGE key start stop [WITHSCORES]
- 특정 범위의 요소들을 조회(점수 기준 오름차순)
- 6.2: REV, BYSCORE, BYLEX and LIMIT option
ZRANGE leaderboard 0 1 WITHSCORES
ZREVRANGE key start stop [WITHSCORES]
- 특정 범위의 요소들을 조회(점수 기준 내림차순)
ZREVRANGE leaderboard 0 1 WITHSCORES
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
- 특정 점수 범위 내의 요소들을 조회
ZRANGEBYSCORE leaderboard 100 200 WITHSCORES
ZREVRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
- 특정 점수 범위 내의 요소들을 내림차순으로 조회
ZREVRANGEBYSCORE leaderboard 200 100 WITHSCORES
ZINCRBY key increment member
- 요소의 점수를 증가
ZINCRBY leaderboard 50 "user2"
ZCARD key
- 집합의 요소 개수를 반환
ZCOUNT key min max
- 특정 점수 범위 내의 요소 개수를 반환
실습
Hashes
- 필드와 값을 쌍으로 저장하는 데이터 구조
- 필드(field): 해시 내에서 고유한 키로 필드명은 문자열로 표현
- 값(value): 필드와 연결된 데이터로, 다양한 문자열 값이 될 수 있음
사용 사례
- 구성 설정 저장
주요 명령어
HSET: 해시에 필드와 값을 설정
HSET myhash field1 "Hello"
HSETNX: 필드가 존재하지 않을 때만 값을 설정
HSETNX myhash field1 "Hello"
HGET: 특정 필드의 값을 반환
HGET myhash field1
HGETALL: 모든 필드의 값을 반환
HGETALL myhash
HMSET/HSET
- 여러 필드와 값을 한 번에 설정
- Redis 4.0부터는 HSET으로 대체됨
HSET myhash field1 "Hello" field2 "World"
HDEL: 하나 이상의 필드를 삭제
HDEL myhash field1
HEXISTS: 특정 필드가 해시에 존재하는지 확인
HEXISTS myhash field1
HLEN: 해시의 필드 개수를 반환
HLEN myhash
HINCRBY: 필드의 값을 정수만큼 증가시킴
HINCRBY myhash field1 5
실습
Geospatial
- 공간 정보를 효율적으로 저장하고 검색하는 데 사용
- 지리적 좌표(위도, 경도)를 다루는 다양한 명령어를 통해 주변 검색, 거리 계산 등을 수행할 수 있음
사용 사례
- 위치 기반 서비스
- 실시간 위치 추적
- 물류 및 배송 관리
주요 명령어
GEOADD key longitude latitude member
- 지리적 좌표를 추가
GEOADD cities 13.361389 38.115556 "Palermo"
GEOPOS key member
- 특정 멤버의 지리적 좌표를 반환
GEOPOS cities "Palermo"
GEODIST key member1 member2 [unit]
- 두 지점 간의 거리 계산
GEODIST cities "Palermo" "Catania" km
GEORADIUS key longitude latitude radius unit [options]
- 특정 지점을 중심으로 반경 내에 있는 모든 멤버를 검색
GEORADIUS cities 15 37 200 km
GEORADIUSBYMEMBER key member radius unit [options]
- 특정 멤버를 중심으로 반경 내에 있는 모든 멤버를 검색
GEORADIUSBYMEMBER cities "Palermo" 200 km
GEOHASH key member
- 지정된 멤버의 GeoHash 값을 반환
GEOHASH cities "Palermo"
GEOSEARCH key [FROMMEMBER|FROMLONLAT] [BYRADIUS|BYBOX] radius unit
- 조건에 맞는 지리적 요소를 검색
GEOSEARCH cities FROMMEMBER "Palermo" BYRADIUS 200 km
GEOSEARCHSTORE destkey key [FROMMEMBER|FROMLONLAT] [BYRADIUS|BYBOX] radius unit
- 검색 결과를 다른 key에 저장
GEOSEARCHSTORE nearby cities FROMMEMBER "Palermo" BYRADIUS 200 km
실습
Bitmap
- 0 또는 1의 값으로 이루어진 비트열
- 메모리를 적게 사용하여 대량의 데이터 저장에 유용
사용 사례
- 사용자 활동 추적: 특정 이벤트가 발생했는지를 비트맵으로 추적하여, 빠르게 대량의 사용자 데이터를 처리할 수 있음
- 유티크 카운팅: 특정 기간 동안의 유니크 이벤트 수를 비트맵으로 추적하여, 메모리 효율적으로 카운팅할 수 있음
주요 명령어
SETBIT key offset value
- 특정 키의 비트맵에서 offset 위치에 비트맵을 설정
- value는 0 또는 1
SETBIT user:1001:login 10 1
GETBIT key offset
- 특정 키의 비트맵에서 offset 위치의 비트 값을 가져옴
GETBIT user:1001:login 10
BITCOUNT key [start] [end]
- 비트맵에서 1로 설정된 비트 수를 계산
- start와 end로 비트맵의 범위를 지정
BITCOUNT user:1001:login
BITOP operation destkey key [key ...]
- 여러 비트맵 키에 대해 비트 연산을 수행하고 결과를 destkey에 저장
- operation은 AND, OR, XOR, NOT 중 하나를 지정
BITOP AND resultKey key1 key2
실습