Notice
Recent Posts
Recent Comments
Link
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Archives
Today
Total
관리 메뉴

밤빵's 개발일지

[TIL]20240812 성능최적화 본문

개발Article

[TIL]20240812 성능최적화

최밤빵 2024. 8. 12. 23:52

성능최적화에 대해서 알아두라는 말을 들어서 바로 알아보기 시작했다. 지금 숙제?처럼 받은 N+1문제도 포함이고, 최적화하는데 여러가지 방법이 있어서, 이걸 정리하는데 시간이 많이 걸렸다..! 개발일지를 작성하면서도 모르는게 아직도 많아서 어렵지만 이런게 있구나 하는 정도는 기억하면 좋지않을까? 

성능 최적화는 애플리케이션의 반응 속도, 처리량, 리소스 사용률을 개선하여 사용자 경험을 향상시키는 중요한 과정이다. 개발자라면 성능 최적화는 시스템의 효율성을 높이고 서버 자원의 낭비를 줄이기 위해 필수적으로 고려해야 하는 부분이다. 

😵‍💫성능 최적화란 무엇일까?

성능 최적화는 애플리케이션의 전반적인 성능을 개선하기 위해 코드와 시스템 구조를 효율적으로 재구성하는 것을 의미한다. 이는 응답 시간을 줄이고, 처리량을 증가시키고, 리소스 사용률을 줄이는 것을 목표로 한다. 성능 최적화는 단순히 코드를 수정하는 것을 넘어 데이터베이스, 네트워크, 캐시, 그리고 하드웨어 리소스까지 전반적인 시스템의 개선을 포함한다.

 

▶데이터베이스 최적화

데이터베이스는 많은 애플리케이션의 핵심 구성 요소이기 때문에 성능 최적화의 중요한 대상이다. 데이터베이스 최적화는 다음과 같은 방법으로 이루어진다.

 

→ 인덱스 최적화:

인덱스는 데이터베이스 쿼리 성능을 획기적으로 개선할 수 있다. 적절한 인덱스 사용은 쿼리의 검색 속도를 향상시킬 수 있지만, 너무 많은 인덱스는 데이터 삽입 및 업데이트 시 성능 저하를 일으킬 수 있다.

→ 쿼리 최적화:

복잡한 SQL 쿼리를 최적화하여 불필요한 연산을 줄이는 것이 중요하다. 서브쿼리 대신 조인을 사용하거나, 불필요한 SELECT * 대신 필요한 컬럼만을 선택하는 등의 방법으로 쿼리를 개선할 수 있다.

→ 캐싱:

자주 조회되는 데이터를 메모리 캐시에 저장하여 데이터베이스 조회 횟수를 줄일 수 있다. Redis나 Memcached와 같은 인메모리 캐시를 활용하면 데이터베이스 부하를 크게 줄일 수 있다.

→ 데이터 정규화와 비정규화:

데이터베이스의 구조를 최적화하는 것도 중요하다. 데이터 정규화를 통해 중복 데이터를 제거하고, 필요한 경우 비정규화를 사용하여 쿼리 성능을 개선할 수 있다.

 

▶코드 최적화

백엔드 애플리케이션의 성능은 코드의 효율성에 큰 영향을 받는다. 코드 최적화는 다음과 같은 방법으로 이루어진다.

 

→ 알고리즘 및 자료 구조 최적화:

효율적인 알고리즘과 적절한 자료 구조를 선택하는 것은 성능 최적화의 기본이다. 예를 들어, 대량의 데이터 검색에는 해시맵을 사용하고, 정렬된 데이터에는 이진 탐색을 사용하는 것이 적합하다.

→ 비동기 프로그래밍:

동기식 요청은 블로킹이 발생하기 때문에, 비동기 프로그래밍을 통해 I/O 작업이나 네트워크 호출을 비동기적으로 처리하여 응답 시간을 줄일 수 있다. Java에서는 CompletableFuture, Spring에서는 WebFlux와 같은 비동기 모델을 활용할 수 있다.

→ 객체 생성 최소화:

불필요한 객체 생성을 줄여 메모리 사용을 최적화할 수 있다. 특히, 불변 객체(Immutable Object)를 사용하여 메모리 사용량을 줄이고, GC(가비지 컬렉션) 성능을 개선할 수 있다.

→ JVM 튜닝:

JVM 옵션을 조정하여 애플리케이션의 성능을 개선할 수 있다. 예를 들어, 힙 크기 조정, GC 알고리즘 설정 등을 통해 메모리 사용과 GC 작업을 최적화할 수 있다.

 

▶네트워크 최적화

네트워크 성능은 전체 애플리케이션 성능에 큰 영향을 미친다. 네트워크 최적화는 다음과 같은 방법으로 이루어진다:

 

→데이터 압축:

