N° 01 — 목록
'Software Architecture' (49)
-
Software Architecture/Distributed SystemsDistributed Systems - 08. 멱등성·정확히 한 번
멱등성과 정확히 한 번 — "exactly-once" 함정 파헤치기2020년 한 결제 시스템에서 같은 결제가 두 번 처리된 사고가 터졌다. 사용자는 한 번 결제했는데, 계좌에서 두 번 빠져나갔다. 조사해보니 — 네트워크 지연으로 결제 서비스가 응답을 못 받은 클라이언트가 재시도했고, 결제 서비스는 같은 요청을 두 번 처리했다. "이런 건 왜 생기나. exactly-once 보장하면 되지 않나?"라는 질문이 자연스럽다. 이 질문에 대한 답이 이 글의 핵심이다. 결론부터 말하면 — end-to-end exactly-once는 매우 어렵고, 대부분 at-least-once + 멱등성으로 달성한다. "exactly-once"를 마케팅 문구처럼 쓰는 시스템은 사실 이 조합을 숨기는 것이다.비유로 감 잡기 — 우편..
-
Software Architecture/Distributed SystemsDistributed Systems - 07. 분산 트랜잭션
분산 트랜잭션 — 분산 환경에서 원자성을 어떻게 보장할까2016년 한 항공 예약 시스템에서 사용자의 예약과 결제가 분리된 서비스로 옮겨갔다. 사용자가 예약을 하면 — 예약 서비스가 좌석을 잠그고, 결제 서비스에 결제를 요청했다.어느 날 결제 서비스가 응답하다가 죽었다. 예약 서비스는 좌석을 잠갔지만, 결제가 됐는지 안 됐는지 몰랐다. 사용자는 돈은 안 빠졌는데 좌석이 잠겨 있다고 불만을 넣었다. 다른 사용자는 그 좌석을 예약하려다 실패했다. 한 트랜잭션으로 묶이지 않은 두 서비스의 변경이 — 중간 상태에 멈춘 것이다.모놀리스였다면 — 예약과 결제가 한 DB 트랜잭션에 묶여 있었다. 둘 다 성공하거나 둘 다 실패했다. 분산에선 그게 안 된다. 두 서비스가 각자 DB를 가지니 한 트랜잭션으로 묶을 수 없다...
-
Software Architecture/DDD & PatternsDDD Patterns - 01. DDD 전략적 설계
한 회사에 "고객"이 다섯 명 있다 — 바운디드 컨텍스트와 보편 언어한 쇼핑몰 회사에서 "고객"이라는 단어를 쓴다고 하자. 영업팀에게 고객은 "계약을 맺을 잠재 대상"이다. 배송팀에게는 "물건을 받는 수령인"이다. CS팀에게는 "문의를 넣는 사람"이다. 재무팀에게는 "매출을 발생시키는 주체"다. 같은 단어인데 뜻이 다르다. 영업팀이 "고객 수가 1만 명 늘었다"고 말하면 배송팀은 "그럼 배송지도 1만 개 추가됐나?"라고 혼란스러워한다.이 혼란의 원인은 언어가 아니라 경계가 없는 것이다. 각 부서가 자기 맥락에서 "고객"을 다르게 쓰는데, 그 맥락의 경계를 명시하지 않으니 같은 단어가 충돌한다. 도메인 주도 설계(DDD)가 푸는 문제가 바로 이것이다.바운디드 컨텍스트 — 언어가 통용되는 국경Eric Eva..
-
Software Architecture/Distributed SystemsDistributed Systems - 06. 복제 패턴
복제 패턴 — 데이터 복사본의 일관성과 가용성2017년 한 서비스가 읽기 부하를 분산시키려고 PostgreSQL에 읽기 복제본을 3개 추가했다. 마스터 DB의 쓰기는 비동기로 복제본에 복제됐다. 며칠 뒤 사용자 불만이 접수됐다 — "방금 게시글 썼는데 피드에 안 떠요". 조사해보니, 사용자의 쓰기는 마스터에 갔지만, 같은 사용자의 직후 읽기는 복제본에 갔고, 복제 지연(보통 수백 ms, 부하 시 수 초)이 발생했다. 사용자는 자기가 방금 쓴 글이 안 보이는 현상을 겪은 것이다. read-your-writes 위반의 전형적 사례. 복제는 데이터 가용성과 읽기 성능을 높이지만, 복제 지연이라는 새로운 일관성 문제를 만든다. 이 글은 복제의 세 가지 형태와 그 trade-off를 다룬다.비유로 감 잡기 — 사..
-
Software Architecture/Distributed SystemsDistributed Systems - 05. 파티셔닝과 샤딩
파티셔닝과 샤딩 — 데이터가 한 노드에 안 들 때2019년 한 SaaS 회사의 주문 테이블이 2TB를 넘겼다. 단일 PostgreSQL 인스턴스에 적재했더니 디스크 I/O가 병목이 돼 쿼리가 10배 느려졌다. 가장 비싼 인스턴스로 올려도 한계가 드러났다 — RAM에 인덱스가 다 안 들어가서 디스크 읽기가 폭증했다. "더 비싼 서버"라는 해결책이 다했던 시점이다. 다음 단계는 — 데이터를 여러 노드로 나누는 것, 즉 파티셔닝(partitioning) 또는 샤딩(sharding)이다. 둘은 같은 개념의 다른 이름이다 (샤딩은 주로 데이터베이스 맥락에서, 파티셔닝은 더 일반적으로 쓰인다). 이 글은 데이터를 어떻게 나눌까, 나누면서 생기는 새로운 문제를 어떻게 다룰까를 다룬다.비유로 감 잡기 — 도서관 책을 ..
-
Software Architecture/Distributed SystemsDistributed Systems - 04. 합의 알고리즘
합의 알고리즘 — 여러 노드가 하나의 값을 정하는 법2019년 한 Elasticsearch 클러스터에서 split-brain(뇌 분리)이 발생했다. 두 데이터센터 사이 네트워크가 30초간 끊겼다. 양쪽 데이터센터의 노드가 각자 자기를 "마스터"로 선언했다. 두 마스터는 같은 데이터에 서로 다른 쓰기를 적용했다. 네트워크가 복구됐을 때 두 마스터의 상태가 충돌했고, 시스템은 어느 쪽이 진짠지 결정하지 못해 일부 데이터를 잃었다.이 사태의 원인은 — "누가 진짜 마스터인가"를 노드들이 동의하지 못한 것이다. 합의(consensus)가 없었다. 분산 시스템에선 이런 "동의"가 필요한 상황이 자주 온다 — 누가 리더인가, 다음 연산은 무엇인가, 클러스터에 새 노드를 추가할까. 이 글은 여러 노드가 하나의 값에 ..