
📚 목차
🧩 인메모리 저장소와 Redis
Redis
- Java의 Map과 같은 방식으로 데이터를 저장하는 데이터베이스
- Redis의 특징: In-Memory 데이터베이스
- 기존의 관계형 DB: 테이블 형태로 데이터를 영속적으로 저장함
- 파일 시스템(SSD 또는 HDD)에 저장해 컴퓨터가 종료되어도 데이터가 사라지지 않음
- 기본적으로 데이터를 읽고 쓰는 속도가 상대적으로 느림
- Redis: 메모리(RAM)에 데이터를 저장함
- 일반적인 RDBMS보다 빠르게 동작하지만 언제든 데이터가 사라질 수 있음
- 특정 게시글의 조회수와 같이 빠르게 업데이트되는 데이터, 또는 사용자 세션이나 장바구니처럼 시간이 지나면 삭제되는 데이터를 저장하는 데 사용됨
- 기존의 관계형 DB: 테이블 형태로 데이터를 영속적으로 저장함
NoSQL (Not only SQL)
- 관계형 DB는 일반적으로 테이블 형식으로 데이터를 저장하고, 그 데이터를 관리하기 위해 SQL문을 사용함
- Redis는 String, List, Set, Hash 등 다양한 형태의 데이터를 저장하며, 이를 관리하기 위해 SQL을 사용하지 않음
SET greeting "Hello, Redis!" GET greeting - 일관성을 포기하는 대신 확장성과 유연성을 확보함

- NoSQL 데이터베이스는 데이터를 관리하는 방법이 서로 다름
- Key-Value: Python의 dict, Java의 Map과 같은 형태 (예: Redis)
- Document: JSON, XML 등 복잡한 데이터 저장 (예: MongoDB)
- Column-Family (Wide-Column): 각 Row의 Column이 고정되어 있지 않고, 필요한 데이터 Column을 이름, 데이터, timestamp와 함께 저장함 (예: cassandra)
- 관계를 기준으로 데이터를 다루지 않기 때문에 스키마를 만들지 않고 비정형 대규모 데이터를 매우 빠르게 다룰 수 있음
Redis의 활용 사례
- Redis는 Key-Value NoSQL In-Memory 데이터베이스
- 데이터 변경이 잦은 기능을 다룰 때 많이 사용함
- 리더보드, 방문자 트래킹
- Session Clustering
- Caching
🧩 Redis 설치하기
Windows(WSL)에서 Redis 설치하기
Ubuntu에서 Redis 설치/실행/종료하기
설치$ sudo apt update$ sudo apt install redis-server -y실행/종료 방법 1$ sudo service redis-server start$ sudo service redis-server stop실행/종료 방법 2실행: redis-start종료: Ctrl + C
munsik22.tistory.com
Docker를 이용해 Redis 설치하기
- Docker Hub에서 Redis를 검색하면 세 가지 이미지를 볼 수 있다.
redis: 가장 많이 사용된 Redis의 핵심 코어redis/redis-stack-server: 여러 플러그인이 추가되어 확률형 데이터나 JSON 문서 등을 사용할 수 있음redis/redis-stack: Redis Insight를 같이 사용 가능함
docker-compose.yml생성services: redis-stack: image: redis/redis-stack container_name: redis-stack-compose restart: always environment: REDIS_ARGS: "--requirepass systempass" # USERNAME=default / password=systempass ports: - 6379:6379 - 8001:8001docker compose up -d를 실행하면 자동으로 최신 버전 Redis Stack 이미지를 사용하게 된다.docker compose ps를 실행하면 컨테이너가 정상적으로 실행되었는지 확인 가능하다.