데이터 전송 전에 데이터를 압축하면 네트워크 대역폭 사용을 줄이고, 전송 속도를 높일 수 있다. Gzip, Brotli와 같은 압축 알고리즘을 활용할 수 있다.

→ HTTP/2 및 HTTP/3 사용:

HTTP/2와 HTTP/3은 멀티플렉싱, 헤더 압축, 서버 푸시와 같은 기능을 제공하여 네트워크 성능을 향상시킨다. 이를 통해 애플리케이션의 응답 속도를 개선할 수 있다.

→ CDN(Content Delivery Network) 활용:

CDN을 사용하면 정적 자원을 전 세계의 여러 서버에 분산하여 배포할 수 있다. 이를 통해 정적 자원(이미지, CSS, JS 파일 등)에 대한 응답 시간을 크게 줄일 수 있다.

→ 로드 밸런싱:

로드 밸런서를 사용하여 서버의 트래픽을 여러 서버에 분산시킬 수 있다. 이를 통해 특정 서버에 과부하가 걸리는 것을 방지하고, 전체 시스템의 안정성을 높일 수 있다.

 

▶캐싱 전략

캐싱은 성능 최적화에서 매우 중요한 요소이다. 캐시는 데이터베이스나 네트워크 호출을 최소화하여 성능을 개선할 수 있다.

→ 클라이언트 측 캐싱:

브라우저 캐싱을 활용하여 정적 리소스의 재요청을 줄일 수 있다. Cache-Control 헤더와 ETag를 사용하여 브라우저가 리소스를 캐싱하도록 설정할 수 있다.

→ 서버 측 캐싱:

서버 측에서 캐시를 설정하여 정적 컨텐츠나 자주 변경되지 않는 데이터를 캐시할 수 있다. Spring에서 @Cacheable 애너테이션을 사용하여 메서드 결과를 캐시할 수 있다.

→ 분산 캐시:

Redis와 같은 분산 캐시를 사용하여 여러 서버 간의 데이터 일관성을 유지하고, 애플리케이션의 스케일링을 지원할 수 있다.

 

▶ 예시: Spring 애플리케이션에서 캐싱을 통한 성능 최적화

다음은 Spring Boot 애플리케이션에서 Redis를 사용하여 캐싱을 적용한 예시이다.

 

▽코드 예시

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    private final UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    // 데이터베이스 조회 결과를 Redis 캐시에 저장
    @Cacheable(value = "users", key = "#userId")
    public User getUserById(Long userId) {
        return userRepository.findById(userId)
                .orElseThrow(() -> new UserNotFoundException("User not found with id: " + userId));
    }

 

→ @Cacheable 어노테이션은 메서드의 결과를 캐시하여 동일한 입력 값으로 메서드가 호출되었을 때 캐시된 값을 반환하도록 한다.

→ value 속성은 캐시의 이름을 지정하고, key 속성은 캐시 키를 정의한다. Redis와 같은 캐시 저장소에 데이터를 저장하여 성능을 최적화한다.

 

▶성능 최적화 시 주의사항

 

→ 과도한 최적화 피하기:

너무 많은 최적화는 오히려 코드의 가독성을 떨어뜨리고 유지보수성을 저하시킬 수 있다. 필요한 부분에만 최적화를 적용해야 한다.

→ 모니터링과 프로파일링:

애플리케이션의 성능을 모니터링하고, 프로파일링 도구를 사용하여 성능 병목 지점을 찾아내는 것이 중요하다.

→ 테스트와 검증:

성능 최적화 후에는 반드시 성능 테스트를 통해 변경 사항이 실제로 효과가 있는지 검증해야 한다.

 

▶정리

백엔드 애플리케이션에서 자주 사용되는 성능 최적화 방법들에 대해 공부해보았다. 데이터베이스 최적화, 코드 최적화, 네트워크 최적화, 캐싱 전략 등 다양한 방법을 통해 애플리케이션의 성능을 개선할 수 있다는 것을 배웠다. 성능 최적화는 단순히 코드를 변경하는 것뿐만 아니라, 시스템 전반에 걸친 접근 방식과 설계를 개선하는 과정임을 알게 되었다. 기술 매니저님의 조언으로 성능 최적화에 대해 알아보았고, 이를 실제 프로젝트에 어떻게 적용할지 고민하는 좋은 기회가 되었다. 앞으로도 꾸준히 성능 최적화와 관련된 지식을 쌓고, 다양한 최적화 기법을 학습해나가야겠다.

'개발Article' 카테고리의 다른 글

[TIL]20240814 N+1 문제해결  (0) 2024.08.14
[TIL]20240813 Nginx  (0) 2024.08.13
[WIL]20240811 Redis  (0) 2024.08.11
[TIL]20240810 단위테스트란?  (0) 2024.08.10
[TIL]20240809 Validation  (0) 2024.08.09