들어가기지난번 포스팅에선 스프링의 힘을 빌려 @Async로 API Latency를 개선했습니다. 하지만 비동기 처리 중 네트워크 문제나 AWS의 문제로 S3 폴더 이동에 제약이 생겨 실패한다면 식별,복구하기가 매우 어렵습니다. 안전한 비동기 처리를 위한 방법들을 알아보겠습니다. Redis Pub/SubRedis의 Pub/Sub은 Publisher가 Channel(Topic)에 이벤트를 발생시키면 Channel을 구독하던 Subscriber(Consumer)가 이벤트를 받아 처리하는 구조입니다. 현재 프로젝트에 대입해보자면 1. 사용자의 게시글 등록 요청2. 이미지 정보 DB에 저장3. S3 tmp 폴더에서 original폴더로 이동시키는 이벤트 발행4. 사용자에게 성공 응답5. Subscriber가 이벤..
들어가기비동기 작업을 이용하려면 스레드 풀을 이용해야 합니다. 요청마다 스레드를 생성하게 되면 생성 비용, 메모리 부족, 콘텍스트 스위칭 비용 등 여러 문제가 발생한다. 따라서 적정 수준의 스레드 수를 선택하는 방법을 알아보려합니다. CorePoolSize, WorkQueueSize, MaximumPoolSize, KeepAliveTime스레드 풀은 스레드를 미리 생성해 놓고 요청이 발생하면 스레드를 할당한 뒤에 응답이 완료되면 해당 스레드는 제거되지 않고 스레드 풀에 반환됩니다. CorePoolSize : WorkQueue가 꽉 차지 않으면 스레드는 CorePoolSize 만큼 생성돼 존재합니다. CorePoolSize를 넘어서는 요청은 WorkQueue에 대기합니다. MaximumPoolSize : ..
들어가기 게시글과 이미지 등록 API 분리로 API Latency 개선기 1들어가기게시글을 등록하는 API와 S3에 이미지를 업로드하는 API를 한 곳에서 처리하다 보면 응답 대기시간이 이미지 개수에 비례해 증가하게 됩니다. 컨트롤러에서 게시글 데이터와 이미지 데curiosity-s.tistory.com 지난번 개선기 1에서 API 분리를 통해 응답시간을 개선해보려 했습니다. 결과는 개선되지 못했고 이번 포스팅에서 그 이유와 해결책을 찾아보도록 하겠습니다. 게시글 등록 요청 시 S3에 폴더 이동 API를 사용 중게시글과 이미지 등록을 분리 시킬 경우 사용자가 중간에 이미지를 등록하고 중간에 게시글 작성 페이지를 이탈하는 경우 S3의 이미지 객체는 고아객체가 됩니다. 해당 문제를 해결하기 위해서 S3에..
들어가기게시글을 등록하는 API와 S3에 이미지를 업로드하는 API를 한 곳에서 처리하다 보면 응답 대기시간이 이미지 개수에 비례해 증가하게 됩니다. 컨트롤러에서 게시글 데이터와 이미지 데이터를 한꺼번에 받아서 처리중인 코드입니다. 게시글을 저장한 뒤에 파일들을 S3에 저장하는 서비스 코드입니다. 위 컨트롤러를 포스트맨으로 테스트 해보겠습니다. 테스트는 간단한 게시글의 제목과 내용 그리고 이미지 7장을 서버에 전송했습니다. 933ms 소요됐습니다. 거의 1초라고 봐도 무방합니다. 이 수치는 이미지의 수가 늘어날 수록 증가하게됩니다. 이번엔 이미지 파일을 3장 추가해서 총 10장을 서버에게 요청해 보겠습니다. 응답대기 시간은 약 1370ms로 이미지 개수 증가에 따라 응답시간이 46%로 크게 증..
지난번 HashSet과 해쉬충돌에 대해 알아보면서 해쉬충돌이 발생한 경우 HashSet(=HashMap)은 Separate Chaining 방식을 사용한다고 언급했었다. 특정한 임계치를 넘기 전까진 링크드리스트 구조로 노드를 연결하다가 임계치를 넘으면 자료구조를 Red-Black트리로 변경한다. Red-Black트리가 무엇인지, 자바는 왜 Red-Black트리를 선택했는지 생각해보자. 왜 트리 구조로 변경하는가? 하필이면 왜 레드-블랙 트리로?HashSet의 검색 성능[O(1)]을 보장하기 위해서는 노드를 링크드리스트로 연결하다간 O(N)의 시간 복잡도를 갖을 수 있다. 물론 데이터가 적다면 무시할 수 있겠지만 데이터가 많아진다면 O(N)은 절대 무시할 수가 없다. 링크드 리스트 대신 이진 탐색 트리를 ..
해쉬충돌은 해쉬알고리즘을 사용하는 자료구조에겐 성능상 치명적이다. 해쉬알고리즘을 사용하는 것의 목적은 자료를 정수로 표현해 인덱스를 구하기 위함인데, 해쉬충돌이 발생하면 인덱스가 충돌되기 때문에 O(1)의 시간복잡도를 유지할 수 없다. 정말 최최최악의 경우엔 O(N)의 시간복잡도를 갖게 된다. 해쉬 충돌을 해결하는 여러가지 방법을 알아보려한다. Open Addressing개방주소법이라고 불리는 이 방식은 해쉬 충돌이 발생하면 비어있는 공간을 찾아가는 알고리즘이다. Open Addressing는 크게 세 가지로 나뉜다. 1. Linear Probing Linear Probing 방식은 해쉬 충돌이 발생하면 비어있는 버킷을 발견할 때 까지 선형적으로 버킷을 검색한다. 이는 H(key,i) = (H_qp(ke..
Set은 List와 달리 중복을 허용하지 않고 순서를 보장하지 않으며 수학에서 집합과 같은 개념을 구현한 자료구조다. 특히 List의 검색은 O(N)인 반면 Set의 검색은 O(1)의 복잡도를 갖는다. Set의 검색이 항상 O(1)을 보장하진 않지만 전반적으로 굉장히 빠르다. 어떻게 O(1)이 될 수 있는지 그리고 항상 O(1)을 보장할 수 없는 이유를 알아보자. O(1)의 시간복잡도O(1)의 시간 복잡도를 갖는 자료구조로 가장 유명한 것은 배열이다. 배열을 사용하면 인덱스를 통해 한 번에 자료에 접근이 가능하기 때문이다. 한 번이라는 의미는 연산이 한 번 일어난다는 의미다. 배열에 대한 이야기는 아래 포스팅에 적어 두었다. ArrayList의 배열 리사이징ArrayList는 내부적으로 가변크기 배열을..
LinkedList링크드리스트 자료구조 역시 이름에서 특징이 잘 드러난다. 링크드리스트는 노드라고 불리는 객체가 서로서로 연결된 리스트다. 아래는 자바의 링크드리스트의 노드 클래스다. private static class Node { E item; Node next; Node prev; Node(Node prev, E element, Node next) { this.item = element; this.next = next; this.prev = prev; }} 내부 클래스로 되어있고 하나의 노드엔 다음 노드와 이전 노드를 가리킬 수 있는 필드가 선언돼있다. 이렇게 노드는 각자가 서로를 참조하는 형태로 연결돼 앞뒤로 이동이 가능하다. 이런..