- Intellij IDEA에서 Redis DB를 연결해 사용 가능하다.
- Redis Stack을 설치한 경우 Redis Insignt도 같이 설치된다.
http://localhost:8001에 접속하면 Redis Insight UI를 확인할 수 있다.- 여기서 USERNAME은
default, PASSWORD는systempass로 설정되었다.
- 여기서 USERNAME은
🧩 Redis 타입 살펴보기
String
- 가장 기본적인 자료형으로, Java의
Map<String, String>처럼 동작함 SET <key> <value>:key에value문자열 저장GET <key>:key에 저장된 문자열 반환- 저장된 데이터가 정수 데이터라면 데이터를 바로 증가, 감소가 가능함
INCR key:key에 저장된 데이터를 1 증가DECR key:key에 저장된 데이터를 1 감소
- 여러 Key-Value를 한번에 다루는 방법
MSET key value [key value ...]:key value의 형태로 주어진 인자들을 각key에value를 저장MGET key [key]: 주어진 모든key에 해당하는 데이터를 반환MSET user:name alex user:email alex@example.com MGET user:name user:email # alex alex@example.com이 반환됨
- 문자열 = 바이트 배열이므로 이미지, 음성, 영상, 파일 등도 보관이 가능하다.
- 분산된 구조에서 비교적 큰 사이즈의 데이터를 주고받는 상황에서 Key만 전달해서 데이터는 여기있다고 전달하는 방식으로 활용 가능함
List
- 여러 문자열 데이터를 LinkedList 형태로 보관하는 자료형
- 스택 또는 큐처럼 사용 가능함
LPUSH key value:key에 저장된 리스트의 앞쪽에value를 저장RPUSH key value:key에 저장된 리스트의 뒤쪽에value를 저장LPOP key:key에 저장된 리스트의 앞쪽에서 값을 반환 및 제거RPOP key:key에 저장된 리스트의 뒤쪽에서 값을 반환 및 제거LPUSH user:list alex # [alex] LPUSH user:list brad # [brad, alex] RPUSH user:list chad # [brad, alex, chad] RPUSH user:list dave # [brad, alex, chad, dave] LPOP user:list # brad RPOP user:list # chad
- Redis는 Key-Value 형태로 저장하므로, 실제로는
Map<String, List<String>>의 형태처럼 사용됨GET user:list라고 입력하면 Key에 저장된 자료형이 달라 WRONGTYPE 에러가 발생한다.
- 리스트를 사용하면서 흔히 사용하는 길이 구하기, 범위 내 원소 반환하기 등의 기능도 제공함
LLEN key:key에 저장된 리스트의 길이를 반환LRANGE key start end:key의start부터end까지 원소들을 반환- 파이썬처럼 음수 범위의 경우 뒤에서부터 반환함
- Worker Queue또는 SNS(X 등) 타임라인 등에서 사용 가능함
Set
- 문자열의 집합: 중복값을 제거하며 순서가 존재하지 않음
SADD key value:key에 저장된 집합에value를 추가SREM key value:key에 저장된 집합의value를 제거SMEMBERS key:key에 저장된 집합의 모든 원소를 반환SISMEMBER key value:key에 저장된 집합에value가 존재하는지 반환SCARD key:key에 저장된 집합의 크기를 반환SADD user:java alex # [alex] SADD user:java brad # [alex, brad] SADD user:java chad # [alex, brad, chad] SREM user:java alex # [brad, chad] SMEMBERS user:java # [alex, brad, chad] SISMEMBER user:java brad # true SISMEMBER user:java dave # false
- 교집합, 합집합 등의 기능도 제공함
SINTER key1 key2:key1과key2에 저장된 집합들의 교집합의 원소들을 반환SUNION key1 key2:key1과key2에 저장된 집합들의 합집합의 원소들을 반환SINTERCARD number key1 [key2 ...]:number개의key에 저장된 집합들의 교집합의 크기를 반환SADD user:python alex SADD user:python dave SINTER user:java user:python # [alex] SUNION user:java user:python # [alex, brad, chad, dave] SINTERCARD 2 user:java user:python # 1
- 어떤 데이터의 존재 여부를 확인하는
SISMEMBER는 O(1)의 시간복잡도를 가져 중복 없는 방문 수 또는 인증 토큰 블랙리스트 등을 구현할 때 활용 가능하다.
Hash
- Field-Value 쌍으로 이뤄진 자료형
- Hash 데이터를 가져오기 위해 Key를 사용하고, 이후 다시 Key에 저장된 Hash 데이터에 Field-Value 쌍을 넣어주는 형식으로 동작함
- Redis 전체가
Map이라면 Hash는Map<String, Map<String, String>>의 형식 - Hash 관련 명령어들
HSET key field value [field value]:key의 Hash에field에value를 넣음HGET key field:key에 저장된 Hash의field에 저장된value를 반환 (없으면null)HMGET key field [field]:key에 저장된 Hash에서 복수의field에 저장된value를 반환HGETALL key:key에 저장된 Hash에 저장된field-value를 전부 반환HKEYS key:key에 저장된 Hash에 저장된field를 전부 반환HLEN key:key에 저장된 Hash에 저장된field의 갯수를 반환HSET user:alex name alex age 25 HSET user:alex major CSE HGET user:alex name HGET user:alex age HMGET user:alex age major HGETALL user:alex HKEYS user:alex HLEN user:alex
- 장바구니: 사용자 별로 Hash 데이터를 생성하고 물품-개수 형식으로 데이터를 저장하는 방식으로 구현 가능
Sorted Set
- 정렬된 집합: 기본적으로 Set과 동일하게 유일한 값들만 유지하지만, 여기서 각 값들에 score라는 실수를 함께 저장하고, 데이터를 가져올 때 score를 바탕으로 정렬함
- Sorted Set 관련 명령어
ZADD key score member [score member ...]:key의 Sorted Set에score를 점수로 가진member를 추가, 이미 있는member의 경우 새로운score를 설정ZRANK key member:key의 Sorted Set의member의 순위를 오름차순 기준으로 0에서 부터 세서 반환ZRANGE key start stop:key의 Sorted Set의member들을start부터stop순위까지 오름차순 기준으로 반환ZREVRANK key member:key의 Sorted Set의member의 순위를 내림차순 기준으로 0에서 부터 세서 반환ZREVRANGE key start stop:key의 Sorted Set의member들을start부터stop순위까지 내림차순 기준으로 반환ZINCRBY key increment member:key의 Sorted Set의member의score를increment만큼 증가 (음수를 전달하면 감소)ZADD user:ranks 10 alex ZADD user:ranks 9 brad 11 chad ZADD user:ranks 8 dave ZINCRBY user:ranks 2 alex ZRANK user:ranks alex ZRANGE user:ranks 0 3 ZREVRANK user:ranks alex ZREVRANGE user:ranks 0 3
- 리더보드나 Rate Limiter와 같이 순위와 관련된 기능을 만드는 데 사용함
- ※ Rate Limiter: API 등을 제공할 때 짧은 시간에 지나치게 많은 요청을 막기 위한 기능
기타 공용 명령어
DEL key:key(와 저장된 데이터)를 제거EXPIRE key seconds:key의 TTL(유효시각)을seconds로 설정,seconds초가 지나면key제거EXPIRETIME key:key가 만료되는 시각을 Unix Timestamp로 반환KEYS *: 저장된 모든 Key 확인FLUSHDB: 모든 Key 제거
🧩 SpringBoot에서 Redis 사용하기
GitHub - qkrwns1478/redis-demo
Contribute to qkrwns1478/redis-demo development by creating an account on GitHub.
github.com
- 새 프로젝트 생성: Spring Data Redis 종속성 추가

