목록CS 지식 (158)
개발놀이터
이번 포스팅에선 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 자동화 툴의 치명적인 단점이라고 생각했습니다.
이번 포스팅에선 도커를 활용해 MySQL 서버를 레플리케이션 (복제) 하여 DB 부하를 줄여보겠습니다. 제 프로젝트 컨셉상 레플리케이션이 필요한 구조이긴 합니다만... 조금 의구심이 들긴 합니다. 데이터베이스 서버를 여러대 두는게 아니고 한 인스턴스에서 MySQL 서버 여러개 둔다고 DB 부하가 줄어들지는 모르겠습니다. 그래도 그냥 새로운거 도전한다고 생각하고 한번 해보도록 하겠습니다. 레플리케이션 레플리케이션이 뭔지 먼저 짚고 넘어가도록 하죠. 데이터베이스 레플리케이션이란, 데이터베이스 클러스터링에서 발전된 형태로서 DB 스토리지와 DB 서버가 하나의 쌍을 이뤄 원래라면 하나의 DB 서버가 부담해야할 부하를 여러대로 나눠 부하를 줄여줌으로써 데이터베이스의 성능이 떨어지지 않게 유지하는 방법입니다. 클러..