[Redis] Redis DataTypes 알아보기

728x90

안녕하세요✋

오늘은 Redis 데이터 타입에 대하여 설명을 해보겠습니다.

 

Redis  Key/Value 구조을 저장을 지원하는 NoSQL 데이터 베이스 입니다.

 

Key는 Redis data에 접근할 수 있는 식별자이며

Key 에는 binary, text를 사용할 수 있습니다.

 

하나의 Key 에는 최대 512MB 까지 저장할 수 있다.

 

이제 Redis 의 DataType 에 대하여 알아보겠습니다.

 

대표적으로 Key/Value(Data type) 에는

 

1) Strings

2) Lists

3) Sets

4) Sorted sets

5) Hashes

6) Geospatial

7) Bitmap

 

Java 컬렉션 프레임 워크에도 비슷한 자료구조가 있습니다. 

그리고 위에 있는 데이터 타입들은 자바 컬렉션 프레임워크랑 거의 유사하다고 생각하시면 됩니다.

 

 

String

  • 대표 기본 타입으로 바이너리, 문자 데이터를 저장
    • maximum 512MB
  • 증가 감소에 대한 원자적 연산
    • increment/decrement

 

command

  1. set

→ 시간복잡도 ( O(n) ) → 빠르다

  1. setnx
  2. get

→ 시간복잡도 ( O(n) ) → 빠르다

  1. mget
  2. inc
  3. dec

이정도가 있습니다.

터미널 CLI 로 한번 테스트를 해보겠습니다.

 

 

 

Java 에서 또한 Redis 라이브러리를 추가한 후 코드로 설정을 할 수 있습니다.

import java.util.List;
import java.util.Objects;

import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Pipeline;

public class RedisString {
	public static void main(String[] args) {

		try (JedisPool jedisPool = new JedisPool("127.0.0.1", 6379)) {
			try(var jedis = jedisPool.getResource()) {
				jedis.set("users:300:email","jin@naver.com");
				jedis.set("users:300:name","jin1234");
				jedis.set("users:300:age","25");

				String email = jedis.get("users:300:email");
				System.out.println(email);

				List<String> list =  jedis.mget(
					 "users:300:email",
							"users:300:name",
							"users:300:age");
				list.forEach(System.out::println);

				long counter = jedis.incr("counter");
				System.out.println("counter : " + counter);

				long counter1 = jedis.incrBy("counter", 10L);
				System.out.println("counter1 : " + counter1);

				long counter2 = jedis.decr("counter");
				System.out.println("counter2 = " + counter2);

				long counter3 = jedis.decrBy("counter", 20L);
				System.out.println("counter3 = " + counter3);

				// 파이프 라인을 사용하여 다수의 명령을 한번에 실행
				Pipeline pipeline = jedis.pipelined();
				pipeline.set("users:400:email","jin@naver.com");
				pipeline.set("users:400:name","jin");
				pipeline.set("users:400:age","25");
				List<Object> objects1 = pipeline.syncAndReturnAll();// 하나의 Redis 로 요청을 하게 됨.
				objects1.forEach( i -> System.out.println(i.toString()));
			}
		}
	}

}

 

 

 

 

이번엔 다른 데이터 타입을 설명하기 전에 중요한 Key 와 관련된 명령어를 보겠습니다

1) TTL (Time to Live)
- EXPIRE[KEY][SECOND]
- TTL[KEY]

 

 

 

삭제

DEL key:value

→ sync → 동기적으로 작동함(데이터를 다 삭제하고 응답이 옴)

삭제

UNLINK key:value

→ Async → 비동기적으로 작동함(데이터를 삭제하자 마자 응답이 온다)

즉 별도 스레드가 삭제가 진행되고, 서비스 운영 관점에서 DEL 보다 UNLINK 가 좋다

메모리 적재량 확인

MEMORY USAGE key:value

 

 

Lists

String에 대한 LinkedList 자료구조 이다. → Java 의 ArrayList 를 생각하면 된다.

주로 Stack, Queue 구현에 사용이 됩니다.

 

주요 명령어

  • LPUSH
  • RPUSH
  • LPOP
  • RPOP
  • LLEN
  • LRANGE

 

Queue를 저장하기 위해서는 항상 마지막에 저장한 RPUSH 와 제일 먼저 저장된 것을 꺼내는 LPOP 을 사용하면 Redis 에서 Queue 로 활용할 수 있다.

 

Stack 은 값을 마지막으러 저장하는 RPUSH 와 그리고 제일 마지막부터 꺼내는 RPOP을 사용하면 Redis에서 Stack 으로 사용할 수 있다.

 

 

간단 예제

lpush books:favorites '{id:100}' (integer) 1
rpush books:favorites '{id:200}' (integer) 2
lrange books:favorites 0 1
1) "{id:100"}
2) "{id:200"}
// 전체 응답 리스트를 받을 수 있는 조회문
lrange books:favorites 0 -1

 

package datatype;

import java.util.List;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