application.yml생성
spring:
application:
name: redis-demo
config:
import: optional:file:.env[.properties]
data:
redis:
host: ${REDIS_HOST}
port: ${REDIS_PORT}
username: ${REDIS_USERNAME}
password: ${REDIS_PASSWORD}
Item엔티티 생성
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@RedisHash("item") // Entity 대신 사용
public class Item implements Serializable {
@Id private String id;
private String name;
private String description;
private Integer price;
}
ItemRepository생성
public interface ItemRepository extends CrudRepository<Item, Long> {}
ItemRepositoryTest생성
@SpringBootTest
public class RedisRepositoryTest {
@Autowired
private ItemRepository itemRepository;
@Test
public void createTest() {
Item item = Item.builder()
.name("키보드")
.description("비싸")
.price(100000)
.build();
itemRepository.save(item);
}
}
- 테스트 코드 실행 후 Redis에 해시 테이블이 추가된 것을 확인할 수 있다.

- item은 id값들을 들고 있는 집합이다.

- Redis에서는 id가 1부터 예쁘게 들어가는 게 아니라 임시값으로 들어간다.

- 일반적으로는 id값보다는 User Session이나 User Config 등 임시로 저장할 데이터를 저장하는 데 사용한다.
Redis Template
RedisTemplateTest생성:StringRedisTemplate은 각 자료형에 대응하는*Operations인터페이스 구현체를 반환할 수 있는 메서드들을 가지고 있다.
@SpringBootTest
public class RedisTemplateTest {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Test
public void stringOpsTest() {
// 문자열 조작을 위한 클래스
ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
ops.set("simplekey", "simplevalue");
System.out.println(ops.get("simplekey"));
}
}

