본문 바로가기

작업일지/안동버스 API 연동

#3) Redis(레디스)로 캐싱하기

Redis(레디스)는 메모리 기반의 “키-값” 구조 데이터 관리 시스템이며, 모든 데이터를 메모리에 저장하고 조회하기에 빠른 Read, Write 속도를 보장하는 NOSQL 중 하나이다. 인메모리 기반이지만 삭제 명령을 하지않으면 영속성을 지원하는 인메모리 데이터 저장소이고 쓰기 성능 증대를 위한 클라이언트 측 샤딩(Sharding)을 지원한다.

 

그래도 메모리 기반이기때문에 데이터 적재용으로 쓰기에는 무리가 있을 것으로 보인다.

 

출처 : 조대협님의 블로그

레디스 구조

다음의 그림과 같이 문자열, 리스트, 해시, 셋, 정렬된 셋과 같은 다양한 데이터형을 지원한다.


Redis와 Springboot 연동

 

1. pom.xml에 Redis dependency 추가

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

 

2. application.yml에 셋팅값 입력

spring:
  profiles:
    active:
    - dblocal
    - redislocal
    - tomcatlocal
    - elasticlocal
    - kafkaLocal
    - mysqllocal
    
    .
    .
    .
    .
    .
    .
  spring:
  profiles: redislocal
  redis:
    host: 127.0.0.1
    port: 6379
    database: 0
    

 

3. 나는 RedisTamplate를 사용했다. Redisconfig 클래스 파일을 생성 후 다음과 같이 작성했다. 

setKeySerializer와 setValueSerializer는 스프링 상에서는 정상적으로 조회되어 보이지만

redis-cli로 데이터를 확인하면 키값에 이상한 문자열이 앞에 붙어서 보이게되는데 이를 방지해준다.

@Slf4j
@Configuration
public class RedisConfig {

    @Value("${spring.redis.host}")
    private String host;

    @Value("${spring.redis.port}")
    private int port;

    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory(host, port);
    }

    @Bean
    public RedisTemplate<byte[], byte[]> redisTemplate() {
        RedisTemplate<byte[], byte[]> redisTemplate = new RedisTemplate<>();
        log.info("Redis Template Connection = {}:{}", host, port);

        redisTemplate.setConnectionFactory(redisConnectionFactory());
        redisTemplate.setKeySerializer(RedisSerializer.string());
        redisTemplate.setValueSerializer(RedisSerializer.string());

        return redisTemplate;
    }
}

 

4. RedisService 클래스를 만들어 다음과 같이 저장 및 조회 메소드를 작성한다. 필자는 안동버스 stationId를 키값으로 잡았고 도착정보를 string으로 뽑아서 전부 value로 넣기로 했다. 키값은 중복이 되면 새로운 value값으로 자동으로 덮어씌워진다. 또 redisTemplate.opsForValue().set(stationId, arrivalInfo,10, TimeUnit.MINUTES); 을 이용해서 데이터가 입력된 후 10분이 지나면 자동으로 삭제되도록 설정했다.

@Slf4j
@AllArgsConstructor
@NoArgsConstructor
@Service
public class RedisService {

    @Resource
    private RedisTemplate redisTemplate;

    //redis 저장
    public void redisSave(String stationId, String arrivalInfo) {
        log.info("Redis Save Start [{}]", arrivalInfo);
        redisTemplate.opsForValue().set(stationId, arrivalInfo,10, TimeUnit.MINUTES);
        log.info("Redis Save Success!![{}],[{}]", stationId, arrivalInfo);

    }

    //redis 조회
    public String redisSelect(Map stationId) {
        log.info("Redis Select Start");
        String result = (String)redisTemplate.opsForValue().get(stationId.get("stationId"));
        log.info("Redis Select Success!![{}],[{}]", stationId, result);
        return result;
    }
}

 

5. 나는 특정 버스정류장의 도착정보를 적재할 때, 다음처럼 캐싱값을 저장하는데 이용했다.

 

아주 잘 연동되었습니다. 

반응형