LabHub
배우기 러닝패스 코스

요청 하나가 아니라 전부가 느려졌다 · 무엇이 막고 무엇이 안 막는가 · 실습

스레드 풀의 칸을 세어 본다

LabHub 에서 이어서 보기

목표

같은 계산이 어디서 도는가 에 따라 루프를 막기도 하고 안 막기도 한다는 것을
직접 재서 확인하고, libuv 스레드 풀의 칸이 몇 개인지를 숫자로 세어 봅니다.

왜 중요한가

crypto.pbkdf2crypto.pbkdf2Sync 는 같은 계산을 합니다. 그런데 하나는
스레드 풀로 가고 하나는 이벤트 루프 위에서 돕니다. 이름 끝의 Sync 네 글자가
"이 요청만 느리다" 와 "전부 느리다" 를 가릅니다.

그리고 스레드 풀은 무한하지 않습니다. 기본이 네 칸이라, 무거운 비동기 작업을
다섯 개 보내면 다섯 번째는 앞의 하나가 끝날 때까지 시작조차 하지 못합니다.
파일 읽기와 DNS 조회와 압축이 같은 네 칸을 나눠 쓰기 때문에, 압축 작업이
파일 읽기를 늦추는 일이 실제로 일어납니다. 반대로 소켓 읽기와 dns.resolve
그 칸을 쓰지 않아서 아무 영향을 받지 않습니다. 이 지도를 외우는 것이 아니라
재서 확인하는 법을 익히는 것이 이 실습입니다.

단계

1. /root/work/blocking/probe.mjsclassify(name) 로 API 의 자리를 적습니다.
2. 같은 파일에 pct(samples, p)withLag(fn, options) 를 만듭니다.
3. crypto.pbkdf2Synccrypto.pbkdf2 를 재어
/root/work/blocking/report.jsonruns.pbkdf2Sync·runs.pbkdf2Async 에 적습니다.
4. 큰 JSON 문자열을 파싱하며 재어 runs.jsonParse 에 적습니다.
5. /root/work/blocking/wave.mjs 를 만들어 같은 일감 여러 개를 한꺼번에 보내고,
runs.pool4runs.pool8 에 적습니다.
6. UV_THREADPOOL_SIZE=8 로 같은 프로그램을 돌려 runs.pool8big 에 적습니다.
7. zlib.gzipSynczlib.gzip 으로 같은 방법을 한 번 더 적용합니다.

참고

단계 7개

  1. 먼저 지도를 그린다
  2. 일을 시키면서 재는 자
  3. 같은 계산, 다른 자리
  4. 옮길 곳이 없는 일
  5. 칸이 몇 개인지 세어 본다
  6. 칸을 늘리면 해결되는가
  7. 새 API 에 같은 방법을 적용한다