분류 전체보기 361

NoSQL - MongoDB는 대용량 데이터를 처리하는 Database일까?

대용량 데이터 대용량 데이터의 기준은 뭘까? 일반적으로는 사람들이 다뤄보지 않은 데이터의 수준을 대용량 데이터라고 하는 것 같다. 그래서 회사마다 기준이 다르겠지만, 대용량 데이터의 기준은 1PB라고 말하곤 한다. MongoDB는 대용량 데이터를 위한 DB일까? MongoDB는 1PB의 데이터를 감당할 수 있을까..? MongoDB Atlas에서 어느정도 스펙까지 서버를 제공해주는 지를 보면 객관적인 수치라고 볼 수 있을 것이다. MongoDB Atlas에서 제공해주는 크기(조율이 가능) 중 가장 높은 스펙의 경우 RAM = 768GB, Storage(SSD) = 4096GB 이다. 즉 Storage는 4TB이고 기본 운영에도 스토리지가 사용된다는 것을 감안하면 300대가 있으면 1PB를 커버할 수 있다..

Database/NoSQL 2023.03.16

SpringBoot - zip 압축 및 다운로드 구현하기!

Spring 프로젝트에서 zip 다운로드를 구현한 내용을 공유한다. 요구사항은 아래와 같았다. 사용자로부터 GET 요청을 받으면 파일 시스템 내의 특정 폴더의 파일들을 zip 형태로 내려준다. Content-Type / Accept 스펙 설계 API를 설계하면서 Content-Type과 수용 가능한 Accept 설계가 필요하다. 아래의 두 가지 중 선택에 고민이 있었다. application/zip application/octet-stream 아래 부분 참고했을 때 application/zip이 IANA에 공식적으로 등록된 MIME 표준이라서 가장 적합한 솔루션이라고 한다. 참고 - stackoverflow 추가로 아래의 이유가 있어서 application/zip을 선택했다. zip 이외의 다운로드가 추..

Server/Spring 2023.03.10

선착순 자원을 사용하기 위한 방법! (동시성, Lock, Isolation, ...)

만약에 특정 기업에서 선착순 50명에게 맥북을 1만원에 파는 이벤트를 한다고 하자. 동시성 이슈를 어떻게 처리할 수 있을까? 문제 상황 '그냥 DB에 Select하고 50명이 없을 경우 Insert하면 되지 않나??' 라고 생각하면 안된다. 다수의 스레드가 SELECT를 수행한 시점에 재고가 있었다면 모두 Insert를 수행할 것이다. 이러한 실시간 선착순 이벤트에서 고려해야 하는 부분은 다음과 같다. 동시성을 어떻게 보장할 지 (feat. 다수의 스레드, 다수의 서버) 한 번에 쏠리는 트래픽을 어떻게 처리할 지 1. Queuing(Redis) 대표적인 솔루션으로 큐잉을 적용할 수 있다. Redis의 경우 분산 처리가 가능하고 자원 낭비가 적고 효율적이라서 대용량 트래픽을 효과적으로 처리할 수 있고, 싱..

MSA 간 동기로 API 호출 시 문제점 (feat. Read Timeout, ..)

MSA간 메시지를 주고 받는 것이 필요할 때가 있다. MSA에서 아래 서버가 있다고 가정하자. 송금 시스템 메일 알림 시스템 송금 시스템은 송금이 완료되면 메일로 알림을 보낸다. 가장 쉬운 방법은 동기 API 호출을 떠올릴 수 있다. 동기 API 호출 - 문제점 내가 다니는 회사의 레거시한 시스템의 경우 동기 API 호출을 통해 MSA에서 메시지를 주고받고 있다. 짐작 가능한 단점은 당연히 아래의 문제가 있다. 서비스 간 성능 및 장애를 공유하게 된다. (1개 시스템의 장애가 MSA 전체의 처리량 저하 및 장애로 이어질 수 있다.) 서비스 간의 강결합이 생긴다. (메일 알림이 실패하면 송금도 실패함) 사실 이번 글에서 다루고자하는 내용은 해당 내용보다는 아래의 내용이다. 동기로 API 호출을 한다고 해서..

ElasticSearch 이해하기!

엘라스틱서치(ElasticSearch)는 Apache Lucene 기반의 Java 오픈소스 분산 검색 엔진이다. 최근 ELK 스택이라는 로그 통합 시스템에도 많이 활용하지만, 해당 포스팅에서는 엘라스틱 서치 자체에 대해서 다룬다. 활용 용도 요즘 충분한 캐시는 규모가 있는 기업이라면 당연하게 되었다. 우리가 구글, 유튜브 등에서 게시글을 조회한다고 가정하자. 검색 결과를 매번 조회하면 엄청나게 큰 부하가 발생한다. 이때 캐시를 사용할 수 있을까..? 검색에서 캐시를 활용하기는 어렵다. 캐시는 보통 Key-Value 구조를 가진다. 아래의 게시글이 있다고 가정하자. 동해물과 백두산이 마르고 닳도록 하느님이 보우하사 우리나라 만세 이때 아래와 같이 엄청나게 큰 데이터를 중복해서는 엄청나게 많은 저장 공간이 ..

Database/NoSQL 2023.02.23

MySQL - 락 불필요한 데이터를 잠그는 문제 정리! (+ Index)

