백엔드

백엔드/Spring

레이어간 의존 관계 문제

아래 사진은 레이어드 아키텍처다 의존하는 방향을 주목해보자. 항상 상위 레이어가 하위 레이어를 의존하는 형태를 가져간다.근데 인프라 레이어의 코드가 도메인에도 있고 애플리케이션 레이어에도 존재한다면 어떻게 될까?DB를 바꿔야 하는 상황에 닥쳤다고 생각해보자.운영상 RDBMS에서 NoSQL로 바꿔야한다는 니즈가 생겨버렸다.그럼 인프라의 변경으로 인해 도메인 레이어의 코드도 수정해야하고, 애플리케이션 레이어의 코드도 수정을 해야한다.수정만이 문제가 아니다. 이전과 동일하게 동작하는지 테스트 코드도 수정해야하고 엄청나게 많은 리소스를 쏟아 부어야한다. 바꿀 수가 없을 정도의 리소스와 리스크를 안고 가야할 수도 있다.그럼 누군가가 이렇게 말할 수도 있다."DB를 바꿔야 하는 건 소프트웨어 설계부터 잘못된거 아니..

백엔드/Java

[Java] Collection API 개선

컬렉션 팩토리 Java 9에서는 작은 컬렉션 객체를 쉽게 만들 수 있는 몇 가지 방법을 제공한다. List friends = new ArrayList(); friends.add("Raphael"); friends.add("Olivia"); friends.add("Thibaut"); 세 문자열을 저장하는데도 많은 코드가 필요하다 Arrays.asList() 메서드를 이용하면 코드를 간단하게 줄일 수 있다. List friends = Arrays.asList("Rapheal", "Olivia", "Thibaut"); 고정 크기의 리스트를 만들었으므로 요소를 갱신할 순 있지만 새 요소를 추가하거나 요소를 삭제할 순 없다. List friends = Arrays.asList("Raphael", "Olivia")..

백엔드/Java

[Java] 병렬 스트림 (parallel stream)