public class RedisList {
	public static void main(String[] args) {
		System.out.println("Hello Redis - List");

		try(JedisPool jedisPool = new JedisPool("127.0.0.1", 6379)) {
			try(Jedis jedis = jedisPool.getResource()) {

				// stack
				jedis.rpush("stack1","aaaa");
				jedis.rpush("stack1","bbbb");
				jedis.rpush("stack1","ccc");

				List<String> stack1 = jedis.lrange("stack1", 0, -1);
				stack1.forEach(System.out::println);

				System.out.println(jedis.rpop("stack1"));
				System.out.println(jedis.rpop("stack1"));
				System.out.println(jedis.rpop("stack1"));

				System.out.println();

				// queue
				jedis.rpush("queue2","zzzz");
				jedis.rpush("queue2","aaaa");
				jedis.rpush("queue2","bbbb");

				System.out.println(jedis.lpop("queue2"));
				System.out.println(jedis.lpop("queue2"));
				System.out.println(jedis.lpop("queue2"));
				System.out.println();

				// block -brpop , blpop
				while (true) {
					List<String> blpop = jedis.blpop(5, "queue:blocking");
					if (blpop != null) {
						blpop.forEach(System.out::println);
					}
				}
				
			}
		}
	}

}

 

Sets

정렬되지 않은 String List 이다.

String 은 Unique 한 값을 보장한다. Java → Set 자료구조랑 비슷함.

순서가 보장되지 않는다.

 

 

 

주요 명령어

  1. SADD
  2. SREM
  3. SISMEMBER
  4. SMEMBERS
  5. SINTER
  6. SCARD
sadd users:1:posts:100tags java (integer) 1
package datatype;

import java.util.Set;

import redis.clients.jedis.JedisPool;

public class RedisSet {
	public static void main(String[] args) {

		try (JedisPool jedisPool = new JedisPool("127.0.0.1", 6379)) {
			try(var jedis = jedisPool.getResource()) {
				jedis.sadd("users:500:follow", "100","200","300");
				jedis.srem("users:500:follow","100");

				Set<String> smembers = jedis.smembers("users:500:follow");
				smembers.forEach(System.out::println);

				System.out.println(jedis.sismember("users:500:follow","200"));
				System.out.println(jedis.sismember("users:500:follow","120"));

				// s inter
				System.out.println(jedis.scard("users:500:follow"));
				Set<String> sinter = jedis.sinter("users:100:follow");
				System.out.println(sinter.toString());
			}
		}

	}

}

Sorted Sets

Unique 한 값을 보장하며, 정렬도 가능하다. Java → SortedSet

점수 기반을 순위를 보여주는 것에서 사용한다.

 

 

command

  1. ZADD
  2. ZREM
  3. ZRANGE
  4. ZCARD
  5. ZRANK / ZREVRANK
  6. ZINCRBY
package datatype;

import java.util.HashMap;
import java.util.List;

import redis.clients.jedis.JedisPool;

public class RedisSortedSet {
	public static void main(String[] args) {
		try (JedisPool jedisPool = new JedisPool("127.0.0.1", 6379)) {
			try(var jedis = jedisPool.getResource()) {
				// sorted set
				HashMap<String, Double> scores = new HashMap<>();
				scores.put("user1",100.0);
				scores.put("user2",200.0);
				scores.put("user3",300.0);
				scores.put("user4",400.0);
				scores.put("user5",500.0);

				jedis.zadd("game2:scores",scores);

				List<String> list = jedis.zrange("game2:score",0,Long.MAX_VALUE);
				list.forEach(System.out::println);

				System.out.println("hi");

			}
		}
	}

}

 

Hashes

field-value → Java에서는 HashMap 자료구조

구조화된 데이터를 그룹화하여 저장 관리하기 용이하다

 

 

command

  1. HSET
  2. HGET, HMGET

→ 1건만 가져온다.

  1. HGETALL
  2. HDEL
  3. HINCRBY
HSET key:value name lee email 123@naver.com age 20 (integer) 3
// 3가지 필드에 대한 값을 설정한다. 
package datatype;

import java.util.HashMap;
import java.util.Map;

import redis.clients.jedis.JedisPool;

public class RedisHashes {

	public static void main(String[] args) {
		try (JedisPool jedisPool = new JedisPool("127.0.0.1", 6379)) {
			try(var jedis = jedisPool.getResource()) {
				// Hash
				long hset = jedis.hset("users:2:info","name","kkyu");

				HashMap<String, String> usersInfo = new HashMap<>();
				usersInfo.put("email","kyu@naver.com");
				usersInfo.put("phone","010-1234-5678");

				jedis.hset("users:2:info", usersInfo);

				// hdel
				jedis.hdel("users:2:info","phone");

				// get. getall
				System.out.println(jedis.hget("users:2:info","email"));

				Map<String, String> hgetAll = jedis.hgetAll("users:2:info");
				System.out.println(hgetAll);
				hgetAll.forEach( (k,v) -> System.out.printf("%s %s%n",k,v));

				//increment
				jedis.hincrBy("users:2:info","visits",1);
			}
		}
	}

}

 

Geospatial

위,경도 정보를 저장 할 수 있는 데이터 타입이다.

ex) google map 에서 사용한다.

command

  1. GEOADD
  2. GEOSEARCH
  3. GEDDIST
  4. GEOPOS
GEOADD key : value 

ex) 
GEOADD library 127.0343423524424 37.36247383734 "centerMedium" (integer) 1

 

Bitmap

0 과 1 의 값으로 이루어진 비트열

→ 메모리를 적제 사용하여 대량의 데이터 저장에 유용

Command

  1. SETBIT
  2. GETBIT
  3. BITCOUNT
SETBIT key:value (integer) 0

 

 

 

이상으로 Redis DataType에 대한 포스팅을 마치겠습니다.

조금 더 공부를 하고, 부족한 내용 추가 및 수정을 하겠습니다.

 

감사합니다.

728x90