본문 바로가기

분류 전체보기

(319)
내가 아는 Node.js -4 스레드 풀(Thread Pool)과 워커 스레드(Worker Thread)Node.js는 본질적으로 싱글 스레드 기반의 이벤트 루프 모델을 채택하고 있지만, 내부적으로 멀티 스레드를 활용하여 비동기 I/O와 CPU 집약적인 작업을 효율적으로 처리할 수 있도록 설계되어 있습니다. Node.js에서 멀티 스레드를 사용하는 방식은 크게 두 가지로 나뉩니다: 스레드 풀 (Thread Pool) 과 워커 스레드 (Worker Threads)입니다.스레드 풀 (Thread Pool)Node.js가 특정 작업을 수행할 때 자동으로 멀티 스레드를 사용하는 대표적인 메커니즘이 바로 스레드 풀입니다. 이는 Node.js 내부에서 사용하는 libuv 라이브러리를 통해 구현되어 있으며, 비동기 I/O 작업이나 일부 CPU 연..
내가 아는 Node.js -3 Node에서 실행되는 방식Node.js의 비동기 처리 흐름을 정확하게 이해하려면, Microtask와 Macrotask의 차이를 명확히 아는 것이 중요합니다. 특히 비동기 코드의 실행 순서를 예측하고 디버깅하거나, 성능을 최적화하고 싶다면 이 두 개념을 필수적으로 이해해야합니다.Macrotask는 Event Loop의 각 Phase에서 실행되는 작업을 의미합니다. 예를 들어, setTimeout, setInterval, setImmediate, I/O 콜백, close 콜백 등은 모두 각각의 Phase에 배정되어 순차적으로 실행됩니다. -2 에서 조금은 자세히 설명되어 있습니다.가장 흔히 언급되는 예는 setTimeout(() => {}, 0)인데, 이 코드는 Timer Phase에서 실행되는 대표적인 ..
내가 아는 Node.js -2 Event LoopNode.js는 싱글 스레드 기반의 JavaScript 런타임입니다. 그러나 단일 스레드라는 제약에도 불구하고, 수천 개의 네트워크 요청이나 파일 I/O 작업을 동시에 처리할 수 있는 고성능 서버 애플리케이션을 개발할 수 있습니다. 그 중심에는 바로 Event Loop라는 메커니즘이 존재합니다. Node.js에서 Event Loop는 libuv 라는 C 기반 라이브러리를 통해 구현되며, 이는 이벤트 기반 비동기 I/O를 가능하게 해줍니다.이벤트 루프는 자바스크립트가 단일 스레드에서 동작하는 언어임에도 높은 동시성을 제공할 수 있도록 설계된 핵심 구조입니다. I/O 작업, 타이머, 네트워크 요청, 파일 시스템 접근과 같은 작업이 비동기로 이루어질 수 있도록 지원하며, 작업 완료 후 등록된..
내가 아는 Node.js -1 Node.js는 Chrome V8 자바스크립트 엔진 위에 구축된 자바스크립트 런타임(JavaScript Runtime) 입니다. 흔히 런타임이란 특정 언어로 작성된 코드를 실행할 수 있는 환경을 의미하며, Node.js는 자바스크립트로 작성된 애플리케이션을 웹 브라우저 외부, 즉 서버 환경에서 실행할 수 있게 해주는 플랫폼입니다.원래 자바스크립트는 웹 브라우저 내에서만 동작하는 스크립트 언어였습니다. 이는 브라우저가 자바스크립트 런타임(예: V8, SpiderMonkey 등)을 내장하고 있었기 때문입니다. 하지만 2009년, 라이언 달(Ryan Dahl)이 V8 엔진과 libuv라는 라이브러리를 조합하여 Node.js를 만들어냄으로써, 자바스크립트를 브라우저 밖으로 끄집어낼 수 있게 되었고, 오늘날에는 ..
비동기 아키텍처 전환 700 RPS 환경에서 응답 시간 96% 개선 및 MySQL 부하 해소서비스 초기에 트래픽이 적을 땐 동기 처리 기반의 단순한 구조만으로도 충분히 운영이 가능했습니다. 하지만 서비스가 성장하고, 초당 700건 이상의 요청이 발생하면서 이전 구조에서는 한계를 드러내기 시작했습니다. 특히 Like 이벤트 처리 시 두 가지 주요 문제가 발생했습니다: MySQL Connection 고갈과 Row-Level Lock 경합입니다.문제가 발생한 시점의 성능 지표는 다음과 같았습니다.평균 응답 시간이 580ms, 95퍼센타일 기준으로는 무려 988ms까지 치솟았습니다. 트래픽은 순간적으로 몰리는 burst 환경에서 더 극단적인 지연을 야기했으며, 이는 사용자 경험에 직접적인 악영향을 주었습니다.단순한 max_conne..
내 API는 실패할 수 있다 개발을 하다보면 내 API는 반드시 성공할 것이라고 믿는다. 실제로 처음 서비스를 개발할 때는 단순한 기능 테스트만으로 만족하며, 클라이언트와의 통신에서 200 OK 응답만 오면 모든것이 잘 작동한다고 생각하게 된다.하지만 서비스가 운영 환경에 배포되고, 실제 유저들이 몰리기 시작하면서 API는 다양한 방식으로 실패할 수 있다는 사실을 알게된다. 특히 대용량 트래픽이 집중되는 순간, 서버는 실패를 예외가 아닌 일상처럼 겪게된다.예상치 못한 실패 중 하나는 과도한 요청 처리로 인해 서버의 스레드가 고갈되는 경우이다.예를 들어, A 서비스가 200개의 스레드를 가진 상태에서, 외부의 B 서비스와 연동된 API를 호출하는 상황을 가정해보려고한다. B 서비스는 최대 100개의 요청을 동시에 처리하지만, 특정 시..
DB Server의 CPU 사용률이 높은 상황 - 4 MySQL에서 COUNT(*), GROUP BY, JOIN과 같은 연산은 단순해 보이지만, 실제로는 매우 많은 시스템 자원을 사용하는 작업입니다. 특히, 적절한 인덱스가 없거나 그룹 수가 많을 경우, 성능에 치명적인 영향을 줄 수 있습니다.우선 COUNT(*)는 특정 조건을 만족하는 전체 행의 수를 세는 작업입니다. 조건이 없는 경우, 또는 조건이 있어도 인덱스를 타지 못하는 경우, MySQL은 테이블 전체를 스캔하여 결과를 계산하게 됩니다. 특히 InnoDB 스토리지 엔진은 MyISAM과 달리 테이블의 전체 행 수를 메타데이터로 관리하지 않기 때문에, 항상 실시간으로 계산을 수행해야 하고, 이 과정에서 디스크 I/O와 CPU 사용량이 급증하게 됩니다.이와 함께 SUM이나 AVG와 같은 집계 함수 역시 ..
DB Server의 CPU 사용률이 높은 상황 - 3 커넥션 수의 과다로 인한 성능 저하와 그 원인MySQL은 기본적으로 Thread per Connection 모델을 사용합니다. 이 말은 하나의 커넥션이 생성될 때마다 별도의 스레드가 생성된다는 뜻입니다.실제 요청을 처리하는 스레드는 별도의 Thread Pool이 아니라, 커넥션마다 1:1로 매핑된 독립 스레드를 의미합니다. 따라서 애플리케이션이나 사용자로부터 동시에 많은 커넥션이 유입된다면, 그 수만큼 스레드가 생성되며 시스템 리소스 소모가 눈에 띄게 증가하게 됩니다.커넥션 수가 과도해진다면?가장 먼저 발생하는 문제는 스레드 생성 및 관리 비용입니다. 수백 수천개의 커넥션이 들어오면 동일한 수의 스레드가 생성됩니다. 이는 OS 차원에서 모두 스케줄링 대상입니다. 이로 인해 CPU는 모든 스레드를 조금씩 ..