s5cmd 사용 가이드 (s3 cp, s3 sync)

업데이트:

s5cmd 설치방법과 사용방법

S5cmd을 사용하면 aws sdk를 사용하여 s3 작업을 할때보다 대략 10배이상 빠른 성능을 보인다.

설치방법

mac 에서 s5cmd 설치를 위해 공식문서에 나온대로 brew로도 열심히 시도해보았지만 실패하였다. brew install peak/tap/s5cmd 이걸로 설치가 되면 다행이지만 안되는 사람들을 위해서 우회방법을 설명한다.

s5cmd의 github 에 들어가서 git clone을 해서 실행시키는 단순한 방법이다. s5cmd는 go 언어로 되어있어서 go언어 설치가 필요하다. 최근버전이면 상관없겠지만 여기에서 go 1.17 라고 나와있기에 맞춰주면된다.

  1. go 설치
  2. git clone https://github.com/peak/s5cmd.git
  3. main.go 가 있는 위치로 이동
  4. go run main.go ls s3://your-files 를 입력하면 실행된다.
    1. brew로 s5cmd를 깔았다면 go run main.go 대신에 s5cmd를 입력하면 된다.

사전조건

s5cmd는 aws sdk 기반이어서 실행환경에서 aws 명령어가 되야한다.

그리고 aws s3 ls 가 되어야한다. 이말은 즉슨 s3를 실행할 권한이 있어야한다는 것이다. ~/.aws/config 또는 ~/.aws/credential 에 프로파일이 필요하다.

여기까지 봤으면 aws s3 sdk가 너무 느려서 다른 방법을 찾아온 사람들일 것 같다. s5cmd를 약간 설명하자면 s3cmd, s4cmd가 진화하여 s5cmd가 된것이다. s4cmd는 python으로 개발했고 s5cmd 는 고언어이다. 고루틴을 사용해 무지막지하게 빠르게 작동된다. aws sdk보다 12배정도 빠르다고하는데 작은 파일을 복사하는 경우 20배 이상 빨랐다.

S5CMD 사용방법

s5cmd 명령어로 ls, cp, rm, mv, sync 등 여러 명령어들이 있다. 대량의 파일들을 처리하기 위한 cp, sync 에서 특히 빛을 발할 것 이다.

ls 명령어

  • s5cmd ls : 내 버킷리스트 보여주기
  • s5cmd ls s3://my-bucket-name , s5cmd ls s3://my-bucket-name/somedir : 내 특정버킷, 특정 위치에 파일 리스트 보여주기 aa

cp 명령어

  • s5cmd cp s3://bucket/prefix/object.gz . : s3에서 로컬로 다운로드
  • s5cmd cp s3://bucket/* target-directory/ : s3 특정위치 파일 모두 다운로드
  • s5cmd cp --exclude "*.txt" --exclude "*.gz" s3://bucket ./ : 파일 이름 기준으로 exclude 하여 모두 다운로드
    • include 옵션은 따로 없다..
  • s5cmd cp s3://bucket/object s3://target-bucket/prefix/object : s3버킷 -> s3버킷 복사
  • s5cmd cp dir/ s3://bucket/ 로컬 -> s3 로 파일 업로드
  • s5cmd cp --exclude "*.txt" --exclude "*.png" --exclude "*.mp4" --content-type "image/jpeg" 's3://bucket/*' s3://bucket/
    • s3 동일 버킷내에서 특정 확장자의 content type 변경하기 단,소스코드의 변경이 있어야함. 현재 s5cmd에서는 지원하고있지 않은 기능임.
    • 동일한 파일의 메타데이터를 변경하기 위해서는 MetadataDirective 의 replace옵션을 추가하고 contentType을 지정해줘야하는데 지금은 지원하지 않고있어서 소스코드상에서 약간의 추가를 해주면 가능하다.
    • s5cmd/storage/s3.go 파일에서