락은 DBMS이나 애플리케이션에서 동시성을 제어할 수 있는 방법이다. 해당 포스팅에서는 MySQL의 락에 대해 다룬다. 락 이란? 락을 통해 동시성을 제어할 때는 락의 범위를 최소화하는 것이 중요하다. 락의 범위가 길어지면 대기중인 DB 커넥션이 많아지므로 커넥션 풀 고갈로 이어질 수 있다. MySQL에서는 트랜잭션의 커밋 혹은 롤백시점에 잠금이 풀린다. 즉, 트랜잭션이 곧 락의 범위가 된다. 트랜잭션과 락 예시를 통해 알아보자. 한 트랜잭션 내에서 DB에 Update를 하고 새로운 이미지를 업로드한다고 한다고 가정하자. 트랜잭션과 락은 각각 아래의 역할을 수행한다. 트랜잭션 업로드가 진행되는 동안에도 DB 커넥션을 유지하고 트랜잭션을 지속한다. 업로드가 성공하면 트랜잭션을 커밋한다. 업로드가 실패하면 ..

Database/SQL 2023.02.17

JAVA - 문자열 비교에서의 시간 복잡도

삼성에서 주관하는 알고리즘 특강에서 라빈-카프 알고리즘에 대해서 배웠다. 그런데 한 가지 의문 사항이 생겼다. 문자열을 equals로 비교하는 것이 O(1)일텐데 왜 굳이 해시로 바꿔서 비교를 해야 하냐는 것이었다. (밑에 작성했지만 이는 사실이 아니었다!!) String.Equals String 인스턴스의 equals 메서드를 살펴봤다. (JDK 13 기준) 해당 메서드에서는 StringLatin1.equals() 메서드를 호출하고 있다. StringLatin1.equals() 메서드를 보자! bytes 배열 요소를 전부 비교하고 있음을 알 수 있었다. 참고로 String의 value 타입은 Jdk 버전마다 구현이 다르다. jdk 8의 경우에는 아래와 같이 char 배열을 사용하고, 아래와 같이 비교하..

Language/Java 2023.02.14

Spring - 멀티 모듈을 적용하면서 (+ CQRS, 이벤트 기반 아키텍처 적용)

최근 사이드 프로젝트에서 멀티모듈을 적용하면서 생긴 문제점들과 해결 과정을 공유하고자 한다. 기존의 싱글 모듈 프로젝트를 아래 네 개의 모듈로 분리할 수 있었다. 멀티 모듈을 적용한 부분과 이벤트 기반 아키텍처를 적용한 부분에 대해 다룬다. 멀티 모듈 아래는 멀티 모듈을 적용해보게 된 이유에 대해 설명한다. 1. Write Back (주기 반영) 조회가 1회 발생할 때마다 조회 수를 매번 Update문으로 갱신하면 DB에 부하가 매우 커질 것이라고 판단했다. 쓰기 락으로 인해 처리량 감소 -> DB 커넥션 쌓임 TPS 저하 및 DB 서버 부하 상승 그래서 Write Back을 해서 일정 주기로 DB에 반영할 수 있도록 작업이 필요했다. 즉, Scheduler가 필요했다. API에 Scheduler를 추가..

Server/Spring 2023.01.25

헥사고날 아키텍처 - 영속성을 구현하는 방법!

클린 아키텍처에서는 전통적인 계층형 아키텍처에서 모든 것이 영속성 계층에 의존하게 되는 점을 역전시켜, 영속성 계층을 애플리케이션 계층의 플러그인처러 만든다. 아키텍처 헥사고날 아키텍처에서는 코어의 서비스가 영속성 어댑터에 접근하기 위해 포트를 사용하는 구조를 가진다. 코어의 서비스는 포트 인터페이스를 통해 의존성을 역전시킨다. 더이상 DB를 교체하거나 JPA에서 JDBC로 기술을 바꾸는 등의 변경이 도메인 코드에 전파되지 않는다. 영속성 어댑터의 책임 영속성 어댑터의 책임은 아래와 같다. 포트의 입력 모델을 DB 포맷으로 매핑한다. DB에 쿼리 요청을 보낸다. DB 출력을 포트의 출력 모델로 매핑한다. 결과를 반환한다. 포트 인터페이스 포트 인터페이스의 크기는 어떻게 하는 것이 적당할까? 일반적으로 아..

헥사고날 아키텍처 - 웹 어댑터(컨트롤러) 구현하기!

헥사고날 아키텍처에서 Controller의 역할은 외부 세계로 보고 어댑터를 통해 이루어진다. 이를 어떻게 구현하는 지 알아보자. 의존성 아래 그림은 웹 어댑터와 애플리케이션 코어가 어떻게 상호작용하는 지 나타낸다. 웹 어댑터(인커밍 어댑터)는 애플리케이션에 의해 구현된 인터페이스인 전용 포트를 통해 애플리케이션 계층과 통신하고, 외부로부터 요청을 받아 애플리케이션 코어를 호출하는 역할을 수행한다. 해당 그림에서 만약 웹 어댑터에 능동적으로 알림을 줘야 한다면 서비스를 거쳐 아웃고잉 포트를 통과하도록 구현하면 된다. 역할 웹 어댑터는 일반적으로 다음의 처리를 한다. (시간 순으로 기술) HTTP 요청을 자바 객체로 매핑 권한 검사 입력 유효성 검증 입력을 유스케이스의 입력 모델로 매핑 유스케이스 호출 유..