Backend 개발/Backend 성능 개선
[애플리케이션 내 캐시 구현하여 백엔드 조회 API 성능 개선하기 ②]
수달리즘
2025. 4. 7. 10:51
반응형
1. 애플리케이션 내 캐시 만들어서 성능 개선
Redis를 이용하기에 앞서 애플리케이션 내에서 사용할 수 있는 캐시를 직접 구현해본다.
캐싱할 데이터가 잘 변하지 않을 경우에는 Redis와 같은 공유 캐시보다 애플리케이션 내에서 캐시를 사용하는 것이 더 유용할 수 있다. 다만 이런 경우에는 서버가 여러 대일 때 데이터가 서로 공유가 안되는 단점이 존재한다.
해당 예제에서는 다음과 같이 ConcurrentHashMap을 이용하여 캐시를 만든다.
..
import java.util.concurrent.ConcurrentHashMap;
@Repository
public class ShortenUrlRepositoryImpl implements ShortenUrlRepository {
private final JpaShortenUrlRepository jpaShortenUrlRepository;
private final ConcurrentHashMap<String, ShortenUrl> cache;
@Autowired
public ShortenUrlRepositoryImpl(JpaShortenUrlRepository jpaShortenUrlRepository) {
this.jpaShortenUrlRepository = jpaShortenUrlRepository;
this.cache = new ConcurrentHashMap<>();
}
@Override
public void saveShortenUrl(ShortenUrl shortenUrl) {
jpaShortenUrlRepository.save(shortenUrl);
cache.put(shortenUrl.getShortenUrlKey(), shortenUrl);
}
@Async
@Override
public void asyncSaveShortenUrl(ShortenUrl shortenUrl) {
jpaShortenUrlRepository.save(shortenUrl);
cache.put(shortenUrl.getShortenUrlKey(), shortenUrl);
}
@Override
public ShortenUrl findShortenUrlByShortenUrlKey(String shortenUrlKey) {
// 먼저 캐시에서 조회하도록 성능 개선
ShortenUrl shortenUrl = cache.get(shortenUrlKey);
if(shortenUrl == null) {
// 캐시에 없으면 db에서 조회
shortenUrl = jpaShortenUrlRepository.findByShortenUrlKey(shortenUrlKey);
if(shortenUrl != null) {
// db에 있으면 캐시에 저장
cache.put(shortenUrlKey, shortenUrl);
}
}
return shortenUrl;
}
}
조회 요청이 들어오면 다음의 순서로 동작한다.
- ConcurrentHashMap(캐시)에 존재하는지 체크
- 존재하면 해당 단축 데이터 리턴
- 존재하지 않으면 DB 조회 후 캐시에 저장(Map)
2. JPA dirty check 로직 수정
코드를 위와 같이 수정하고 실행하면 update문과 select문이 번갈아가며 실행되는 것을 확인할 수 있다. JPA가 엔티티에 대해 dirty check를 하기 때문에 이러한 요소가 성능이 저하되는 요인이 될 수 있다. 데이터가 변할 때 select문이 실행되지 않도록 하여 성능 개선을 도모하고자 한다면 코드를 다음과 같이 수정한다.
..
// update문만 실행되도록 네이티브 쿼리 작성
@Modifying
@Transactional
@Query("UPDATE ShortenUrl s SET s.redirectCount = s.redirectCount + 1 WHERE s.shortenUrlKey = :shortenUrlKey")
int incrementRedirectCount(String shortenUrlKey);
성능 개선이 되긴 했지만 해당 예제에서 중요하게 알아야 될 점이 있다.
성능 개선을 한다고 이런저런 작업을 했는데 오히려 성능이 떨어질 수 있다. 이럴 때 원인을 파악하고 다양한 방법으로 개선해나가는 작업을 해야 한다는 것이 중요하다. 해당 예제에서는 JPA의 특징 때문에 SELECT문이 실행되는 것을 막았는데 이게 좋은 방안이라고는 할 수 없다. 이보다 더 좋은 방법을 찾을 수 있어야 한다.
다음 예제에서는 Redis를 이용하여 캐시를 사용해볼 것이다. → https://soodal0328.tistory.com/39
728x90
반응형