목록CS 지식 (169)
개발놀이터
데이터베이스에는 동시성 문제를 해결하기 위해 시스템 내부적으로 다양한 방법들을 제공해줍니다. 오늘은 데이터베이스에서 사용할 수 있는 다양한 동시성 제어에 대해서 알아보도록 하겠습니다. 동시성 제어 이번 포스팅에서 중점적으로 다룰 동시성 제어 방식은 타임스탬프 기반 프로토콜 (Timestamp-Based Protocol) 낙관적 동시성 제어 (Optimistic Concurrency Control) 이렇게 두가지를 보도록 하겠습니다. 사실 저 두개 말고도 락 기반 프로토콜과 MVCC가 있는데 이 두가지는 이미 포스팅으로 다뤘기 때문에 이번엔 링크만 남기고 넘어가도록 하겠습니다. 락 기반 프로토콜 https://coding-review.tistory.com/302 Phantom Read 부정합문제 해결방안 ..
이번 포스팅에선 Redis와 Memcached의 동시성 문제에 대해서 궁금증이 생겨서 공유하고자 글을 쓰게 되었습니다. 구글링하다 Redis-Semaphore로 Mutex 해결하기 라는 제목의 포스팅을 발견했습니다. 처음엔 보고 "으잉? 이게 무슨말이야?" 하게 됐는데 Mutex는 동시성 문제를 해결하는 방법론인데 Mutex를 해결..? 아마 포스팅 쓰신 글쓴이분께서 Mutex의 뜻을 착각하고 계신게 아닌가 싶었습니다. 그래서 그 부분은 넘어가도록 하고 Redis-Semaphore라는게 걸려서 이번에도 역시 GPT로 공부해봤습니다. Redis와 Memcached의 차이 우선 이 둘의 차이부터 짚고 넘어가도록 하겠습니다. Redis 싱글스레드이다. 여러가지 자료형을 제공한다. String, Hash, Li..
Q. TCP의 흐름 제어와 혼잡 제어에 대해서 설명해주세요. A. 흐름 제어는 송신자와 수신자 사이에서 벌어지는 현상이고 송신자가 보내는 패킷의 크기가 수신자의 수용 용량보다 클 경우 수신자의 버퍼를 동적으로 늘리기 위해 잠시 시간을 벌어주는 용도로 사용됩니다. 이때 sliding window 방식으로 수신자가 ACK 패킷을 전달할 때마다 일정량의 데이터를 보내주는 것이 특징입니다. 혼잡 제어는 송신자와 수신자와의 통신뿐만 아니라 더 넓은 범위에서 일어나는 현상으로서 네트워크 트래픽이 너무 많아지는 경우 패킷이 로스되는 것을 막기 위해 트래픽 레벨의 모니터링을 통해 혼잡을 막기위해 window 크기와 전송 속도를 제어하는 역할을 합니다. Q. window 크기가 뭔가요? A. 단위 시간당 전송되는 패킷의..
우리가 흔히 말하는 네트워크 통신은 TCP 3way handshaking에 의해 일어납니다. 그리고 TCP에 대해 조금 공부해보신 분들은 UDP와의 차이도 말할 수 있죠. UDP와 다르게 TCP는 전이중 방식과 점대점 방식 그리고 흐름제어와 혼잡제어를 통해 높은 신뢰성을 줄 수 있다고 말이죠. 잠시 설명하자면 전이중 방식은 전송이 양방향으로 이어진다는 뜻이고 점대점 방식은 각 연결점이 종단점을 가진다는 것입니다. 하지만 흐름제어와 혼잡제어는 그냥 외우기만해서 잘 모르더라구요. 이 부분에 대해서 본격적으로 공부해봤습니다. 흐름 제어 흐름 제어는 송신자와 수신자 사이에 버퍼(데이터를 받을 수 있는 용량)를 관리하기 위해 나온 방법론입니다. 만약 송신자가 수신자에게 엄청나게 큰 데이터를 넘겨준다고 생각해봅시다..
이번 포스팅에선 데이터베이스 프로시저에 대해서 알아보도록 하겠습니다. 면접 봤는데 해당 내용이 나왔고 대답을 못했습니다. 다음 면접을 위해 정리해두는 느낌으로 포스팅 해보도록 하겠습니다. 데이터베이스 프로시저 프로시저란 무엇일까요? 간단하게 쿼리 묶음이라고 생각하시면 됩니다. 만약 자주 사용하는 SQL문이 있다면 그것들을 정리해둔 것이죠. 한번 간단한 예시를 상정해보고 코드 예제까지 보여드리겠습니다. "books"라는 테이블에 새로운 책을 입력할 것입니다. "books"테이블에 특정 책의 수량을 변경할 것입니다. 데이터가 바뀐 책의 상세 데이터를 요청해보겠습니다. DELIMITER // CREATE PROCEDURE ManageBook(IN bookTitle VARCHAR(255), IN bookAuth..
Q. 트랜잭션 전파단계에 대해서 설명해주세요 A. 스프링은 여러개의 트랜잭션 연산을 하나로 통합하기위해 물리 트랜잭션과 논리 트랜잭션이라는 개념을 도입했고 이로인해 트랜잭션 연산들이 전파되면서 원자성을 보장할 수 있었습니다. JPA에서는 다양한 트랜잭션 전파 단계를 지원하는데 디폴트값인 REQUIRED부터 무조건 새로운 트랜잭션을 만드는 REQUIRES_NEW 그외에도 SUPPORTS, NOT_SUPPORTED, NESTED, NEVER, MANDATORY 등이 있습니다.
Q. 왜 비관적 락을 사용했나요? A. 낙관적 락의 사용과 비관적 락의 사용 중 많은 고민이 있었습니다. 성능상 낙관적 락을 선택하고 싶었지만 이용자 수가 1000만명이나 된다는 컨셉 때문에 충돌이 빈번할 것으로 예측했습니다. 또한, 먼저 결제를 진행한 사용자에게 결제가 일어나고 그 뒤의 사용자는 결제가 일어나면 안된다는 생각 때문에 비관적 락을 선택했습니다.
Q. 왜 Redis를 사용하셨나요? A. 우선 대안책으로 EHcache와 Memcached가 있었습니다. 같은 글로벌 캐시인 Memcached는 Redis가 제공하는 다양한 자료구조와 장애가 발생해도 데이터를 유지할 수 있는 지속성, 수평적 확장이 용이하다는 특징 때문에 Redis를 선택했습니다. EHcache는 스프링과 통합이 쉽고 속도가 빠르다는 장점이 있어서 많은 고민이 있었지만 멀티 스레드 상황과 분산 시스템 상황에서 캐시 스토리지 동기화에 신경을 써야 해서 앞으로 분산 시스템으로 넘어갈 때 프로젝트의 복잡도를 올리고 싶지 않았습니다.
Q. 왜 JWT를 사용했는가? A. 우선 제 프로젝트의 종점이 MSA였다는 것을 먼저 피력하고 싶습니다. 때문에 격리된 애플리케이션 사이의 통신에서 인증을 위해 stateless한 인증 방식이 필요하다고 생각되었습니다. 기존 인증 방식은 스프링 시큐리티에 온전히 의존해 인증방식이 stateful하기 때문에 MSA와 맞지 않다고 생각했습니다.
Q. 왜 Jenkins를 사용했나요? A. 비교 대상은 Github Action이었고 많은 고민이 있었습니다. 결과적으로 Jenkins를 사용하게 된 이유는 우선 넓은 커뮤니티로 인해 풍부한 레퍼런스가 그 이유였습니다. 처음 CI 자동화를 하는 것이기 때문에 트러블 슈팅이라던가 레퍼런스를 참고할 곳이 많은 곳이 큰 메리트가 있었습니다. 또한 Github Action이 가지고 있는 문제 중 하나인 잡 스케쥴링에 종종 이슈가 있다는 것을 알고 CI 자동화 툴의 치명적인 단점이라고 생각했습니다.