티스토리 뷰

Can I do work while waiting?

Synchronous I/O

  1. 요청자가 요청을 보내면 프로세스가 중단된다.
  2. 요청자는 코드를 더 실행할 수 없다.
  3. 수신자가 응답을 주면, 요청자 중단이 해제된다.

OS의 동기 I/O 예시

  • 프로그램이 디스크로부터 읽을 것을 요청한다.
  • 프로그램의 메인 스레드가 CPU에서 쫓겨난다. (I/O 하는동안 원래 요청보낸 스레드를 쫓아내서 CPU에서 컨텍스트 스위칭이 일어난다.)
// Program starts
// Program uses CPU to execute stuff
doWork();
// Program reads from disk
// Program can't do anything until file loads
// 요청이 커널 -> 드라이브 -> 디스크 컨트롤러로 도달
readFile("largefile.dat");
// Program resumes
doWork2();

Asynchronous I/O

  1. 요청자가 요청을 보내고, 응답을 받을 때까지 다른 작업을 할 수 있다.
  2. 요청자의 선택
    1. 응답이 준비되었는지 체크? Are you ready? Tell me when it's ready (epoll)
    2. 수신자가 작업을 완료하면 호출자에게 콜백한다. Completion Queue (CQ). (Windows IOCP)
    3. 메인 스레드가 보조 스레드를 생성해서, 걔한테 작업을 맡김. 메인 스레드는 다른 일을 할 수 있음. (like tricks)

OS의 비동기 I/O 예시 (Node.js)

  1. 프로그램이 보조 스레드를 시작한다. spins up a secondary thread
  2. 보조스레드는 디스크에서 읽고(CPU에서 제외된다), 메인 스레드는 유지되고, 다른 코드를 실행한다.
  3. 보조 스레드가 읽기를 끝내고 메인 스레드에게 콜백을 호출한다.
// Program starts
// Program uses CPU to execute stuff
doWork();
// Program reads from disk
// Program asks to callback when done
// Program moves on to doWork2
readFile("largefile.dat", onReadFinished(theFile);
// file is probably not read yet
// Program happy doing stuff
doWork2();
// someone just called onReadFinished
// processing it.
----> onReadFinished(theFile);

동기 vs 비동기 in Request Response

동기성은 항상 클라이언트의 속성?

더 이상 동기적인 클라이언트 라이브러리가 없다.

클라이언트가 HTTP 요청을 보내고 작업을 계속한다.

동기 vs 비동기 in real life

  • 동기 : 회의 중에 누군가에게 질문을 하는 것
  • 비동기 : 이메일 보내기 (앉아서 답변을 기다리지 않죠)

비동기 워크로드

  • 비동기 프로그래밍 (Promises/Future)
  • 비동기 백엔드 프로세싱
    • 클라이언트는 비동기적이지만, 전체 시스템은 동기적이다. 기술적으로 백엔드 입장에서는 "누군가 날 기다리고 있어"
    • Queue!! 요청을 큐에 넣는다. 백엔드가 지금 프로미스를 처리할 수 없으니까. 지금 다른 요청을 처리해야돼!!
      • 요청을 보내면 즉시 큐에 들어가고, 작업 ID를 받으면 클라이언트는 연결을 끊고, 작업 ID를 저장해놨다가, "야 백엔드야 너 이거 끝났니?" 할 수 있다는 것
  • Postgres의 비동기 커밋
  • 리죽스의 비동기 I/O (epoll, io_uring)
  • 비동기 복제 (Replication)
  • 비동기 OS fsync (fs cache)
    • 파일을 쓸 때 바로 파일에 저장되지 않고 일단 파일 시스템 캐시에 저장된다.
    • 왜냐면 항상 쓰려고 하면 바이트들에 지웠다 썼다 하면서 하드웨어에 좋지 않음
    • 쓰기 양을 최소화 하기 위해 캐시에 데이터를 일괄 처리한다.