전체 글

The sky is the limit
문제 상황최근 입찰가보다 1000원 이상 높은 입찰가로 입찰해야 한다는 제약 조건이 있다.그러나 1000개의 스레드로 동시에 같은 금액으로 입찰했을 때 10건이 중복 저장되는 문제가 발생했다. 해결 1 - 비관적 락 적용경매 조회 시 비관적 락을 적용해 트랜잭션이 종료될 때까지 유지되도록 하였다.@Lock(LockModeType.PESSIMISTIC_WRITE)@Query("select a from Auction a where a.id = :id")Optional findByIdWithPessimisticLock(Long id); 한 번에 하나의 요청만 접근할 수 있으므로 입찰이 중복으로 저장되는 문제가 해결되었다. 한계경매는 핵심 엔티티로 수정할 일이 많았다.비관적 락을 걸면 조회 시점부터 업데이트를 ..
복합 인덱스가 적용 안되었던 이유를 실험을 통해 알게 되어 공유하고자 한다. 상황경매 목록 조회 쿼리 성능을 개선해보고자 하였다.필터링 조건: 카테고리 목록정렬 조건: 북마크 수쿼리는 아래와 같다.select ...from auction_search as1_0 where as1_0.category in ('디지털 기기','패션/잡화')order by as1_0.bookmark_count desc limit 100; 조회 성능을 개선하기 위해 (카테고리, 북마크 수)를 복합 인덱스를 생성하였다.create index idx_category_bookmark_cnt on auction_search (category, bookmark_count desc); 문제실행 계획을 확인해 보니 복합 인덱스를 타지 않고..
추천 경매 목록 조회 API 조회 성능을 개선한 과정에 대해 정리해보고자 한다. 요구사항경매와 상품이 1:1, 상품과 상품 이미지가 1:N으로 연결되어 있다.경매 추천 목록 조회 API는 필터링과 정렬 수행 후 조건에 만족하는 경매 리스트를 반환한다.필터링 조건: 경매 상태(진행중), 사용자 거주지동적 정렬 조건: 북마크순, 입찰수순, 최신순, 경매 마감일 임박 순 문제조회할 때마다 경매 테이블과 상품 테이블을 조인하여 성능이 저하되었다.select ..from auction a1_0join product p1_0 on p1_0.product_id = a1_0.product_idwhere a1_0.auction_status = 'BIDDING' and a1_0.si = '서울시' and a1_..
MongoDB는 데이터 정합성이 낮은 대신, MySQL보다 빠른 읽기/쓰기 속도를 제공한다.그렇기 때문에 채팅처럼 입출력이 많을 때 사용하기 적합하다. 이번 글에서는 채팅 메시지를 MongoDB에 저장한 후, 채팅방별 최근 메시지를 조회해볼 것이다. MongoDB 컬렉션 매핑하기MySQL이 table을 사용한다면, MongoDB는 collection을 사용한다.@Document로 MongoDB의 collection을 매핑하였다. JPA Auditing을 사용하지 않으므로 createdAt을 직접 넣어주었다.그런데 DB에서는 시간이 UTC 기준으로 저장되어서 불편했다.이에 UTC로 변환된 값을 DB에 저장하고, 데이터를 가져올 때 다시 KST로 변환하는 코드를 추가하였다. collection이 제대로 매핑..
쿼리 성능 테스트를 위해 대용량 데이터를 삽입해야 했다.평소에는 데이터 삽입 시 saveAll()을 사용했는데, batch insert를 사용하면 빠르게 삽입할 수 있다. 이번 글에서는 batch insert로 대용량 데이터를 삽입해 보고, saveAll()과의 성능 차이를 비교해 보려고 한다. 그전에 batch insert에 대해 간략히 알아보자.Batch insertbatch는 대량의 작업을 한 번에 처리한다는 뜻이다.batch insert는 여러 SQL 명령을 그룹화하여 단일 네트워크 호출로 DB 서버에 전송한다. batch insert는 JPA, JDBC 두 방식으로 구현할 수 있다. JPA로 batch insert 구현JPA 사용 시 아래처럼 batch size 설정을 추가해 배치를 구현할 수 ..
JPA Auditing 사용 시 주의사항이전 글에서 벌크 업데이트 시 JPA Auditing이 동작하지 않는다는 점을 배웠습니다. 그런데 아래 테스트 코드를 보면, 벌크 업데이트 후에 updatedAt 필드가 자동 갱신되는 것처럼 보입니다. 채팅 요청에 대해 벌크 연산을 진행했을 경우, updatedAt 필드도 함께 갱신되는지 확인하는 테스트 코드입니다.@DisplayName("벌크 함수 호출 시, updated_at 필드가 같이 변경된다.")@Testvoid changeUpdatedAtWhenChangeStatusOfChatInquiry() { // given ChatInquiry chatInquiry = chatInquiryRepository.save(ChatInquiryFixture.ch..
배경저는 진행 중인 프로젝트에서 채팅 기능을 담당하고 있습니다.기획에 따르면, 일주일이 지난 채팅 요청은 자동 거절되어야 합니다. 이를 구현하기 위해 스케줄러를 돌려 채팅 요청들의 상태를 bulk update 해주었습니다. 채팅요청 상태가 대기중이고, 현재 시간을 기준으로 생성된 지 일주일이 지났을 때채팅요청 상태를 거절됨으로 변경해 주는 코드입니다.public void updateChatInquiryStatusRejected() { queryFactory.update(chatInquiry) .set(chatInquiry.status, InquiryStatus.REJECTED) .where( chatInquiry.status.eq(InquiryStatus..
배경AWS는 각 Public IPv4 주소에 대해 시간당 0.005달러의 과금을 부과한다.따라서 과금을 줄이기 위해서는 Public IPv4 사용을 최소화해야 한다. 나는 아래의 목적으로 EC2, RDS에 대해 각각 public ip를 사용했었다.- EC2: 배포한 서버에 탄력적 IP 매핑- RDS: intellj와 DB 연결하여 편리하게 DB 수정 및 조회 다행인 점은 EC2는 IPv4 사용이 무료이다.그래서 RDS 인스턴스만 Public IPv4를 사용하지 않도록 바꾸면 된다. 내부 네트워크로 RDS에 접근하면 IPv4 없이도 RDS 인스턴스에 연결할 수 있다.아래 그림처럼 외부에서 EC2 public subnet으로 접근하고 이를 통해 다시 RDS private subnet으로 접근한다. RDS 생..
배경기존에는 애플리케이션만 Docker 이미지로 EC2 서버에서 실행하고, Redis는 EC2 서버에 인메모리로 설치하였다.하지만 Redis도 컨테이너로 관리하는게 환경 구성에 편리할 것 같다고 생각했다.이에 Docker-Compose를 사용하여 두 컨테이너들이 통합 관리되도록 변경하였다.추후에도 배포 자동화시 이 방법을 계속 사용할 거라 잊어버리기 전에 기록해두려고 한다.cd.yml 파일 수정더보기name: CD Backendon: push: branches: [ "main", "dev" ]permissions: contents: readjobs: build-and-push-image: runs-on: ubuntu-latest steps: - name: Checkout c..
기존에는 CI만 구현되어 있는 상태였고, PR merge 후 EC2 서버에 수동 배포했다.매번 배포할 때마다 우분투 서버에서 아래 과정들을 반복했는데, 시간이 오래 걸리고 번거로웠다.깃허브 프로젝트 클론 받기gitignore 파일 직접 추가프로젝트 빌드해 jar 파일 생성기존에 실행 중인 프로세스 종료jar 파일 백그라운드에서 실행이에 Github Actions와 Docker를 활용해 배포를 자동화하였다.이번 글에서는 어떻게 배포를 자동화했는지 정리해보려고 한다. cd.yml을 작성하기 전 Dockerfile 추가, EC2 패스워드 연결 활성화, Github Secrets 환경 변수 추가가 선행되어야 한다.Dockerfile 추가DockerFile은 자바 Docker 이미지를 생성하기 위한 스크립트이다...
hyun_12
hyunDev