@Test
public void stringValueOpsTest() {
ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
ops.set("simplekey", "simplevalue");
System.out.println(ops.get("simplekey"));
ops.set("greeting", "hello redis!");
System.out.println(ops.get("greeting"));
}
@Test
public void stringSetOpsTest() {
SetOperations<String, String> setOps = stringRedisTemplate.opsForSet();
setOps.add("hobbies", "games");
setOps.add("hobbies", "coding");
setOps.add("hobbies", "alcohol");
setOps.add("hobbies", "games");
System.out.println(setOps.size("hobbies"));
}

@Test
public void redisOpsTest() {
// 10초 뒤에 일괄 만료(삭제)됨
stringRedisTemplate.expire("simplekey", 10, TimeUnit.SECONDS);
stringRedisTemplate.expire("greeting", 10, TimeUnit.SECONDS);
stringRedisTemplate.expire("hobbies", 10, TimeUnit.SECONDS);
}

@Configuration에서 RedisTemplate 정의하기
ItemDto생성
@Getter
@ToString
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ItemDto {
private String name;
private String description;
private Integer price;
}
RedisConfig생성: 커스텀RedisTemplate만들기
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, ItemDto> itemRedisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, ItemDto> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
template.setKeySerializer(RedisSerializer.string()); // Key 데이터를 문자열로 직렬/역직렬화
template.setValueSerializer(RedisSerializer.json()); // Value 데이터를 JSON으로 직렬화
return template; // Bean 객체로 등록
}
}
@Autowired
private RedisTemplate<String, ItemDto> itemRedisTemplate;
@Test
public void itemRedisTemplateTest() {
ValueOperations<String, ItemDto> ops = itemRedisTemplate.opsForValue();
ops.set("my:keyboard", ItemDto.builder()
.name("Mechanical Keyboard")
.price(300000)
.description("Expensive")
.build());
System.out.println(ops.get("my:keyboard"));
ops.set("my:mouse", ItemDto.builder()
.name("mouse mice")
.price(100000)
.description("Expensive")
.build());
System.out.println(ops.get("my:mouse"));
}

'내일배움캠프' 카테고리의 다른 글
| [내일배움캠프] Spring Boot에 캐싱 적용하기 (0) | 2026.05.10 |
|---|---|
| [내일배움캠프] Redis 응용 (0) | 2026.05.08 |
| [내일배움캠프] Github Actions와 CI/CD (0) | 2026.05.06 |
| [내일배움캠프] CI/CD와 AWS ECS (0) | 2026.05.05 |
| [내일배움캠프] Docker와 Docker Compose (0) | 2026.05.04 |