Node.js 스트림은 데이터 처리를 위한 강력한 기능입니다. 이전 포스팅에서는 스트림 개요, 스트림 API, 스트림 사용 예시 등에 대해 알아보았습니다. 이번 포스팅에서는 스트림 변환, 스트림의 한계, 스트림 활용 등에 대해 더 자세히 알아보도록 하겠습니다.
스트림 변환
스트림 변환은 데이터를 변환하여 스트림을 통해 전달하는 것을 의미합니다. 이를 통해 스트림을 통해 데이터를 처리하고 변환하는 것이 가능해집니다. 이를 위해 Node.js에서는 Transform 스트림을 제공합니다.
Transform 스트림은 Readable 스트림과 Writable 스트림 사이에서 동작합니다. Readable 스트림에서 데이터를 읽어 들이고, 그 데이터를 처리한 후 Writable 스트림에 전달합니다. 이를 통해 데이터를 변환하고 다른 스트림으로 전달할 수 있습니다.
아래는 Transform 스트림을 사용하여 데이터를 변환하는 예시입니다.
const { Transform } = require('stream');
// Transform 스트림 생성
const uppercase = new Transform({
transform(chunk, encoding, callback) {
callback(null, chunk.toString().toUpperCase());
}
});
// Readable 스트림 생성
const readStream = fs.createReadStream('input.txt');
// Writable 스트림 생성
const writeStream = fs.createWriteStream('output.txt');
// Readable 스트림과 Transform 스트림을 파이프로 연결
readStream.pipe(uppercase).pipe(writeStream);
위의 예시에서는, Transform 스트림을 사용하여 데이터를 대문자로 변환합니다. Readable 스트림에서 데이터를 읽어 들이고, Transform 스트림에서 데이터를 변환한 후 Writable 스트림으로 전달합니다. 이를 통해 데이터를 효율적으로 처리할 수 있습니다.
스트림의 한계
스트림은 데이터를 처리하는 데 매우 효율적인 방법입니다. 그러나 스트림을 사용할 때는 몇 가지 주의할 점이 있습니다. 예를 들어, 스트림은 언제나 순차적으로 실행되며, 일부 스트림은 동기적으로 동작합니다. 이는 스트림에서 데이터를 처리하는 데 시간이 오래 걸릴 경우 문제가 될 수 있습니다.
또한, 스트림은 한 번에 하나의 데이터 조각만 처리할 수 있습니다. 이는 데이터를 처리할 때 메모리 사용량을 줄이는 데 도움이 되지만, 대용량 데이터를 처리할 때는 속도가 느려질 수 있습니다.
1. 스트림 연결과 오류 처리
스트림을 연결하는 것은 개발자에게 추가적인 책임을 요구합니다. 예를 들어, 스트림의 마지막에서 에러가 발생하는 경우, 그 에러를 처리해주지 않으면 애플리케이션이 중단될 수 있습니다.
또한, 스트림 연결 시 오랜 시간 동안 대기하는 스트림이 있을 경우, 전체 연결이 지연될 수 있습니다. 이 문제는 pipe() 메서드 대신 직접 데이터를 전송하는 방법을 사용하면 완화될 수 있습니다.
2. 스트림과 메모리
스트림은 대량의 데이터를 처리할 때 메모리를 절약할 수 있습니다. 그러나 모든 스트림이 메모리를 아예 사용하지 않는 것은 아닙니다. 스트림은 버퍼링을 사용하며, 이를 통해 일정량의 데이터를 한 번에 처리할 수 있습니다. 따라서 대량의 데이터를 다룰 때 메모리 사용량은 줄어들지만, 메모리 사용량을 완전히 없앨 수는 없습니다.
3. 스트림 종류
스트림은 데이터를 읽기 위해 디스크, 메모리, 네트워크 등 다양한 소스로부터 생성될 수 있습니다. 그러나 각 스트림의 특성에 따라 다른 문제가 발생할 수 있습니다. 예를 들어, 디스크 스트림은 느리고, 네트워크 스트림은 불안정할 수 있습니다.
스트림 활용
1. 파일 압축 및 압축 해제
스트림은 파일 압축 및 압축 해제와 같은 작업에도 사용됩니다. 예를 들어, zlib 라이브러리는 파일의 압축을 처리하는 데 사용됩니다. zlib 모듈은 gzip, deflate 및 raw 압축 형식을 지원하며, zlib.createGzip() 및 zlib.createGunzip() 함수를 사용하여 파일의 압축과 압축 해제를 처리할 수 있습니다.
const fs = require('fs');
const zlib = require('zlib');
const gzip = zlib.createGzip();
const readStream = fs.createReadStream('./largefile.txt');
const writeStream = fs.createWriteStream('./largefile.txt.gz');
readStream.pipe(gzip).pipe(writeStream);
위의 코드는 largefile.txt 파일을 읽어 들여서 gzip 형식으로 압축하고 largefile.txt.gz 파일로 쓰는 예시입니다. 스트림을 이용해 대용량의 파일도 쉽게 압축 및 압축 해제가 가능합니다.
2. 데이터베이스 쿼리 결과 처리
스트림은 대량의 데이터를 처리하는 데 유용한 방법이기 때문에 데이터베이스 쿼리 결과를 처리하는 데도 사용될 수 있습니다. 데이터베이스에서 결과를 가져올 때, 결과가 큰 경우 메모리 사용량이 많아져 문제가 발생할 수 있습니다. 스트림을 사용하면 일부 결과만 가져오고 처리할 수 있으므로 메모리 부족 문제를 해결할 수 있습니다.
const mysql = require('mysql');
const fs = require('fs');
const connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'password',
database: 'my_db'
});
const query = connection.query('SELECT * FROM large_table');
query
.stream()
.pipe(JSONStream.stringify())
.pipe(fs.createWriteStream('./result.json'));
위 코드는 large_table에서 모든 데이터를 가져와 JSON 형식으로 변환하고 result.json 파일로 쓰는 예시입니다. 결과를 처리하는 동안 메모리 사용량이 증가하지 않기 때문에 대용량 데이터베이스 쿼리도 처리할 수 있습니다.
스트림은 파일, 네트워크, 데이터베이스 등 다양한 데이터 소스에서 데이터를 읽고 쓰는 데 사용될 수 있습니다. 또한 스트림은 대용량 데이터를 처리하면서도 메모리 사용량을 최소화할 수 있도록 도와줍니다.
스트림은 읽기, 쓰기 및 변환 세 가지 방법으로 사용할 수 있습니다. 스트림을 사용하면 데이터를 처리하면서도 메모리 사용량을 최소화할 수 있으며, 데이터 처리 과정에서 에러를 처리하고, 코드의 가독성과 유지 보수성을 높일 수 있습니다.
Node.js에서는 fs, http, net과 같은 기본적인 모듈에서 스트림을 지원하며, 다양한 스트림 라이브러리가 존재합니다. 스트림을 사용하면 복잡한 데이터 처리를 쉽게 다룰 수 있으며, 메모리 사용량을 최소화하여 더욱 효율적인 데이터 처리가 가능해집니다.
스트림은 비동기 처리에 유용한 기능 중 하나입니다. 데이터를 처리하면서 데이터를 읽고 쓰기 위한 복잡한 로직을 쉽게 처리할 수 있고, 에러 처리를 쉽게할 수 있습니다. 따라서 스트림은 Node.js 개발자라면 반드시 알아야 하는 기능 중 하나입니다.
스트림을 다루는 방법에 대해서는 이번 글에서 다루었으며, 스트림이 데이터 처리에 있어서 강력한 기능임을 알 수 있습니다. 스트림은 Node.js 개발자가 알아둬야 할 필수적인 개념 중 하나이며, 이를 잘 활용하면 보다 효율적이고 안정적인 코드를 작성할 수 있을 것이라고 생각합니다.
다음글
'Backend > Node.js' 카테고리의 다른 글
[Node.js] Util 모듈의 promisify() 함수 사용법 (0) | 2023.02.21 |
---|---|
[Node.js] RxJS란 (0) | 2023.02.18 |
[Node.js] 스트림이란 (Stream) ① (0) | 2023.02.18 |
[Javascript] 2차원 배열을 1차원 배열로 만들 (0) | 2023.02.08 |
[FP] fp-ts 란 (0) | 2023.02.07 |