목록 Architecture (40)
배경알림 서비스 이야기이다.카프카로부터 메시지를 수신하고 이를 사용자에게 전달하는 서비스를 운영하고 있다.네트워크 통신 비용 절감을 위해 카프카에서 메시지를 배치 수신, 그룹 단위로 처리한다.그룹 단위 처리 중 예외가 발생하면 이미 처리한 내용을 잊기에 복구 시 메시지를 중복 수신하게 된다.이에 수신한 메시지 ID를 레디스에 기록하고, 처리 전 비교하는 것으로 이전에 수신했던 메시지 여부를 검증한다.간단한 메시지 ID 저장 구조 변경으로, 레디스 메모리 사용률을 33% 개선한 경험을 소개한다. String vs Hash 기존 구조는 수신한 각 메시지 ID를 레디스 String 타입으로 저장했다.양이 많고, 짧은 보관 기간의 데이터이기에, 각 메시지 ID를 레디스 Key로 하여 TTL을 명확하게 지정했다...
배경나는 아래의 상황에서 카프카를 생각한다.- 처리에 시간이 걸려서 메인 흐름 부에서 분리하고 싶을 때- 서비스 간 안전하고 순서가 보장된 이벤트 전달이 필요할 때 물론 비동기 처리와 이벤트 전달 방법은 많지만 방법마다 다른 제약이 존재한다.- Http : 이벤트를 전달받는 쪽의 상태에 의존적- Redis PS : Fire and Forget. 쏘기만 하고 잘 받았는지는 검증 않음- RabbitMQ : 여러 수신처에서 동일하게 수신하려면 여러 개 큐가 필요. 꼼꼼한 순서 보장을 위해선 단일 컨슈머 필요 카프카를 다루면서 고민해야 하는 포인트가 있다면 다음과 같다.- 브로커 측면 : 파티션 크기, 브로커 성능과 수 - 프로듀서 측면 : 메시지 키, 배치 크기, 배치 간격, 직렬화 방법- 컨슈머 측면 : ..
배경최근 프로젝트로 서버에서 클라이언트로 데이터를 전달해야 하는 요구사항이 생겼다. 좀 더 자세히는 한 B2B 서비스에 우리 회사 카메라 기기의 스트리밍을 제공해야 하는데, 이때 사용자 페이지와 기기 사이의 중개 서버 개발을 맡았고, 서버에서 클라이언트로 네트워크 경로 후보지 전달이 필요했다. 그간 고질이었던 기존 WebSocket 서버 관리 방법을 다시 한번 고민할 수 있는 기회가 되었다. 그 과정에서 AWS의 API Gateway WebSocket을 사용하면 웹 소켓 서버를 직접 관리하지 않아도 됨을 찾을 수 있었다. 생각보다 저렴한 비용과 편한 모니터링, 무엇보다 거의 없다시피 한 관리 포인트에도 안정적인 확장이 가능했다. 이 글에서는 내가 느낀 기존 전통적 방식의 웹 소켓 서비스 운영의 제약을 소..
요구 사항 우리 팀은 IoT 기기를 다룬다. 도어락의 문 열림 기록이나, 온습도계의 일간, 월간 온습도 변화 기록 조회 등, 기기의 상태 기록을 조회할 수 있는 기능을 제공한다. 이런 기능을 위해 ‘히스토리’ 서비스는 기기의 상태 이벤트를 수신하고, 기록해야 할 테이터를 필터링하여 DB에 적재하는 역할을 수행한다. 현재 히스토리 서비스에서 저장해야 하는 이벤트 양은 초당 초당 2600 ~ 2800건이다. 그리고 아래는 현재 히스토리 서비스 초당 처리량이다. 이벤트 유입량과 처리량이 크게 차이가 나지 않음을 알 수 있다. 지금까진 가까스로 처리되었지만, 지금보다 유입량이 조금만 더 많아지면, 유입량이 처리량보다 많아져 이벤트 유실이나 OOM이 발생하기 좋다. 우리 팀의 목표 요구치는 초당 7천 건의 저..
OOM 발생최근 서비스 하나가 말썽이었다. 대략 이벤트를 HTTP로 수신해서, DB와 API를 호출하여 처리 여부를 결정하고 RabbitMQ로 전달하는 중간 파이프라인 역할의 서비스였다. 부끄럽지만 예전에 개발되고 더 이상 건들지 않고 운영되던 히스토리가 없는 코드였다. 갑자기 메모리 사이즈 사용률이 비정상적임을 알리는 경고 메시지를 수신했고, '올게 왔구나' 했다. 가장 먼저 그라파나 대시보드를 살폈다. Heap 메모리와 GC 의 동작을 확인했다. GC 동작 이후에도 Old Gen의 최저 수위가 점점 높아지는 것을 볼 수 있다. Major GC의 처리 대상이 되지 못하는 메모리 영역이 계속 쌓이고 있고, 긴 Stop the world 시간과 함께, Major GC 수행만 반복되는 것을 확인할 수 있다..
배경회사 서비스 중 하나로, IoT 기기를 코드로 조회/제어할 수 있는 API를 제공하고 있다. 서비스가 커지면서 해당 서비스에 과금 정책을 도입하여, 서버 비용을 충당하고, 과하게 리소스를 사용하는 사용자를 제한하고자 한다. 나는 포인트 결제, 차감, 보상 처리를 맡아, 잔여 포인트를 확인하고 처리를 제한하거나, 포인트를 차감하는 트랜잭션 처리를 개발하고 있다. 개발 요구 사항은 아래와 같다.1. 사용자의 잔여 포인트를 조회하고 사용량만큼 차감되어야 한다.2. 잔여 포인트 부족 시, 비즈니스 로직이 수행되어선 안된다.3. 서버 문제로 비정상 응답을 반환할 경우, 포인트는 차감되어선 안된다. 문제 시나리오, 차감과 보상 사이의 포인트 부족 현상서버 이상으로 비정상 응답이 반환될 때는 포인트가 차감되어선..
처리량 개선이 필요하다.회사가 성장하며 기기 이벤트가 크게 늘었다. 8개월 전까지만 해도 초당 1500건이었던 기기 이벤트가, 이제는 3500건을 넘는다. 한 달 동안의 이벤트 수 변화량만 보더라도, 그 수위가 점점 높아지는 것을 볼 수 있다. 기존 인프라와 로직으로는 늘어난 유입량을 못 따라가고, 곧 지연과 유실로 이어진다. 이벤트 컨슘부터 Ack까지의 흐름 안에는 다양한 로직들이 있다. 그래서 '어떤 구간이 문제다!'라기보다는, 주변 영향을 최소화하면서도 효과적인 개선 방향을 고민한다. 물론 어떤 경우에는 단순히 인프라만 늘리면 해결되는 경우도 많다. 프로세스를 더 띄우고, 스레드 수를 늘리는 게 제일 빠를 수도 있겠지만, 최대한 주어진 자원 안에서 개선하는 방법을 고민하는 게 요즘 우리 팀의 방향..
이벤트 파이프라인우리 회사 기기는 삼성의 Smartthings, LG의 ThinQ, KT, Genie, Kakao, Clova 등 여러 IoT 플랫폼에서 연동되어 사용된다. 서버는 기기의 이벤트를 외부 서버에 전달하여 해당 플랫폼에서 상태 변화나 알림을 반영될 수 있도록 한다. 이벤트 파이프라인은 기기의 연동 정보를 확인하여 이벤트를 전달하거나, 필터링하는 역할을 한다. 만약 이벤트에 지연이 생기거나 유실이 발생한다면, 단순히 기기의 상태 변화가 앱에 반영되지 않는 것을 넘어, 혼자 있는 집에서의 도어락 강제 문 열림 감지, 영업을 종료한 가게에서 발생한 동작 감지, 아기 방에서의 비정상 온도 경보 등, 사용자의 안전과 직결된 문제로 이어질 수 있다. 그래서 기기 이벤트 지연과 유실은 팀에서 가장 유심하..