본문 바로가기

Spring

Spring (boot 아님) redis (lettuce)적용하기

728x90

redis에 대해 호기심이 생겨서 로그인 정보를 캐시에 저장하는 기능으로 redis를 적용해보기로 했다.

 

Redis가 뭐시여

Redis는 Mysql이나 Oracle과 같이 DB 소프트웨어다. 하지만 다른점은 디스크에 저장하는 Mysql, Oracle등 DB 소프트웨어들과 다르게 Memory(램)에 저장하는 오픈소스 DB 소프트웨어다. 때문에 캐시처럼 데이터가 휘발성이 있지만 더 빠른 접근이 가능하기 때문에 빠른 속도를 얻을 수 있다.

 

싱글 스레드로 동작, 키-값 형태의 NoSql 등 많은 특징이 있고 장점과 단점들이 있지만 사실 나는 정리할 정도로 redis에 대한 지식은 없고 느낌만 맛보고 있는 수준이다.

 

redis는 빠른 속도가 장점이지만 데이터가 휘발성이 있다는 단점이 있기 때문에, 데이터의 생명? 관리에 대해 설정을 잘해야 빠른 속도를 제대로 활용할 수 있다고 한다. redis 튜닝에 대해서 많은 지식이 필요할것 같다.

 

그렇다면 어디에 활용하나? 사실 이걸 제일 모르겠다. 나는 redis를 현업에서 쓰지 않고 고작 개인 프로젝트로 맛만보기 때문에, 하지만 찾아보고 적용해볼 예정이다.

 

내가 알기로는 redis 어쨋든 캐시이기 때문에 사용자의 세션 클러스터링 (로그인 상태 관리)에도 쓰이고 (AWS의 Elasticache), 조회수 같은 단순한 쿼리가 많이 발생하는 요청등을 redis에 저장했다가 나중에 db에 반영하는 등으로 활용된다고 알고있다.

 

사전 조건

redis는 redis-server와 redis-client로 나뉘어지는데, 소켓통신처럼 서버가 허용된 ip에 리슨하고 있으면 클라이언트가 해당 서버에 접속하고 인증해서 명령을 실행한다. 때문에 Spring에서 적용하기전 redis-server를 설치한 서버가 필요하고, spring에서 redis 설정을 완료하고 적용하거나 테스트할 때 redis-server가 실행되어있는 상태여야한다. (spring이 클라이언트 라는 뜻)

 

 

Spring-data-redis 적용

Spring에서는 spring-data-redis라는 라이브러리를 제공하기 때문에 사용하면 쉽게 구현이 가능하다.

보통 jedis와 lettuce가 대표적으로 사용되는데 찾아보니 대부분 lettuce의 성능이 좋다는 말이 많고, 동기냐 비동기냐의 차이기 때문에 맛 보고 싶은 걸로 적용하면된다. 난 lettuce다.

 

pom.xml

spring doc을 참고해 최신버전으로 하고 싶었지만 기존에 추가한 jpa와 버전이 맞지 않는지 jpa에서 에러를 계속 뱉어서 최신버전 보다 조금 낮춰서 적용했다.

 

	<!-- redis -->
    <dependency>
	  		<groupId>org.springframework.data</groupId>
	  		<artifactId>spring-data-redis</artifactId>
			<version>2.2.1.RELEASE</version>
	  	</dependency>
	  	
	  	<dependency>
		    <groupId>io.lettuce</groupId>
		    <artifactId>lettuce-core</artifactId>
		    <version>6.0.2.RELEASE</version>
	  </dependency>

dependency 2개를 추가해준다. 참고로 spring은 5.2.7.RELEASE

 

 

Spring-data-Redis는 RedisTemplate이라는 객체를 통해서 redis에 데이터를 관리하는데, 데이터 형식에 따라서 String, Hash, list등등 이 있다. 사실 아직 String만 써봤다.

 

 

root-context.xml

<!-- redis -->
<bean id="redisConnectionFactory" class="org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory" p:host-name="${REDIS_HOST}" p:port="${REDIS_PORT}" p:password="${REDIS_PASSWORD}" />

<bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate" p:connectionFactory-ref="redisConnectionFactory" />

context파일에는 2개의 빈을 추가해줬다.

 

Test 코드

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"file:src/main/webapp/WEB-INF/spring/*.xml", 
								   "file:src/main/webapp/WEB-INF/spring/appServlet/*.xml"})
public class RedisTest {
	
	@Autowired
	StringRedisTemplate redisTemplate;
	
	@Test
	public void test() {

	    final ValueOperations<String, String> stringStringValueOperations = redisTemplate.opsForValue();
	    
	   // stringStringValueOperations.set("testKey", "testValue"); // redis set
	   
	    // String result = stringStringValueOperations.get("testKey"); // redis get
	    
	   // stringStringValueOperations.getOperations().delete("sabarada"); // redis delete
	    
	   // stringStringValueOperations.getOperations().rename("testKey", "testKey2"); //key명 변경
	   
	   //stringStringValueOperations.set("testKey2", "testValue2"); // redis 덮어쓰기
	   
	}
}

테스트로 StringRedisTemplate을 객체로 사용했다. context에 template bean을 몇개 더 추가해서 상황에 따라 맞는 redisTemplate을 쓰면 될 것 같다.

 

간단하게 데이터 insert, select, delete하는 기능과 key명을 수정하는 rename, 그리고 value update를 테스트해봤다.

 

결과

는 사실 캡처한 이미지가 없어져서 사진은 없지만 잘 된다.

728x90