해당 강연을 보고 정리한 글입니다.
CPU intensive 한 코드란?
학습 페이지
www.inflearn.com
잘 알고 있다 시피, node.js는 이벤트 루프를 사용하고 싱글 스레드지만, 만약 블로킹 IO 나 커널 블로킹이 필요하다면, libuv 엔진의 스레드 풀을 사용하여 처리하게 된다
결국 강연자가 생각했을 땐, 전체 Node.js 의 요청들은 worker pool과 event pool로 나누어질 것이고
worker pool : libuv엔진이 처리하는 것들
event pool : 그외의 것들이다
강연자는 event pool이 cpu를 오래 점유하고 있는 상황에 대해서 지적하고 이를 찾아내는 법에 대해 공유하였다.
예를 들어, 20초 대기하는 코드가 있으면 이는 event pool이고 이후에 요청하는 API 들에 레이턴시가 생길 것이다.
function get((req,res) => {
let count = 0
// 20초 대기
const endTime = Date.now() + 20000;
while(Date.now() < endTime){
count++;
}
}
즉 싱글 스레드 이기 때문이다.
이벤트 루프를 특정 코드가 오래 점유되고 있는 상황에서는 request 처리가 전부 멈춘다.
- Node.js 서버의 request처리량 감소
- 레이턴시 증가
- 스케일 아웃을 시켜도 퍼포먼스가 비례하게 증가하지 않음.
결국 우린 이 부분을 찾아서 해결해야 한다.
어떻게 찾느냐?
이벤트 루프가 blocking이 된다면 어떤 함수에서 왜 해당 현상이 일어나는지 확인한다.
- datadog의 분산 트레이싱을 확인
- Clinic.js를 사용한다. 성능 문제를 진단하고 찾아내는데 도움을 주는 도구
- Doctor
- event loop가 딜레이 되는 시간을 측정하는 도구
- cpu 사용량, 메모리 사용량, 소켓수를 알 수 있는 도구
- flame
- 어떤 함수가 가장 오랫동안 cpu를 점유하는지
- clinic flame에서 확인할 수 있다
- Doctor
- Grafana labs의 k6
- 부하 테스트 툴을 사용해서 검사한다.
강연자의 intensive 한 코드 사례
- json desearlizing : 큰 파일을 json 오브젝트로 바꾸면 정말 오래 걸림. 대부분의 사람들은 이를 모르고 Object.assign()을 남용함
- TypeORM에서 응답 값을 Object.assign()으로 변경했다가 CPU 점유가 오래 걸렸음
- 따라서, raw 한 방안으로 사용.
결론
어떤 API의 코드가 느려지고, 서버가 느려지는 원인 중에, cpu intensive한 코드가 있었는지 확인해 보자.
나의 생각
강연을 통해 NodeJS 자체에서 서버 레이턴시가 증가되는 원인이 있음을 생각해 볼 수 있었다.
만약에 cpu intensive 한 코드를 찾아내도, 해결 방안이 어떤 게 있을까 싶다.
강연자가 Object가 아닌 raw 한 쿼리로 응답해서 해결했다고 했는데, 큰 파일 json은 결국 데이터가 많을 것이고 보통 object에 필드가 정의되어 있어서 필드로 다른 개발자에게 유지 보수에 필요한 정보를 주는데 이를 객체로서 명시하는 것을 저버리고 파일 자체를 가져다 쓴 거니깐.. 타입스크립트를 썼다고 가정하면 사실 타입스크립트의 가장 큰 장점을 못쓰는 거나 마찬가지이기 때문이다 물론 자세하게 어떻게 했다를 말씀 안 하셨으니, 어떻게 했는진 모르지만 그냥 그런 생각이 들었다.
또 드는 생각은 정말 intensive 한 코드가 자주 호출 된다면 사실 auto-scaling으로 스케일 업하면 싱글 스레드가 N 개 생기니깐 이것도 해결책 아닌가 싶기도 하다. 물론 코드 단에서 수정하면 베스트이고..
nodejs 가 싱글 스레드라서 생기는 고려점이 참 많은 것 같다. cluseter나 worker도 정리해 봐야겠다.
'개발 아카이브' 카테고리의 다른 글
Grafana LGTM 톺아보기 (1) - Loki 란? (5) | 2025.01.19 |
---|---|
당근 채팅 시스템은 어떻게 만들까? (5) | 2024.12.08 |
slack 파일 업로드, completeUploadExternal(),getUploadURLExternal() 사용법 (3) | 2024.11.19 |
쿠버네티스란? feat. 데이터 처리도 이제는 컨테이너로, 우아한형제들의 데이터플랫폼 혁신 (5) | 2024.10.13 |
[Deview] - 일본에서도 VOD 를 빠르게 업로드하고 재생할 순 없을까 정리 및 후기 (7) | 2024.09.29 |