Problem

Node.js에서 파일 업로드 시 RangeError: Array buffer allocation failed 에러가 발생하는 경우가 있다. 메모리가 작은 장비에서 큰 용량의 파일을 다룰 때 주로 발생한다. 주로 fs.readFile을 사용할 때 발생했었다. 네트워크 처리는 다소 많지만 CPU나 메모리 사용률은 낮은 서비스에서 사양이 낮은 장비를 이용하는 경우 신경쓰지 못한다면 문제가 생길때까지 확인하지 못할 수도 있다.

RangeError: Array buffer allocation failed
        at new ArrayBuffer (<anonymous>)
        at new Uint8Array (<anonymous>)
        at new FastBuffer (buffer.js:79:1)
        at Function.alloc (buffer.js:283:10)
        at new Buffer (buffer.js:180:19)
        at module.exports.Reader.addChunk (/home/node/app/node_modules/packet-reader/index.js:35:21)
        at Socket.<anonymous> (/home/node/app/node_modules/pg/lib/connection.js:117:18)
        at Socket.emit (events.js:182:13)
        at addChunk (_stream_readable.js:283:12)
        at readableAddChunk (_stream_readable.js:264:11)
        at Socket.Readable.push (_stream_readable.js:219:10)
        at Pipe.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)

Solution

파일의 모든 내용을 메모리에 로드할 수 없는 상황도 있기에 나의 해결방법은 fs.readFile대신 fs.createReadStream를 이용하여 스트림으로 전송하여 해겼했다. 아래는 파일을 stream으로 열어서 AWS SDK를 이용해 S3에 전송하는 예제의 일부이다.

const params = {
    Bucket: BUCKET,
    Key: id,
    Body: fs.createReadStream(path),
    ContentType: contentType,
};

client.upload(params, function(err, data) {
    callback(err, data);
});