S3 버킷에서 gzip 파일을 가공하여 다시 gzip으로 내보내기

별일 아닌 것 같지만 조금 막혀서 남아있을 거예요.
하고 싶은 일
어떤 S3통에 있는 gzip 파일(안은 json)은 매번 성도에서 일부분을 가공하고 다른 통에 압축해서 출력해야 한다.
그림을 그릴 정도는 아니지만 그런 구성이다.

어떻게
Source Bucket에서 SQS에 람보를 호출하는 곳을 알리는 것은 일반적인 설정이기 때문에 생략합니다.
gzip을 처리할 수 있는 npm포장은 유명node-zip이지만 zlib만 할 수 있기 때문에 이번처럼 간단한 포장은 외부포장이 필요 없습니다.
해동, 가공, 재압축을 하는 람다는 다음과 같다.(nodejs14.x)
const AWS = require('aws-sdk')
const s3 = new AWS.S3()
const zlib = require('zlib');

exports.handler = async (event) => {
  try{
    for (const record of event.Records) {
      for (const recordBody of JSON.parse(record.body)) {
        const key = recordBody.s3.object.key
        if (/\.gz$/.test(key)){
          // Source Bucketからgzipオブジェクトを取得
          const getParams = {
            Bucket: 'SOURCE_BUCKET_NAME',
            Key: key
          }
          const source = await s3.getObject(getParams).promise()

          // 1. 解凍
          const sourceData = JSON.parse(zlib.gunzipSync(source.Body))

          // 2.加工
          // ...

          // 3. 再圧縮
          const destData = zlib.gzipSync(JSON.stringify(sourceData))

          // 4. 保存
          const putParams = {
            Bucket: 'DESTINATION_BUCKET_NAME',
            Key: key,
            Body: destData,
            ContentType: 'application/json',
            ContentEncoding: 'gzip'
          }
          await s3.putObject(putParams).promise()
        }
      }
    }
    // done
    return true
  }catch(err){
    throw new Error("Exception error")
  }
}

1. 해동
zlib.gunzipSync(data)
데이터는 다음과 같은 형식의 하나다.이번에는 통에서 얻은 버퍼 값을 직접 넣었다.<Buffer> | <TypedArray> | <DataView> | <ArrayBuffer> | <string>두 번째 파라미터로 전달할 수도 있다옵션.
zlib.gunzip이라는 방법도 있지만, 다른 라인의 호출 형식으로 변한다.
zlib.gunzipSync가 같은 라인에서 실행되기 때문에 호출 형식이 되지 않습니다.
2. 가공
해동된 데이터 (이번에는 json 형식) 를 여기서 가공합니다.
3. 재압축
zlib.gzipSync(data)
데이터는 다음과 같은 형식의 하나다.이번에는 직접 가공된string을 넣었어요.<Buffer> | <TypedArray> | <DataView> | <ArrayBuffer> | <string>두 번째 파라미터로 전달할 수도 있다옵션.
여기도 마찬가지로 zilib입니다.gzip이라는 방법도 있어 다른 라인에서 호출하는 형식이 된다.
zlib.같은 스레드에서 gzipSync가 실행되기 때문에 콜백이 되지 않습니다.
4. 저장
그러나 이번에 저장된 것은 json을 gzip으로 압축한 것이기 때문에 다음과 같은 메타데이터를 추가했습니다.
ContentType: 'application/json'
ContentEncoding: 'gzip'
이 메타데이터를 추가하면 S3의 객체 처리가 변경되고 콘솔에서 다운로드할 때 자동으로 동결해제됩니다.
참고로 메타데이터를 추가하지 않고 저장한 경우ContentTypeapplication/octet-stream.
나는 이 일대가 후속 처리에 따라 적당한 값을 더하는 것이 가장 좋다고 생각한다.
기타
오류 처리는 DLQ의 재처리 및 후속 처리에도 영향을 미치므로 적절한 조정이 필요합니다.
이번에는 재처리에 대해 그렇게 엄격하게 생각할 필요가 없어 간단한 기재를 썼다.
참고 자료
https://nodejs.org/api/zlib.html
https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/UsingMetadata.html

좋은 웹페이지 즐겨찾기