diff --git a/marshmallowing/Week03/chapter03.md b/marshmallowing/Week03/chapter03.md new file mode 100644 index 0000000..dd3f9e7 --- /dev/null +++ b/marshmallowing/Week03/chapter03.md @@ -0,0 +1,206 @@ +# 6장: 광고 클릭 이벤트 집계 + +> 디지털 광고의 핵심 프로세스는 RTB(Real-Time-Bidding), 즉 실시간 경매라고 부른다. 이 경매 절차를 통해 광고가 나갈 지면(inventory)을 거래한다. 온라인 광고에 사용되는 핵심 지표로는 CTR(클릭률), CVR(전환률) 등이 있으며, 집계된 광고 클릭 데이터에 기반하여 계산한다. + +### 질의 API 설계 + +> 클라이언트가 대시보드를 이용하는 순간 집계 서비스에 질의가 발생 +> +- 기능 요구사항 + - 지난 M분 동안 각 ad_id에 발생한 클릭 수 집계 + - 지난 M분 동안 가장 많은 클릭이 발생한 상위 N개 ad_id 목록 반환 + - 다양한 속성을 기준으로 집계 결과를 필터링하는 기능 지원 +1. 지난 M분간 각 ad_id에 발생한 클릭 수 집계 + + : `GET /v1/ads/{:ad_id}/aggregated_count` + +2. 지난 M분간 가장 많은 클릭이 발생한 상위 N개 ad_id 목록 + + : `GET /v1/ads/popular_ads` + + +### 데이터 모델 + +- 원시 데이터 + - 장점: 원본 데이터를 손실 없이 보관, 데이터 필터링 및 재계산 지원 + - 단점: 막대한 데이터 용량, 낮은 질의 성능 +- 집계 결과 데이터 + - 장점: 데이터 용량 절감, 빠른 질의 성능 + - 단점: 데이터 손실- 원본 데이터가 아닌 계산/유도된 데이터를 저장하는 데서 오는 결과 + +> 두 데이터 모두 저장하는 방식을 추천한다. 원시 데이터는 양이 많으므로 질의를 할때는 집계 결과 데이터를 이용하며 원시 데이터의 경우 디버깅용이나 백업 데이터로 활용할 수 있다. 집계 결과 데이터는 활성 데이터 역할로, 질의 성능을 높이기 위해 튜닝한다. +> + +### 올바른 데이터베이스 + +- 원시 데이터 + - 평균 쓰기 QPS는 10000, 최대 QPS는 50000 + - 백업과 재계산 용도로, 쓰기 중심 시스템 + - 쓰기 및 범위 질의에 최적화된 카산드라, InfluxDB +- 집계 데이터 + - 시계열 데이터로, 읽기 연산과 쓰기 연산 둘 다 많이 사용 + - 각 광고에 대해 매 분마다 데이터베이스에 질의를 던져 고객(광고주)에세 최신 집계 결과를 제시 + - 총 200만개의 데이터로, 읽기 연산 매우 빈번 + - 집계 서비스가 데이터를 매 분 집계하고 그 결과를 기록하므로 쓰기 작업도 매우 빈번 + +--- + +## 개략적 설계안 + +집계 서비스에서 실시간으로 빅데이터를 처리할 때, 입력은 원시 데이터(무제한 데이터 스트림)이고, 출력은 집계 결과이다. + +### 비동기 처리 + +동기식 시스템의 경우, 특정 컴포넌트의 장애는 전체 시스템 장애로 이어진다. 트래픽이 갑자기 증가하여 발생하는 이벤트 수가 소비자의 처리 용량을 훨씬 넘어서는 경우, 소비자는 예기치 않은 문제를 겪게 된다. + + + +> 로그 감시자, 집계 서비스, 데이터베이스는 두 개의 메시지 큐로 분리되어 있다. 데이터베이스 기록 프로세스는 메시지 큐에서 데이터를 꺼내 데이터베이스가 지원하는 형식으로 변환한 다음 기록하는 역할을 수행한다. +> + +![원통 모양이 메시지 큐](attachment:9cb14994-8d86-40ba-aa41-30c08a7c5ae4:image.png) + +원통 모양이 메시지 큐 + +- 첫번째 메시지 큐 + - 광고 클릭 이벤트 데이터 +- 두번째 메시지 큐 + - 분 단위로 집계된 광고 클릭 수 + - 분 단위로 집계한, 가장 많이 클릭한 상위 N개 광고 + + + +### 집계 서비스 + +> 광고 클릭 이벤트를 집계하는 방안으로 **맵리듀스 프레임워크**를 활용할 수 있다. 맵리듀스 프레임워크에 좋은 모델은 유향 비순환 그래프(**DAG**)다. DAG 모델의 핵심은 시스템을 맵/집계/리듀스/ 노드 등의 작은 컴퓨팅 단위로 세분화하는 것이다. 각 노드는 한 가지 작업만 처리하며, 처리 결과를 다음 노드에 인계한다. +> +- **맵 노드** + - 데이터 출처에서 읽은 데이터를 필터링하고 변환하는 역할을 담당 + - 입력 데이터를 정리하거나 정규화해야 하는 경우에 필요 + - 데이터가 생성되는 방식에 대한 제어권이 없는 경우에 동일한 ad_id를 갖는 이벤트가 서로 다른 카프카 파티션에 입력될 수도 있어서 맵 노드가 필요 +- **집계 노드** + - ad_id별 광고 클릭 이벤트 수를 매 분 메모리에서 집계한다 + - 맵리듀스 패러다임에서 집계노드는 사실 리듀스 프로세스의 일부 +- **리듀스 노드** + - 모든 집계 노드가 산출한 결과를 최종 결과로 축약 + - 집계 노드 각각은 자기 관점에서 가장 많은 클릭이 발생한 광고 3개를 추려 리듀스 노드로 보내고, 리듀스 노드는 그 결과를 모아 최종적으로 3개의 광고만 남긴다 + +> **DAG**는 맵리듀스 패러다임을 표현하기 위한 모델로, 빅데이터를 입력으로 받아 병렬 분산 컴퓨팅 자원을 활용하여 빅데이터를 작고 일반적 크기 데이터로 변환할 수 있게 설계된 모델이다 +> +- 클릭 이벤트 수 집계 + - 멥 노드는 시스템에 입력되는 이벤트를 (ex: ad_id%3을 기준으로) 분배하며, 분배한 결과는 각 집계 노드가 집계 +- 가장 많이 클릭된 상위 N개 광고 반환 + - 입력 이벤트는 ad_id 기준으로 분배되고 각 집계 노드는 힙을 내부적으로 사용해 상위 3개 광고를 식별한다. 마지막 단계의 리듀스 노드는 전달 받은 9개 가운데 가장 많이 클릭된 광고 3개를 골라낸다. +- 데이터 필터링 + - 필터링 기준을 사전에 정의한 후 기준에 따라 집계 + - 해당 기법을 스타 스키마라 부르며, 데이터웨어하우스에서 주로 쓰이는 기법으로 필터링에 사용되는 필드는 차원(id-mension)이라 부른다 + +--- + +## 상세 설계 + +### 스트리밍 VS 일괄 처리 + +> 스트림 처리는 데이터를 오는 대로 처리하고 서의 실시간으로 집계된 결과를 생성하는 데 사용한다. 일괄 처리는 이력 데이터를 백업하기 위해 활용한다. +> +- 람다 아키텍처 + - 일괄 및 스트리밍 처리 경로를 동시에 지원하는 시스템 아키텍처 + - 두 가지 처리 경로를 지원하므로 유지 관리해야하는 코드가 두배이다 +- 카파 아키텍처 + - 일괄 처리와 스트리밍 처리 경로를 하나로 결합하여 위 문제를 해결 + - **단일 스트림 처리 엔진**을 사용하여 실시간 데이터 처리 및 끊임없는 데이터 재처리 문제를 모두 해결 + +### 데이터 재계산 + +> 이미 집계한 데이터를 다시 계산해야 하는 경우, 이를 이력(history) 데이터 재처리라고 부른다. 집계 서비스에 버그가 발생 시, 버그 발생 시점부터 원시 데이터를 다시 읽어 집계 데이터를 재계산하고 고쳐야 할 것이다. +> +1. 재계산 서비스는 원시 데이터 저장소에서 데이터를 검색한다. 일괄 처리 프로세스를 따른다. +2. 추출된 데이터는 전용 집계 서비스로 전송된다. 전용 집계 서비스를 두는 것은 실시간 데이터 처리 과정이 과거 데이터 재처리 프로세스와 간섭하는 일을 막기 위해서다. +3. 집계 결과는 두 번째 메시지 큐로 전송되어 집계 결과 데이터베이스에 반영된다. + +재계산 프로세스는 데이터 집계 서비스를 재사용하기는 하지만 처리 대상 데이터는 다른 곳에서 읽는다. (원시 데이터를 직접 읽는다) + +### 시간 + +- 이벤트 발생 시각: 광고 클릭이 발생한 시각 + - 광고 클릭 시점을 정확히 아는 것은 클라이언트이므로 집계 결과가 보다 정확 + - 클라이언트가 생성한 타임스탬프에 의존하는 방식이므로 위험성 존재 +- 처리 시각: 집계 서버가 클릭 이벤트를 처리한 시스템 시각 + - 서버 타임스탬프이므로 안정적 + - 이벤트가 시스템에 도착한 시각이 한참 뒤인 경우 (네트워크 지연, 비동기 환경..) 부정확 + +> 데이터의 정확도를 위해 책에서는 이벤트 발생 시각을 이용 +> +- **워터마크** + - 시스템에 늦게 도착한 이벤트를 올바르게 처리하기 위한 기술 + - 집계 윈도우의 확장으로 집계 결과의 정확도 향상 + - 집계 윈도우 + - 광고 클릭 이벤트를 1분 단위로 끊음 + - 이벤트가 집계 윈도우가 끝나는 시점보다 살짝 늦을 경우 누락되는 이벤트 발생 + - 워터마크의 구간이 길면 늦게 도착하는 이벤트 포착 가능하지만 시스템의 이벤트 처리 시간은 늘어남 + - 짧을 시 데이터 정확도는 떨어지지만 응답 지연 낮아짐 + +### 집계 윈도우 + +- 텀블링 윈도우 + - 시간을 같은 크기의 겹치지 않는 구간으로 분할한 것 +- 슬라이딩 윈도우 + - 데이터 스트림을 미끄러져 나아가면서 같은 시간 구간 안에 있는 이벤트를 집계 + - 서로 겹칠 수 있음 + +### 전달 보장 + +> 약간의 중복이 괜찮다면 ‘최소 한 번’이 적절하지만 이 설계안에서는 데이터의 정확성과 무결성이 중요하기에 (데이터의 작은 차이로 큰 과금 이어질 수 있다) ‘정확히 한 번’ 방식을 권장한다. +> +- 데이터 중복 제거 + - 중복된 데이터가 발생하는 경우 + - 클아이언트: 한 클라이언트가 같은 이벤트를 여러번 전송 + - 악의적 전송의 중복 이벤트 처리하기 위해 광고사기/위험제어 컴포넌트 존재 + - 서버 장애: 집계 도중에 집계 서비스 노드에서 장애가 발생하였고 업스트림 서비스가 이벤트 메시지에 대해 응답을 받지 못하였다면, 같은 이벤트가 다시 전송되어 재 집계 될 가능성 존재 + +### 시스템 규모 확장 + +- **메시지 큐의 규모 확장** + - 생산자: 생산자 인스턴스 수에는 제한을 두지 않으므로 확장성 쉽게 달성 가능 + - 소비자: 소비자 그룹 내의 재조정 매커니즘은 노드 추가/삭제를 통해 규모를 쉽게 조정 가능 +- **브로커** + - 해시키 + - ad_id를 해시키로 사용하면 집계 서비스는 같은 ad_id를 갖는 이벤트를 전부 같은 파티션에서 구독 가능하다 + - 파티션의 수 + - 사전에 충분한 파티션 확보 필요 (동적 증가 피하기) + - 토픽의 물리적 샤딩 + - 데이터를 여러 토픽으로 나누면 시스템의 처리 대역폭 높일 수 있음 + - 복잡성과 유지 관리 비용 증가하는 단점 +- **집계 서비스의 규모 확장** + - ad_id마다 별도의 처리 스레드 구성 + - 집계 서비스 노드를 아파치 하둡 YARN 같은 자원 공급자에 배포해 다중 프로세싱을 활용 +- **데이터베이스의 규모 확장** + + 카산드라는 안정 해시와 유사한 방식으로 수평적 규모 확장 지원 + + - 데이터와 사본은 각 노드에 균등 분산 + - 각 노드는 해시 링 위의 특정 해시 값 구간의 데이터 보관을 담당하며 다른 가상 노드의 데이터 사본도 보관 + - 클러스터에 새 노드 추가 시 가상 노드 간 균형 자동 조정 + +- **핫스팟 문제** + + 다른 서비스나 샤드보다 더 많은 데이터를 수신하는 서비스나 샤드 + + - 서버 과부하 문제 발생 가능 + - 더 많은 집계 서비스 노드를 할당하여 완화 가능 +- **결함 내성** + + 집계는 메모리에서 이루어지므로 집계 노드에 장애가 생기면 집계 결과도 소실 + + - 업스트림 카프카 브로커에서 이벤트를 다시 받아오면 숫자 재생 가능 + - 업스트림 오프셋같은 시스템 상태를 스냅숏으로 저장하고 마지막으로 저장된 상태부터 복구 \ No newline at end of file diff --git a/marshmallowing/Week03/references03.md b/marshmallowing/Week03/references03.md new file mode 100644 index 0000000..b74379c --- /dev/null +++ b/marshmallowing/Week03/references03.md @@ -0,0 +1,161 @@ +# **이벤트 기반 아키텍처 (EDA)** + +[[배민스토어] 배민스토어에 이벤트 기반 아키텍처를 곁들인… | 우아한형제들 기술블로그](https://techblog.woowahan.com/13101/?utm_source=chatgpt.com) + +## **MSA** + +- MicroService Architecture +- **서비스의 단위를 작게 도메인별로 시스템을 구현하는 방식**으로 대다수의 기업들이 시스템 아키텍처를 이 방식으로 구현 + +> 배민의 경우 서비스 간의 통신을 효율적으로 하기 위하여 Kafka를 사용하고 있으며, 배민스토어의 상품을 빠르게 노출하기 위해 DynamoDB, Redis를 활용 +> + +### 배민 스토어 + +![image.png](attachment:c53a184e-0182-4998-8881-96d81daaa2b8:image.png) + +- 상품 데이터, 리뷰 평점 및 리뷰 데이터, 지역별 가게 정보, 쿠폰 데이터 .. +- 다른 도메인들과 데이터를 주고받으며 안정적인 서비스 구현 필요 +- 일반적으로 MSA 구조에서는 HTTP API를 활용하여 다른 도메인들과 데이터를 주고 받음 + + + +## 전시 도메인 + +**데이터가 변경되는 시점에 사용자들에게 바로 노출하는 것을 중요하게 여긴다** + +- 트랜잭션을 보장이 필요한 로직도 많지 않다 + +### CQRS 패턴 + +데이터 저장소에 대한 읽기 및 업데이트 작업을 구분하는 패턴인 명령과 쿼리의 역할 분리를 의미 + +- 애플리케이션에서 CQRS를 구현하면 성능, 확장성 및 보안을 최대화할 수 있음 +- CQRS로 마이그레이션하면 유연성이 생기므로 시스템이 점점 진화하고 업데이트 명령이 도메인 수준에서 병합 충돌을 일으키지 않도록 할 수 있음 + +> 배민스토어 개편 당시 시스템 아키텍처를 **ReadModel, WriteModel을 분리하여 ReadModel을 전시 영역에 알맞게 최적화**하기로 했다. 분리 할 시 전시 도메인의 영역에서 사용되는 데이터는 컴퓨팅 리소스를 읽기에만 활용하기 때문에 효율적으로 데이터를 읽을 수 있다. 이를 기반으로 Kafka를 활용하여 이벤트 기반으로 ReadModel을 구성하는 방향으로 진행하기 시작했다. +> + +## **이벤트 기반 아키텍처(EDA)** + +### 이벤트란? + +- 일어난 일의 기록 +- 변경 또는 삭제할 수 없는 변경 불가능한 사실을 캡처 +- 이벤트 소비 시 서비스가 적용하는 로직에 관계없이 발생 +- 무기한 대규모로 유지되며 필요한 만큼 사용할 수 있음 + +![image.png](attachment:d8403f0e-6d3c-44ff-9391-1c98bd00358d:image.png) + +배민 스토어에서는 한 명의 사용자가 `배민스토어에서 [상품을 클릭하고] - [상품을 장바구니에 담고] - [상품을 구매(주문) 하고] - [상품을 결제하고] - [상품을 배송받아 배송 메세지를 확인]` 까지 대략적으로 총 5개의 이벤트를 구성할 수 있다. + + + +### **이벤트 기반 아키텍처(EDA) 이점** + +- **MSA 환경에서 도메인 간에 느슨한 결합을 할 수 있다** + - 이벤트를 발행하는 도메인과 소비하는 도메인이 서로 독립적인 배포를 할 수 있는 시스템으로 설계할 수 있게 된다. +- 발행 또는 구독하는 시점을 지정할 수 있다 +- 비동기 이벤트 기반으로 복원력이 존재한다 + - 각 도메인별로 비동기식으로 시스템 별로 응답을 기다리지 않고, 소비하는 도메인에서 이벤트를 수신하여 사용할 수 있을 때 활용되기 때문에 타 시스템의 영향을 크게 끼치지 않음 + +### **배민스토어의 이벤트 기반 아키텍처(EDA)** + +![image.png](attachment:f75b61c6-9cb1-41cd-89be-d607b247dbb8:image.png) + +1. 각각의 MSA 시스템별로 각 도메인별 필수 데이터들을 수신 (MSA 시스템 -> Domain Event 발행) + - 각 도메인 서비스는 **자신이 소유한 데이터에 변경이 발생했을 때**, 그 변경 사실을 다른 서비스에 직접 알려주지 않고 **Domain Event 형태로 발행** (도메인에서 발생한 변경 사실 기록) + + + +2. 배민스토어 전시 시스템에서는 해당 이벤트들을 구독(수신)하고 이를 필요한 데이터별로 ReadModel로 변환 처리 + - 수신한 이벤트를 그대로 사용하지 않고, 전시 화면에 필요한 정보만 선별·가공하여 **전시 전용 ReadModel 형태로 변환**한다 + +```java +Seller { + sellerId: "1", + sellerName: "배민스토어", + serviceType: "배민스토어", + logoImageUrl: "https://techblog.woowahan.com/" + sellerPaymentType: ["카드결제", "복합결제"] +} + +data class Seller( + val sellerId: String, + val sellerName: String, + val logoImageUrl: String, + val serviceType: SellerType, + ... +) +``` + +불필요한 데이터는 수신할 필요가 없기 때문에 데이터 변환을 거친 후에 정말로 필요한 데이터(DTO)를 기반으로, 전시에서 필수로 노출되어야하는 데이터로 **ReadModel**를 구성한다. + + + +![생성된 ReadModel은 DynamoDB 및 Redis에 순차적으로 저장한 뒤 고객에게 서빙하게 된다.](attachment:0d4890a6-f489-411e-a2e4-bf2bec84dbd0:image.png) + +생성된 ReadModel은 DynamoDB 및 Redis에 순차적으로 저장한 뒤 고객에게 서빙하게 된다. + +### 2개의 데이터 저장소를 구상한 이유 + +- DynamoDB + - 일관된 10밀리초 미만 성능, 무제한 처리량의 강점 +- Redis + - 메모리를 이용하여 빠른 데이터를 쓰고, 조회하는 액세스 패턴에서 사용이 가능 + +*⇒ 단일 장애점(SOPF) 문제점을 발생시키지 않기 위해서 Redis에 장애 발생 시 DynamoDB 데이터 기준으로 안전하게 FallBack을 할 수 있게 된다* + +## **Kafka – Producer & Consumer** + +> Seller(본사 정보), Shop(지점 정보)의 정보가 변경되었을 때 **Producer**를 통해서 이벤트가 **Kafka Cluster**에 도달하게 되고 본사 정보 및 지점 정보를 구독하는 **Consumer**가 이벤트를 수신하여 DynamoDB 및 Redis에 데이터를 순차적으로 저장하는 방식 +> +- **이벤트가 발행되었던 시점에 데이터가 캡처**되어 해당 데이터를 구독할 수 있는 장점 + - 이벤트가 재구독 되더라도 동일한 데이터 수신 가능 +- 데이터의 정합성 해칠 수 있는 위험 존재 + - 이벤트의 순서가 보장되지 않는 상황에서 **이벤트의 순서가 역전**되는 현상이 발생 가능 + + + +### **Zero Payload** + +**이벤트 Body에 데이터가 없는 형태로 수신되는 것** + +- 결과적으로 최종 변경된 이벤트를 기반으로 항상 최신의 데이터를 갱신해 이전의 이벤트 순서 문제점을 해결 가능 + + *⇒ 이벤트를 데이터 전달 수단이 아니라 데이터가 변경되었다는 알림으로 사용하여 순서 문제를 해결* + + 1. **알림 수신**: "광고 클릭 데이터가 업데이트되었습니다"라는 빈 메시지(ID만 포함)를 받음 + 2. **직접 조회 (Pull)**: 수신자는 해당 ID를 가지고 광고 서버나 DB(Master)에 **현재 최신 데이터가 무엇인지 직접 조회** + 3. **순서 무력화**: + - 만약 1번 이벤트(과거)와 2번 이벤트(현재)의 순서가 바뀌어서 도착하더라도, 수신자는 메시지를 받을 때마다 DB를 조회하므로 **언제나 조회 시점의 가장 최신 데이터**를 가져오게 된다 + - 즉, 늦게 온 1번 이벤트를 처리할 때도 결과적으로는 2번 이벤트에 의해 갱신된 최신 값을 읽게 되므로 데이터 정합성이 깨지지 않음 +- 이벤트에 대한 스키마 스펙이 자주 변경되면 유연하게 스펙 변경에 대처할 수 있는 장점 + +> 데이터 저장 시 실시간으로 HTTP API 호출을 통하여 변경된 이벤트 중 가장 마지막 정보를 DynamoDB, Redis에 저장하여 사용자에게 올바르게 데이터를 노출하게 된다. +> \ No newline at end of file diff --git a/marshmallowing/Week05/chapter05.md b/marshmallowing/Week05/chapter05.md new file mode 100644 index 0000000..f22c160 --- /dev/null +++ b/marshmallowing/Week05/chapter05.md @@ -0,0 +1,155 @@ +# 5장: 지표 모니터링 및 경보 시스템 +- **구성요소** + - 데이터 수집: 여러 출처로부터 지표 데이터 수집 + - 데이터 전송: 지표 데이터를 지표 모니터링 시스템으로 전송 + - 데이터 저장소: 저장되어 오는 데이터를 정리하고 저장 + - 경보: 밀려오는 데이터를 분석하고, 이상 징후를 감지하고, 경보를 발생시킴 + - 다양한 통신 채널로 경보 발생 + - 시각화: 데이터를 차트나 그래프 등으로 제공 + +> 지표 데이터는 통상 시계열 데이터 형태로 기록한다 +> + +| 이름 | 자료형 | +| --- | --- | +| 지표 이름 | 문자열 | +| 태그/레이블 집합 | <키:값> 쌍의 리스트 | +| 지표 값 및 그 타임스탬프의 배열 | <값, 타임스탬프> 쌍의 배열 | + +### 개략적 설계안 + +- 지표 출처: 지표 데이터가 만들어지는 곳으로 애플리케이션 서버, SQL 데이터베이스, 메시지 큐 등 어떤 것이든 가능 +- 지표 수집기: 지표 데이터를 수집하고 시계열 데이터에 기록하는 역할 +- 시계열 데이터베이스: 지표 데이터를 시계열 데이터 형태로 보관하는 저장소 + - 다량의 시계열 데이터를 분석하고 요약하는데 적합하도록 설계된 질의 인터페이스 제공 +- 질의 서비스: 시계열 데이터베이스에 보관된 데이터를 질의하고 가져오는 과정을 돕는 서비스 +- 경보 시스템: 경보를 받아야 하는 다양한 대상으로 경보 알림을 전송하는 역할 +- 시각화 시스템: 지표를 다양한 형태로 시각화 하는 기능 제공 + +--- + +## 지표 수집 + +### 풀 모델 + +**실행 중인 애플리케이션에서 지표 수집기가 주기적으로 지표 데이터를 가져온다** + +- 지표 수집기 서버 안에 모든 서비스 엔드포인트의 DNS/IP 정보를 담은 파일을 두어 데이터를 가져올 서비스 목록을 파악 가능 +- 위 방법은 대규호 환경에선 용이하지 않아, etcd나 아파치 주키퍼 같은 서비스 탐색 기술 활용 + - 각 서비스는 자신의 가용성 관련 정보를 서비스 탐색 서비스(SDS)에 기록하고, SDS는 서비스 엔드포인트 목록에 변화가 생길 때마다 지표 수집기에 통보 + - SDS: 언제 어디서 지표를 수집하면 되는지에 관한 설정 정보 기록 +1. 지표 수집기는 SDS에서 서비스 엔드포인트 설정 메타데이터 목록을 가져온다 + + -각 메타 데이터는 지표 수집 주기, IP 주소, 타임아웃, 재시도 인자 등이 기록되어 있다 + +2. 지표 수집기는 사전에 합의된 HTTP 엔드포인트에서 지표 데이터를 가져온다 + + -엔드포인트를 수집기에 노출하기 위해, 통상 서비스에 특정 클라이언트 라이브러리를 추가한다 + +3. 지표 수집기는 서비스 엔드포인트 목록의 변화를 통지 받기 위한 변경 이벤트 알림 콜백을 서비스 탐색 컴포넌트에 등록한다 + +> 여러 지표 수집기 서버를 둘 때 문제점은 여러 서버가 같은 출처에서 데이터를 중복해서 가져올 가능성이 있다. 따라서 지표 수집 서버 간에 중재 매커니즘이 존재해야 한다. ⇒ *해시 링* +> + + + +### 푸시 모델 + +**웹 서버나 데이터베이스 서버 같은 서버가 직접 지표를 수집기에 전송하는 모델** + +- 모니터링 대상 서버에 통상 수집 에이전트라고 부르는 소프트웨어를 설치 + - 수집 에이전트는 해당 장비에서 실행되는 서비스가 생산하는 지표 데이터를 받아 모은 다음 주기적으로 수집기에 전달 + - 데이터 집계는 수집기에 보내는 데이터의 양을 줄이는데 효과적 + - 데이터 전송 트래픽이 막대하여 일시적으로 수집기가 전송되는 데이터를 처리하지 못하게 되어 오류를 반환하면, 에이전트는 내부의 소규모 버퍼에 데이터를 일시적으로 보관한 다음 나중에 재전송 가능 + +> 푸시 모델에서 지표 수집기가 밀려드는 지표 데이터를 제때 처리하지 못하는 일을 방지하려면, 지표 수집기 클러스터 자체도 자동 규모 확장이 가능하도록 구성하고 그 앞에 로드밸런서를 두는 것이 바람직하다 +> + +### 풀 모델 VS 푸시 모델 + +- 풀 모델: 프로메테우스 + - 엔드포인트를 설정하면 언제든 지표데이터를 볼 수 있으므로 디버깅 쉬움 + - 풀 요청에 응답하지 않으면 해당 서버에 장애가 발생한 것이므로 상태 진단 쉬움 + - 일반적으로 TCP +- 푸시 모델: 아마존 클라우드와치, 그래파이트 + - 지표를 받지 못하면 그 원인 알기 어려워 상태 진단 어려움 + - 로드밸런서 및 자동 규모 확장 클러스터 형태로 구성되었다면 어디서 오는 지표라도 수집 가능 + - 일반적으로 UDP를 사용해 전송 지연 더 낮음 + +## 지표 전송 파이프라인의 규모 확장 + +> 지표 수집기는 서버 클러스터 형태이며 엄청난 양의 데이터를 받아 처리해야하며 자동으로 규모 확장이 가능하도록 설정하여 언제나 데이터 처리에 충분한 수집기 서버가 존재하도록 해야한다. 하지만 시계열 데이터베이스에 장애가 생기면 데이터 손실이 발생할 가능성이 있으므로 큐를 두면 그런 문제를 해결할 수 있다. +> + + + +- 위 설계안의 장점 + - 카프카는 고도로 안정적이고 규모 확장성이 뛰어난 분산 메시지 플랫폼 + - 데이터 수집 컴포넌트와 처리 컴포넌트 사이의 결합도를 낮춘다 + - 데이터베이스에 장애가 생겨도 데이터는 소실되지 않는다 + - 카프카에 보관 + +### 카프카를 통한 규모 확장 + +- 대역폭 요구사항에 따라 파티션의 수를 설정한다 +- 지표 이름에 따라 어떤 지표를 어느 파티션에 배치할지 결정하면 소비자는 지표 이름에 따라 데이터를 집계할 수 있다 +- 태그/레이블에 따라 지표데이터를 더욱 세분화한 파티션으로 나눈다 +- 중요 지표가 먼저 처리될 수 있도록 분류하고 우선순위를 지정한다 + +## 데이터 집계 지점 + +- 수집 에이전트가 집계 + - 클라이언트에 설치된 수집 에이전트는 복잡한 집계 로직 수행 어려움 +- 데이터 수집 파이프라인에서 집계 + - 데이터를 저장소에 기록하기 전에 집계할 수 있으려면 스트림 프로세싱 엔진 필요 + - 데이터베이스에는 계산 결과만 기록되므로 실제로 기록되는 양은 엄청나게 감소 + - 하지만 늦게 도착하는 지표 데이터의 처리가 어렵고, 원본 데이터를 보관하지 않으므로 정밀도나 유연성 측면에서 손해 +- 질의 시에 집계 + - 데이터를 날것 그대로 보관한 다음 질의할 때 필요한 시간 구간에 맞게 집계 + - 데이터 손실 문제는 없으나 질의를 처리하는 순간에 전체 데이터세트를 대상으로 집계 결과를 계산해야 하므로 속도 느림 + +## 질의 서비스 + +질의 서버 클러스터 형태로 구현되며 시각화 또는 경보시스템에서 접수된 요청을 시계열 데이터베이스를 통해 처리하는 역할 + +- 질의 처리 전담 서비스를 두면 클라이언트와 시계열 데이터베이스 사이의 결합도 낮출 수 있음 +- 캐시 계층: 질의 결과를 저장할 캐시 서버를 도입하면 시계열 데이터베이스에 대한 질의 부하를 낮추고 질의 서비스의 성능 높일 수 있음 + +## 저장소 계층 + +> 운영 데이터 저장소에 대한 질의의 85%는 지난 26시간 내에 수집된 데이터를 대상으로 한다 +> + +### 저장 용량 최적화 + +- 데이터 인코딩 및 압축 +- 다운샘플링 + - 데이터의 해상도를 낮춰 저장소 요구량을 줄이는 기법 + - 낡은 데이터는 해상도를 줄여 보관 +- 냉동 저장소 + - 잘 사용되지 않는 비활성 상태 데이터를 보관하는 곳 + +## 경보 시스템 + +### 경보 처리 흐름 + +1. 설정 파일을 가져와 캐시 서버에 보관한다. 경보 규칙은 디스크에 파일 상태로 보관하며, 규칙을 정의하는 데는 YAML이 사용된다. +2. 경보 관리자는 경보 설정 내역을 캐시에서 가져온다 +3. 설정된 규칙에 근거하여 경보 관리자는 지정된 시간마다 질의 서비스를 호출한다. 그리고 그리고 질의 결과가 설정된 임계값을 위반하면 경보 이벤트를 생성한다. + - 경보 필터링, 병합, 중복 제거 + - 접근 제어 + - 재시도 - 경보 상태를 확인하고 알림이 최소 한번 전달 됨을 보장해야 한다 +4. 경보 저장소는 카산드라 같은 형태의 키-값 저장소이다. 모든 경보의 상태가 여기 보관된다. 알림이 적어도 한 번 이상 전달되도록 보장하는 구실을 한다 +5. 경보 이벤트를 카프카에 전달한다 +6. 경보 소비자는 카프카에서 경보 이벤트를 읽는다 +7. 경보 소비자는 카프카에서 읽은 경보 이벤트를 처리하여 다양한 채널로 알림을 전송한다 \ No newline at end of file diff --git a/marshmallowing/Week05/references05.md b/marshmallowing/Week05/references05.md new file mode 100644 index 0000000..db474bb --- /dev/null +++ b/marshmallowing/Week05/references05.md @@ -0,0 +1,218 @@ +# AWS와 OpenTelemetry 기반 모니터링 + +[Best Practices for Monitoring with AWS and OpenTelemetry](https://www.sawmills.ai/blog/best-practices-for-monitoring-with-aws-and-opentelemetry?utm_source=chatgpt.com) + +이 글은 AWS 환경과 OpenTelemetry를 기반으로 효과적인 모니터링 전략을 구축하는 방법을 포괄적으로 설명한다. + +단순히 메트릭을 수집하는 것에 그치지 않고, 운영 관점에서 실질적 의미를 가지는 데이터로 전환하고, 알림 전략을 설계하며, 대시보드와 트레이싱을 결합해 문제 해결을 가속화하는 방법을 다루고 있다. + +--- + +## **모니터링 기준선(Baseline) 설정** + +시스템 상태를 평가하기 위한 기준선을 정의한다. 기준선은 단순 임계값이 아니라 서비스 수준 목표(SLO: Service Level Objectives)를 기반으로 한다. + +- **SLO(Service Level Objectives) 수립** + + 비즈니스에 직결되는 핵심 지표를 설정한다 + + - **가용성(Availability)**: 중요 서비스는 99.9% 이상의 가용성 목표 + - **지연 시간(Latency)**: 사용자 API는 P95((전체 요청 중 상위 5%) 응답시간 < 500ms로 설정 + - **에러율(Error Rate)**: 프로덕션 서비스의 에러율 < 1% 유지 + - **처리량(Throughput)**: 요청률을 통해 용량과 성능 변화 감지 +- **Error Budget 활용** + - SLO를 기반으로 '허용 가능한 오류량'인 에러 버짓을 계산 + - 배포 속도와 시스템 안정성 사이의 의사결정 도구로 활용 +- **CloudWatch Anomaly Detection** + - 과거 데이터를 학습하여 상한/하한선을 자동으로 긋는 이상 탐지 알람을 적용 + - 단순 임계값 알람의 한계를 극복 + + +## **포괄적 경보(Alerts) 전략 구현** + +알림을 *무작위로 울리는 신호*가 아닌 **실행 가능하고 즉각적인 대응 지점을 제공하는 도구**로 설계한다. + +### 다양한 경보 레벨 + +경보는 목적과 기대되는 대응 시간에 따라 체계적으로 분류해야 한다 + +**심각도(Severity) 기반 계층화**: + +- **P0: Critical (즉각 대응)** + + > 예: 에러율이 5%를 초과하는 경우 + > + > + > 즉각적인 On-call 호출로 유료 결제 실패 등 비즈니스 정지 상황 +> +- **P1: Warning (단기 조사)** + + > 예: P95 Latency가 1초 이상 지속 + > + > + > 빠른 분석을 통해 퍼포먼스 저하 징후를 파악 +> +- **P2: Informational (추세 관찰)** + + > 예: 트래픽 패턴이 비정상적으로 변화 + > + > + > 추세를 파악하거나 새로운 패턴을 이해하는 데 유용 +> + + + +### 경보 소음(Alert Fatigue) 완화 전략 + +- **정적 임계값 대신 이상 탐지(Anomaly Detection)** 적용 + - 갑작스러운 패턴 변화 등을 자동으로 감지 +- **경보 그룹핑/상관관계(Alert Correlation)** + - 관련 경보를 하나의 이슈로 묶어 노이즈 감소 +- **메인터넌스 윈도우 유지** + - 배포/점검 시간 동안 불필요한 경고 억제 +- **에스컬레이션 정책** 정의 + - 일정 시간이 지나면 더 높은 레벨로 자동 전달 +- **정기 경보 리뷰/클린업** + - 오랜 기간 사용되지 않았거나 의미 없는 경보 제거 + +## **분산 추적(Distributed Tracing) 적용** + +마이크로서비스가 복잡하게 얽힌 환경에서 **단일 요청의 전체 경로를 시각화하고 성능 병목을 파악**한다. + +> 사용자 요청 → API Gateway → 인증 서비스 → 주문 서비스 → 결제 서비스 → DB +> + +분산 추적은 단일 요청의 전체 호출 경로를 추적하여 각 서비스에서 소요된 시간, 에러 발생 여부, 의존 관계를 시각적으로 보여준다. 이를 통해 운영자는 **병목 지점과 장애 원인을 구조적으로 파악할 수 있다.** + +### AWS X‑Ray와 OpenTelemetry 통합 + +OpenTelemetry는 데이터를 수집하기 위한 표준 계측 도구이며, AWS X-Ray는 AWS 환경에서 Trace를 수집·시각화하는 서비스다. OpenTelemetry로 애플리케이션을 계측하고, Collector를 통해 X-Ray로 전송하면 다음과 같은 효과를 얻는다 + +```scss +[애플리케이션] + │ + │ (OpenTelemetry로 계측) + ↓ +[Collector] + │ + ↓ +[AWS X-Ray] +``` + +- **서비스 간 의존성 매핑** + - 각 요청이 어떤 서비스를 거쳤는지를 그래프 형태로 시각화한다. + - 분산 상태에서 호출 경로를 시각적으로 분석 가능 +- **Root Cause 분석** + - 느린 요청/에러 발생 지점을 빠르게 식별 + - 요청을 Span 단위로 나누어 기록해 병목 지점을 정확히 특정 가능 + - 각 서비스에서의 처리 시간, DB 쿼리 시간, 외부 API 호출 시간, 에러 발생 위치 +- **샘플링 정책 기반 효율화** + - 분산 추적은 요청 하나당 Trace 하나가 생성되고 트래픽이 높은 서비스에서는 초당 수천 개 Trace가 생성된다. 따라서 모든 요청을 저장하는 것은 비효율적이다. + - **Head Sampling** + - 요청 시작 시 랜덤으로 저장 여부를 결정 + - 비용은 줄지만 가치 있는 Trace를 놓칠 가능성 존재 + - **Tail-Based Sampling** + - 요청이 끝난 뒤 결과를 보고 저장 여부를 결정하는 것으로 결과 기반 선택 + - 저장량은 줄이면서 분석 가치가 높은 Trace는 확보 + +## **모니터링 시스템 자체를 모니터링** + +관측 시스템 자체가 *정상적으로 작동하고 있는지*를 확인한다. + +### 모니터링 대상 + +- Collector/Agent Pod의 **헬스 체크** + - Pod 상태(Running / CrashLoopBackOff 여부) + - 재시작 횟수 증가 여부 + - 서비스 엔드포인트 정상 응답 여부 +- 메모리/CPU 사용률 +- 수집 실패 또는 전송 실패율 + + ```scss + Application → Agent → Collector → Backend 저장소 + ``` + + - 대표적인 장애 상황 + - Collector → Backend 전송 실패 + - Backend 저장소 과부하 + - 네트워크 장애 +- 큐 대기량 + - 큐 길이가 지속적으로 증가한다는 것은 데이터 유입 속도가 처리 속도를 초과하고 있다는 의미 + +> 관측 파이프라인이 중단되면 시스템 전체 모니터링이 마비되므로, **관측 시스템 자체의 경보와 대시보드가 필수적**이다. +> + +## **비즈니스 메트릭과 KPI 연결** + +기술 지표와 **비즈니스 성과 지표를 직접 연결**함으로써 운영 → 비즈니스 가치까지 해석 가능하게 한다. + +### 주요 비즈니스 메트릭 예시 + +- **주문 및 결제 관련 지표** + - 주문 생성 횟수 + - 결제 성공률 + - 결제 실패율 + - 장바구니 → 결제 전환율 +- **매출 영향 장애 분석** + - 특정 API 지연 → 결제 실패율 증가 여부 + - DB 장애 → 주문 생성 감소 여부 + - 인증 오류 → 사용자 이탈 증가 여부 +- **사용자 행동 기반 전환율 분석** + - 페이지 로딩 지연 → 구매 전환율 감소 + - 검색 성능 저하 → 사용자 체류 시간 감소 + - 추천 알고리즘 오류 → 재방문율 감소 + +> 또한 **비즈니스 경보**를 설정하면 기술 이상 여부가 *사용자 및 수익에 어떤 영향*을 미치는지도 바로 알 수 있다. +> + +## **고급 로그 분석** + +로그 데이터를 단순 저장/조회가 아니라 **운영 인사이트 생성 및 이상 탐지**에 활용한다. + +### 로그 활용 예 + +- 느린 DB 쿼리 식별 + - 실행 시간이 긴 쿼리, 반복적으로 호출되는 쿼리, 인덱스 미사용 쿼리 + + ⇒ DB 성능 튜닝, 인덱스 최적화, 캐시 전략 개선 + +- 에러 패턴 분석 + - 특정 API에서 반복적으로 발생하는 예외 + - 특정 사용자 그룹에서 발생하는 오류 + - 특정 시간대에 집중되는 장애 +- 보안 이상 이벤트 탐지 + - 비정상 로그인 시도 + - API 남용 또는 공격 트래픽 +- 사용자 기반 API 사용 패턴 + - 특정 기능 사용 빈도 + - 사용자 이동 경로 분석 + - 인기 API 식별 + +**적절한 로그 보존 전략(Hot/Warm/Cold)도 동시에 설계해야 한다.** + +- Hot Storage + + 장애 대응 및 실시간 모니터링에 활용 + + - 최근 로그 저장 + - 빠른 검색 및 실시간 분석 가능 + - 비용이 가장 높음 +- Warm Storage + + 트렌드 분석 및 감사(Audit)에 활용 + + - 일정 기간 이후 로그 저장 + - 분석 가능하지만 접근 속도 감소 + - 비용 중간 수준 +- Cold Storage + + 법적 보관, 장기 데이터 분석 등에 사용 + + - 장기 보관 로그 저장 + - 접근 속도 느림 + - 비용 최소화 \ No newline at end of file