func (s *S3) Copy(ctx context.Context, from, to *url.URL, metadata Metadata) error { 
    ~~~ 제일 하단 부분에

    input.MetadataDirective = aws.String("REPLACE") // 추가
	input.ContentType = aws.String(metadata.ContentType()) // 추가

	_, err := s.api.CopyObject(input)
	return err
}

sync 명령어

  • s5cmd --dry-run sync ~/s3files s3://mybucket/ : 로컬파일 기준 s3 버킷 데이터 확인
  • s5cmd --dry-run sync s3://mybucket/* ~/s3files : s3 기준 로컬 파일 확인

dry-run 사용법

  • s3 sync 명령어와 유사하며 s3버킷과 로컬 위치와의 파일을 동기화 시켜주는 역할이다.
  • 이때 dry-run 옵션을 추가하면 실제 cp와 같은 복제 행동은 일어나지 않고 양쪽을 비교하여 어떤 파일이 비었고 추가되어야하는지 목록을 보여준다. cp 실행 전 실행할 cp 명령어를 보여주는 것이다. go run main.go –dry-run sync ~/s3files ‘s3://my-files/’ go run main.go –dry-run sync ‘s3://ssh-dump-files/*’ ~/s3files

s5cmd 튜닝하기

cp 작업을 할 경우에 바꿀만한 옵션들을 찾아봤다.

  1. defaultCopyConcurrency 바꾸기
// S5CMD/command/cp.go 파일 일부

const (
	defaultCopyConcurrency = 40 // 변경
	defaultPartSize        = 50 // MiB
	megabytes              = 1024 * 1024
)

  1. 실행 시 numworkers 수정
    • 디폴트 numworkers 값은 256으로 이보다 더 증가시킬때는 실행환경에 따라 ulimit의 값을 확인하여 최대 스펙으로 실행할 수 있도록 값을 조절해야한다.
    • s5cmd --numworkers 512 cp '/Users/foo/bar/*' s3://mybucket/foo/bar/ 파일 용량은 작은데 갯수가 엄청 많은 경우
    • s5cmd --numworkers 10 cp '/Users/foo/bar/*' s3://mybucket/foo/bar/ 이렇게 줄이는 경우도 있다. 파일 갯수는 적지만 용량이 큰 경우

s5cmd 사용안하고 네이티브 AWS s3 sdk 로만 작업해보기

AWS S3 sdk 네이티브를 사용할때 아래와같은 옵션으로 약간의 성능을 개선할 수 있다.

AWS 프로파일 정보가 담긴곳에서 S3 옵션을 추가하면 된다. 일반적으로 ~/.aws/config 위치에 configure 파일이 존재한다.

성능 개선을 위해 아래와 같은 옵션을 바꾸면 된다.

  • max_concurrent_requests - The maximum number of concurrent requests.
    • 동시 요청량을 증가시키는 것인데 기본값은 10으로 실행시키는 서버환경에 따라 적절하게 증가시키면 된다. 20~50정도
  • max_queue_size - The maximum number of tasks in the task queue.

작업 : vi ~/.aws/config

[profile development]
aws_access_key_id=AKIAaaaaaaaab
aws_secret_access_key=somesecrectkey
s3 =
  max_concurrent_requests = 20
  max_queue_size = 20000

s3 config 참고자료 - https://docs.aws.amazon.com/cli/latest/topic/s3-config.html

s5cmd 나 S3 에서 다량의 파일 작업을 하다보면 linux의 시스템 한계를 만나게 될 것이다. cpu, ram 리밋 혹은 disk io 등등 여러가지가 있겠지만 위와같은 작업에서는 프로세스 제한이 걸리게 될 가능성이 높다.

s5cmd에서 numworker 를 너무 높이게 되면 Too many open files 와 같은 에러를 만나게 될 것이다. ulimit -a 로 file limit을 확인해보고 현재 값보다 높게 설정해 처리량을 높여보자.

태그: , ,

카테고리:

업데이트:

댓글남기기