병렬 스트림이란? 병렬 스트림이란 각각의 스레드에서 처리할 수 있도록 스트림 요소를 여러 청크로 분할한 스트림이다. 따라서 병렬 스트림을 이용하면 모든 멀티코어 프로세서가 각각의 청크를 처리하도록 할당할 수 있다. 예를 들어, 숫자 n을 인수로 받아서 1부터 n까지의 모든 숫자의 합계를 반환하는 메서드를 구현한다했을 때, public long sequentialSum(long n) { return Stream.iterate(1L, i -> i + 1) // 무한 자연수 스티림 생성 .limit(n) // n개 이하로 제한 .reduce(0L, Long::sum); // 모든 숫자를 더하는 스트림 리듀싱 연산 } 위와 같은 코드에 n이 커진다면 이 연산을 병렬로 처리하는 것이 좋을 것이다. 병렬 스트림을 ..

백엔드/데이터베이스

[데이터베이스] Redis 캐시(Cache) 설계 전략

Redis 캐시 전략 이전 Redis의 글에서 레디스의 캐시 활용에 대해서 알아봤는데, 이번에는 캐시 배치 전략 종류에 대해서 더 상세히 알아보고, redis에서 캐쉬를 다룰 때 어떤 점을 유의해서 설계해야 되는지 적절한 캐싱 전략 선택 지침 이론을 정리해 본다. 캐시는 일반적으로 메모리(RAM)를 사용하기 때문에 데이터베이스 보다 훨씬 빠르게 데이터를 응답할 수 있어 이용자에게 빠르게 서비스를 제공할 수 있다. 하지만 기본적으로 RAM의 용량은 커봐야 16~32GB 정도라, 데이터를 모두 캐시에 저장해 버리면 용량 부족 현상이 일어나 시스템이 다운될 수 있다. 따라서 어느 종류의 데이터를 캐시에 저장할지, 얼마큼 데이터를 캐시에 저장할지, 얼마동안 오래된 데이터를 캐시에서 제거하는지에 대한 '지침 전략..

백엔드/데이터베이스

[데이터베이스] 레디스(Redis)

Redis(Remote Dictionary Server)란? Redis는 Remote(원격)에 위치하고 프로세스로 존재하는 In-Memory 기반의 Dictionary(key-value) 구조 데이터 관리 Server 시스템이다. Redis는 mysql 같은 관계형 데이터가 아닌 비 관계형 구조로서 데이터를 그저 '키-값' 형태로 단순하게 저장한다. 그래서 관계형 데이터베이스와 같이 쿼리 연산을 지원하지 않지만, 대신 데이터의 고속 읽기와 쓰기에 최적화되어 있다. 그래서 Redis는 일종의 NoSQL로 분류되기도 한다. 또한 Redis는 인 메모리(In-Mememory) 솔루션으로도 분류되기도 하는데, 다양한 데이터 구조체를 지원함으로써 DB, Cache, Message Queue, Shared Memo..

백엔드/JPA

[JPA] 즉시 로딩과 지연 로딩

객체는 객체 그래프로 연관된 객체들을 탐색한다. 그런데 객체가 데이터베이스에 저장되어 있으므로 연관된 객체를 마음껏 탐색하기는 어렵다. JPA 구현체들은 이 문제를 해결하려고 프록시라는 기술을 사용한다. 프록시를 사용하면 연관된 객체를 처음부터 데이터베이스에서 조회하는 것이 아니라, 실제 사용하는 시점에 데이터베이스에서 조회할 수 있다. 하지만 자주 함께 사용하는 객체들은 조인을 사용해서 함께 조회하는 것이 효과적이다. JPA는 즉시 로딩과 지연 로딩이라는 방법으로 둘을 모두 지원한다. 즉시 로딩과 지연 로딩 프록시 객체는 주로 연관된 엔티티를 지연 로딩할 때 사용한다. JPA는 개발자가 연관된 엔티티의 조회 시점을 선택할 수 있도록 다음 두 가지 방법을 제공한다. 즉시 로딩(EAGER LOADING) ..

백엔드/JPA

[JPA] 트랜잭션과 락

트랜잭션과 격리 수준 트랜잭션은 ACID라 하는 원자성, 일관성, 격리성, 지속성을 보장해야 한다. 원자성(Atomicity) : 트랜잭션 내에서 실행한 작업들은 마치 하나의 작업인 것처럼 모두 성공하든가 모두 실패해야 한다. 일관성(Consistency) : 모든 트랜잭션은 일관성 있는 데이터베이스 상태를 유지해야 한다. 예를 들어 데이터베이스에서 정한 무결성 제약 조건을 항상 만족해야 한다. 격리성(Isolation) : 동시에 실행되는 트랜잭션들이 서로에게 영향을 미치지 않도록 격리한다. 예를 들어 동시에 같은 데이터를 수정하지 못하도록 해야 한다. 격리성은 동시성과 관련된 성능 이슈로 인해 격리 수준을 선택할 수 있다. 지속성(Durability) : 트랜잭션을 성공적으로 끝내면 그 결과가 항상 ..

백엔드/JPA

[JPA] 복합 키와 식별 관계 매핑

식별관계와 비식별 관계 데이터베이스 테이블 사이에 관계는 외래 키가 기본 키에 포함되는지 여부에 따라 식별 관계와 비식별 관계로 구분된다. 식별 관계 식별 관계는 부모 테이블의 기본 키를 내려받아서 자식 테이블의 기본 키 + 외래키로 사용하는 관계다. 비식별 관계 비식별 관계는 부모 테이블의 기본 키를 받아서 자식 테이블의 왜래 키로만 사용하는 관계다. 비식별 관계는 외래 키에 NULL을 허용하는지에 따라 필수적 비식별 관계와 선택적 비식별 관계로 나눈다. 필수적 비식별 관계(Mandatory) : 외래 키에 NULL을 허용하지 않는다. 연관관계를 필수적으로 맺어야 한다. 선택적 비식별 관계(Optional) : 외래 키에 NULL을 허용한다. 연관관계를 맺을지 말지 선택할 수 있다. 데이터베이스 테이블..

밝은별 개발자
'백엔드' 카테고리의 글 목록