개발자공부일기
버퍼와 스트림 본문
버퍼(Buffer)와 스트림(Stream) in Node.js
Node.js에서 버퍼와 스트림은 파일 처리, 네트워크 통신 등 대규모 데이터 처리를 효율적으로 수행하기 위한 핵심 개념입니다. 유튜브 스트리밍을 예로 들면, 이 두 개념이 어떻게 작동하는지 쉽게 이해할 수 있습니다.
버퍼(Buffer)
버퍼는 고정된 크기의 메모리 공간으로, 바이너리 데이터를 임시로 저장합니다. 주로 파일, 네트워크 프로토콜, 스트리밍 등에서 데이터가 처리되기 전에 저장하는 용도로 사용됩니다.
유튜브 스트리밍에서 버퍼는 동영상 데이터를 재생 전에 임시로 저장하는 역할을 합니다.
주요 특징
- 고정 크기: 생성 시 크기가 결정되며, 이후 변경 불가.
- 바이너리 데이터 처리: 데이터는 이진 형식으로 저장되어 직접 조작이 가능.
- 임시 저장소 역할: 스트리밍 데이터가 네트워크 속도에 영향을 받지 않도록 임시 저장.
주요 메서드
- Buffer.from(data): 데이터를 기반으로 새로운 버퍼 생성.
- buffer.toString([encoding]): 버퍼 데이터를 문자열로 변환.
- Buffer.alloc(size): 지정된 크기의 버퍼를 0으로 초기화하여 생성.
예시
const buffer = Buffer.from('Hello, Node.js');
console.log(buffer); // 출력: <Buffer 48 65 6c 6c 6f 2c 20 4e 6f 64 65 2e 6a 73>
console.log(buffer.toString()); // 출력: 'Hello, Node.js'
유튜브에서 버퍼링(buffering)은 동영상 데이터가 네트워크에서 받아들여지면, 먼저 버퍼에 임시로 저장되는 것을 의미합니다. 이 데이터가 충분히 쌓이면 재생이 시작됩니다. 네트워크가 느릴 경우, 버퍼가 비워질 수 있어 동영상이 멈추고 추가 데이터가 쌓일 때까지 기다리는 현상이 나타납니다.
스트림(Stream)
스트림은 데이터를 조각(chunk) 단위로 처리하는 방법입니다. 유튜브는 동영상을 한 번에 다운로드하지 않고, 조각 단위로 데이터를 전송하여 재생하는 방식으로 작동합니다. 이 스트림 처리 방식 덕분에 대규모 데이터를 실시간으로 처리할 수 있습니다.
스트림의 유형
- Readable Streams: 데이터를 읽기 위한 스트림.
예: fs.createReadStream(), HTTP 요청 객체. - Writable Streams: 데이터를 쓰기 위한 스트림.
예: fs.createWriteStream(), HTTP 응답 객체. - Duplex Streams: 읽기와 쓰기를 동시에 수행.
예: 네트워크 소켓. - Transform Streams: 읽고 쓰는 동안 데이터를 변환.
예: 데이터 압축, 암호화.
스트림의 특징
- 이벤트 기반 처리: data, end, error 등의 이벤트로 데이터 흐름을 제어.
- 효율적 데이터 처리: 데이터 조각 단위로 처리하여 메모리 과부하를 방지.
- 역압 관리: 생산자와 소비자 간 속도 차이를 조율.
예시: 읽기 스트림
const fs = require('fs');
const readableStream = fs.createReadStream('example.txt', { encoding: 'utf8' });
readableStream.on('data', (chunk) => {
console.log('받은 데이터:', chunk);
});
readableStream.on('end', () => {
console.log('데이터가 더 이상 없습니다.');
});
유튜브의 스트리밍에서 서버는 동영상 데이터를 Readable Stream처럼 조각 단위로 클라이언트에 전송합니다. 클라이언트는 데이터를 받아 Writable Stream처럼 화면에 출력하거나 버퍼에 저장하여 재생합니다.
버퍼와 스트림의 관계
버퍼와 스트림은 밀접한 관계를 가지고 있습니다.
- 스트림의 버퍼링: 스트림은 데이터를 처리하기 전에 내부적으로 버퍼를 사용해 데이터를 임시 저장합니다.
- 역압(Backpressure): 데이터 생산 속도와 소비 속도 간 불균형을 조정합니다. 예를 들어, 네트워크 속도가 느려 스트림 소비가 지연되면 서버는 데이터 전송을 일시 중지하고 클라이언트가 준비되면 다시 시작합니다.
역압 처리 예시
const fs = require('fs');
const readableStream = fs.createReadStream('largeFile.txt');
const writableStream = fs.createWriteStream('output.txt');
readableStream.on('data', (chunk) => {
if (!writableStream.write(chunk)) {
readableStream.pause();
}
});
writableStream.on('drain', () => {
readableStream.resume();
});
readableStream.on('end', () => {
writableStream.end();
});
이처럼 스트림은 내부 버퍼를 사용하여 데이터 흐름을 제어하고 효율적인 처리를 보장합니다.
요약
Node.js에서:
- 버퍼는 데이터를 임시로 저장하고 조작하기 위한 공간입니다.
- 스트림은 데이터를 조각 단위로 처리하여 효율성을 극대화합니다.
- 두 개념의 조합은 대규모 데이터 처리(예: 유튜브 스트리밍)에서 핵심적인 역할을 합니다.
'TIL(Today I Learned)' 카테고리의 다른 글
Promise와 forEach의 동작 차이 (0) | 2024.12.31 |
---|---|
I/O(Input/Output) 최적화 (0) | 2024.12.30 |
OSI 응용 계층 (0) | 2024.12.26 |
운영체제 (Operating System)란? (0) | 2024.12.24 |
인덱스 (0) | 2024.12.20 |