problem
Read 기능은 요청의 90프로를 차치 할 만큼 굉장히 중요하다
또한, 일반적인 웹서비스의 기능은 서비스가 복잡해질수록 다양한 요구가 생기며,
변경 역할과 조회 역할은 다른 성격을 띄게 되어 분리의 필요성이 커진다. ( 관심사 분리 )
조회 서버의 스케일 업/아웃 하여 조회성능을 높일 수도 있다.
그만큼 서비스의 복잡도도 엄청나게 늘어나고 유지보수 비용도 늘어난다.
복잡도는 공부로 유지보수 비용은 몸빵으로 극복하면 되지 않는가 !
solution
이 글은 Redis를 통한 조회성능을 올리는 것을 목표로 한다.
조회 서버와 DB를 분리하여 조회서버에서 redis의 데이터를 영속화 하여 관리하는 것으로 변경 해 보려고 한다.
DB 를 분리하고
최종적으로 Read서버를 분리하는 모습으로 변화 된다.
변경 전파 ( EventSourcing ) Pub/Sub 구조로 Kafka, Redis ,RabitMQ 등이 있다.
이렇게 분리 해두면 Read의 성능 CreateUpdateDelete 의 각자의
MicroService 에 맞게 각 서버의 스케일 업/아웃을 유동적으로 할 수 있는 장점을 가져올 수 있다
각자 할일에 집중 해야 할 MSA에 적절한 구조인 셈이다.
코드 적용해보기
이 구조로 만들어 보았다.
필자는 Redis의 Read 캐쉬서버를 따로 두려고 한다.
@Override
public void create(CreatePostRequestDto requestDto) {
//객체 생성 처리
.
.
Post result = postRepository.save(post);
//redis ReadRepository 데이터 삽입
PostResponseDto responseDto = result.toResponseDto();
redisService.saveRedis(result.toResponseDto());
}
데이터를 삽입 할 때 변경에 대한 이벤트를 레디스에 기록해준다.
밸류를 저장할땐 Response할 Dto객체를 저장해 준다.
dto를 저장해주는 이유는 엔터티를 조회성능에 집중하여 필요한 정보만 저장하고 조회하기 위함이다.
변경이 잦은 엔터티는 적합하지 않고 조회에 필요한 데이터를 넣어둔 Dto를 저장해주자.
//RedisService
@Override //ex. PostResponseDto
public void saveReadValue(Object value) {
try{
String className = value.getClass().getSimpleName();
String jsonObject = objectMapper.writeValueAsString(value);
redisTemplate.opsForList().leftPush(className,jsonObject);
//레디스에 저장되는 key값은 PostResponseDto value값은 json 형태의 value 파라매터
}catch (JsonProcessingException e ){
e.getStackTrace();
}
}
해당 밸류의 클래스 이름을 가져와 키로 저장하고 해당 밸류를 json으로 변경 후 저장 해준다.
//클래스이름(Key값)을 파라메터로 받아 Topic에 있는 밸류들을 불러온다
fun <T> getValues(clazz: Class<T>): List<T> {
val result: MutableList<T> = ArrayList()
try {
val className = clazz.simpleName
val jsonValues = redisTemplate.opsForList().range(className, 0, -1)
for (responseDto in Objects.requireNonNull(jsonValues)) {
val value = objectMapper.readValue(responseDto, clazz)
result.add(value)
}
} catch (e: IOException) {
e.printStackTrace()
}
return result
}
저장한 Dto의 클래스이름을 Key값으로 사용했으니 불러올때도 필요한 데이터의 Dto 클래스를 넣어 찾아오게 구현해 보았다.
결과
게시물을 단지 3개만 넣은 수치를 비교 해 보아도 3배정도의 차이가 난다
수만건의 데이터라면 더 큰 기대를 해볼 수 있지 않을까 ?
참고자료
https://www.youtube.com/watch?v=xf0kXMTFJm8&t=549s
'개-발 > Java + Spring + Kotlin' 카테고리의 다른 글
[Kotlin] build.gradle 환경변수 적용 (0) | 2024.03.18 |
---|---|
[Spring] Java + Kotlin 멀티 모듈 프로젝트 만들기 (설정편) (0) | 2024.03.17 |
[Kotlin] 단위 테스트 작성하기 (feat.JUnit5 , MockK) (0) | 2024.02.21 |
[Spring Batch] addBatch로 다량 쿼리문 한번에 실행 (bulk insert) (0) | 2024.01.17 |
[JAVA] CountDownLatch 스레드 대기 시키기 (2) | 2024.01.05 |