728x90
개발 중인 회사 서비스에서 카프카에서 정제한 데이터를 임시데이터베이스에 저장하고, api로 호출해서 사용자 화면에 리턴해야 하는 기능을 개발했다.
처음엔 카프카 스트림즈에서 제공하는 KTable , RocksDB 를 사용했었다.
카프카에서 제공하는 라이브러리라서 의존성만 추가해주면 사용할 수 있어서 편리하긴 하지만,
카프카에 종속성이 있기에 (카프카 서버가 죽으면 외부 저장소를 사용할 수가 없다..) 리스크가 있어 외부 데이터베이스인 redis로 바꾸기로 했다.
redis 를 적용하는 과정을 정리해보았다.
- springboot 버전 : 2.5.4
- redis 버전 : 3.3.1
- 총 적용 소요시간 : 1시간
1. redis 서버 설치
1) 도커로 설치
docker pull redis
2) 방화벽 설정
firewall-cmd --permanent --add-port=6379/tcp
3) 실행
docker run --name my-redis-container -d -p 6379:6379 redis
- -name my-redis-container: 컨테이너의 이름을 my-redis-container로 지정합니다. 원하는 이름으로 변경할 수 있습니다.
- d: 백그라운드에서 컨테이너를 실행합니다 (detached 모드).
- p 6379:6379: 호스트의 6379 포트를 컨테이너의 6379 포트에 매핑합니다. 이렇게 하면 호스트에서도 Redis에 접근할 수 있습니다.
- redis: 사용할 Docker 이미지 이름입니다.
netstat -tnlp로 포트 상태 확인해보니 6379 포트가 잘 열려있다.
4) 레디스 컨테이너 안으로 접속
docker exec -it my-redis-container redis-cli
5) 레디스 테스트
터미널에 입력한 데이터가 잘 조회되고 삭제되는 것까지 확인했다. 끝!!
2. 레디스 스프링부트 적용방법
1) 의존성 추가
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>3.3.1</version>
</dependency>
2) application.yml 파일에 레디스 host, port 추가
로컬에서 레디스를 사용한다면 localhost, 다른 서버나 도커 등을 사용한다면 그에 맞는 호스트로 설정해준다. 디폴트 포트는 6379이다.
spring:
redis:
host: localhost
port: 6379
3) 레디스 설정 클래스 생성 (RedisConfig) 🌱
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
* Redis 설정 클래스
*/
@Configuration
public class RedisConfig {
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private int port;
/**
* RedisConnectionFactory 빈 생성
* (LettuceConnectionFactory를 사용하여 Redis 서버와의 연결을 설정)
*
* @return RedisConnectionFactory 객체
*/
@Bean
public RedisConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory(host, port);
}
/**
* RedisTemplate 빈 생성
* (RedisTemplate은 Redis 서버와 상호작용하기 위한 주요 인터페이스로, 다양한 Redis 명령어를 수행한다.)
*
* @return RedisTemplate 객체
*/
@Bean
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory()); // redisTemplate에 redisConnectionFactory 객체 세팅
// 일반적인 key:value의 경우 시리얼라이저
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());
// Hash를 사용할 경우 시리얼라이저
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new StringRedisSerializer());
// 모든 경우
redisTemplate.setDefaultSerializer(new StringRedisSerializer());
return redisTemplate;
}
}
4) 레디스 유틸 클래스 생성 (RedisUtils) 🌱
레디스를 사용하는 방법은 RedisRepository, RedisTemplate 둘 중 하나를 사용하면 된다. 나는 레디스템플릿을 사용할 예정.
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
@RequiredArgsConstructor
@Service
public class RedisUtils {
/**
* Redis 사용위한 util 클래스
*/
private final RedisTemplate<String, Object> redisTemplate;
/**
* 지정된 키와 값으로 데이터를 Redis에 저장
*/
public void setData(String key, String value) {
redisTemplate.opsForValue().set(key, value);
}
/**
* 지정된 키에 해당하는 데이터를 Redis에서 ㅈ회
*/
public String getData(String key) {
return (String) redisTemplate.opsForValue().get(key);
}
/**
* 지정된 키에 해당하는 데이터를 Redis에서 삭제합니다.
*/
public void deleteData(String key) {
redisTemplate.delete(key);
}
}
레디스 템플릿은 사용하는 자료구조마다 제공하는 메서드가 다르기 때문에 객체를 만들어서 레디스의 자료구조 타입에 맞는 메소드를 사용하면 된다.
나는 String 타입으로 사용했다.
메서드 명 | 레디스 타입 |
opsForValue | String |
opsForList | List |
opsForSet | Set |
opsForZSet | Sorted Set |
opsForHash | Hash |
5) 컨트롤러 예제 (RedisController) 🌱
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/redis")
@RequiredConstructor
public class RedisController {
private final RedisUtils redisUtils;
/**
* Redis에 데이터를 저장하는 엔드포인트 예제
*
* @param key 저장할 데이터의 키
* @param value 저장할 데이터의 값
*/
@PostMapping("/setData")
public void setDataToRedis(@RequestParam String key,
@RequestParam String value) {
redisUtils.setData(key, value);
}
/**
* Redis에서 데이터를 조회하는 엔드포인트 예제
*
* @param key 조회할 데이터의 키
* @return 키에 해당하는 데이터 (문자열 형태)
*/
@GetMapping("/getData")
public String getDataFromRedis(@RequestParam String key) {
return redisUtils.getData(key);
}
/**
* Redis에서 데이터를 삭제하는 엔드포인트 예제
*
* @param key 삭제할 데이터의 키
*/
@DeleteMapping("/deleteData")
public void deleteDataFromRedis(@RequestParam String key) {
redisUtils.deleteData(key);
}
}
kafka 프로듀서로 데이터를 보내고, 키 값으로 조회하는 호출을 postman 으로 해보았다.
해당 키 값을 가진 데이터 중 최신 데이터가 잘 호출이 되었다.
끝 ^^
'DB > Database' 카테고리의 다른 글
[Redis] 레디스 캐시를 사용하면 조회 성능이 몇 배 정도 빨라질까? (@Cacheable) (2) | 2024.07.31 |
---|---|
[Redis] Redis 라이브러리 3종 비교 (Spring redis vs Lettuce vs Redisson) (0) | 2024.07.28 |
[MyBatis] getter 메소드 자동 사용(?) (0) | 2024.01.16 |
[MySQL] 계층형 조회 (Recursive 재귀 쿼리) (1) | 2024.01.09 |
MariaDB / DBeaver 에서 컬럼 Auto increment 숫자 변경 (0) | 2023.11.30 |