티스토리 뷰

Node.js

Node.js 스트림(stream)

jonyo 2021. 7. 15. 17:09

stream이란?

stream은 여러가지 종류가 있다.

file로 부터 읽어오는 스트림일 수 있고, 네트워크로부터 읽어오는 스트림일 수 있다.

소스로부터 핸들러에게 데이터를 여러 chunks로 나누어 보낸다.

stream은 스트림 가능한 소스로부터 데이터를 작은 청크로 쪼개 처리할 수 있게한다.

큰 데이터를 처리하거나, 비동기적으로만 얻을 수 있는 데이터를 처리할 때 유용하다.

예를들어 5GB파일의 데이터를 처리할 때 한번에 데이터를 올려 처리하려고 한다면 메모리의 5GB공간을 사용해야 할 것이다.

그러나 스트림을 사용하면 이 데이터를 잘개 쪼개어 사용할 수 있다.

stream의 종류

  • Readable

스트림으로부터 읽을 수 있다.

  1. fs.createReadStream
  2. process.stdin
  3. 서버 입장의 HTTP 요청
  4. 클라이언트 입장의 HTTP 응답

등이 있다.

  • Writeable

스트림에 출력할 수 있다.

  1. fs.createWriteStream
  2. process.stdout
  3. 클라이언트 입장의 HTTP 요청
  4. 서버 입장의 HTTP 응답
  • Duplex

이 스트림에 입력을 받을 수도 있고, 출력을 보낼 수도 있다.

  1. TCP sockets
  2. zlib streams
  3. crypto streams

등이 있다.

  • Transform

입력받은 스트림을 변환해 새로운 스트림으로 만든다.

  1. zlib streams
  2. crypto streams

stream을 사용한 큰 데이터의 처리

우선은 큰 데이터를 한번 만들어 보자.

const fs = require('fs')

const ws = fs.createWriteStream('big-file')

for (let i = 0; i < 500; i += 1) {
  ws.write('a'.repeat(1024 * 1024))
}

1byte를 1024 * 1024 하면 1MB가 된다.

반복문을 500번 돌았으니 이 프로그램이 실행 된 후에 500MB크기의 파일이 만들어진다.

이번엔 이 파일을 읽어보자.

const fs = require('fs')

const rs = fs.createReadStream('big-file', {
  encoding: 'utf-8',
})

let chunkCount = 0

rs.on('data', () => {
  chunkCount += 1
})

rs.on('end', () => {
  console.log('end')
  console.log(chunkCount)
})

이 코드를 통해 아까 만들었던 파일을 스트림을 통해 읽어 보았다.

결과를 확인해보면 총 8000번의 chunk를 통해 파일을 읽었음을 확인할 수 있다.

그렇다면 스트림을 사용했을 때와 버퍼를 사용했을 때의 성능차이는 어떨까?

데이터를 읽는 속도는 버퍼를 통해 읽는것 보다 느릴 수 있다.

그러나 만약 큰 데이터를 버퍼를 통해 읽어 사용한다면, 그 데이터의 처리가 끝날 때까지 그 크기만큼의 메모리가 계속 사용되어야 할 것이다. 그러나 스트림을 사용한다면 chunk단위로 데이터를 읽어오기에 큰 공간의 메모리가 필요하지 않다.

따라서 버퍼를 통한 read와 스트림을 통한 read를 상황에 맞게 잘 사용해야한다

stream 사용시 주의해야 할 점

chunk를 사용하여 데이터를 처리할 때 우리가 처리하고자 하는 데이터가 끊겨서 오는 경우가 존재할 수 있다. 이 때는 어떻게 처리해야 할까?

아래와 같은 방법으로 해결할 수 있을 것이다.

  1. 우리가 처리할 수 있는 데이터의 크기만큼 들어올 때까지 chunk를 계속 더해준다.
  2. 원하는 크기만큼 데이터가 들어왔으면 해당 데이터를 특정한 기준으로 나누어 주고, 처리할 수 있는 데이터에 대해 처리한다.

이 작업은 string의 여러 함수들을 이용해 처리할 수 있다.

이처럼 stream을 사용할 때는 chunk의 크기에 따라 데이터가 잘려서 올 수 있다는 점을 생각하여 예외를 처리해주는 로직을 따로 구현하여 처리해야 한다.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함