AWS S3에서 디렉터리 구조 병합

Streaver's blog에 원래 게시되었습니다.

문제



다른 날에는 AWS S3에서 수백 개의 파일 정도인 작은 파일 트리를 평면화해야 했습니다. 몇 번의 시행착오 끝에 작업을 완료한 매우 간단한 일련의 파이프된 명령으로 끝냈습니다.

문제는 간단했습니다. 우리는 s3:// <your-bucket>/posts/:postId/images/:imageId와 같은 구조에서 s3:// <your-bucket>/posts/images/:imageId와 같은 플랫 디렉토리 구조로 마이그레이션하기를 원했습니다. 그래서 우리는 이미지를 특정 포스트 폴더 아래에 두지 않고 모든 포스트가 공유하는 전역 사물로 가질 수 있기를 원했습니다.

베어 셸과 자격 증명이 포함된 AWS CLI 설정이 필요합니다. 나는 당신이 이미 그 모든 것을 가지고 있다고 가정 할 것입니다.

1단계: 이름 충돌 확인


post1/image1.pngpost2/image1.png 가 있을 수 있으므로 평탄화가 가능한지 확인해야 합니다. 아주 간단합니다. 일부 셸 명령을 함께 사용하면 몇 초 만에 얻을 수 있습니다.

마이그레이션하려는 모든 파일 목록을 가져오는 것으로 시작합니다. 이를 위해 다음을 사용합니다.

$> aws s3 ls <your-bucket> --recursive
2021-06-07 12:24:28     390966 posts/1/images/image1.png
2021-06-08 13:09:16     120346 posts/1/images/image2.png
2021-06-07 12:23:37     144935 posts/2/images/image3.png
2021-06-07 12:23:37     144945 posts/3/images/image3.png
...


타임스탬프, 크기 및 경로가 포함된 목록을 얻습니다.

두 번째 단계는 필요하지 않은 정보를 필터링하는 것입니다.

$> aws s3 ls <your-bucket> --recursive | awk '{print $4}'
posts/1/images/image1.png
posts/1/images/image2.png
posts/2/images/image3.png
posts/3/images/image3.png


이를 위해 우리는 awk 패턴을 스캔 및 감지하고 정보를 매우 빠르게 추출할 수 있는 편리한 셸 명령(실제로는 패턴 지향 스캐닝 및 처리 언어임)을 사용합니다.

디렉토리 구조를 평면화할 것이기 때문에 중복을 확인하려면 파일 이름만 확인해야 하며 전체 경로는 필요하지 않습니다. 이를 달성하기 위한 세 번째 단계는 다음과 같습니다.

$> aws s3 ls <your-bucket> --recursive | awk '{print $4}' | xargs -I {} basename {}
image1.png
image2.png
image3.png
image3.png


여기에서 파이프로 연결하는 각 줄에 대해 명령을 실행할 수 있는 xargs를 사용하고 basename와 결합하여 주어진 경로의 파일 이름을 추출합니다.

마지막 단계는 중복된 파일 이름을 확인하는 것입니다. 이를 위해 중복된 줄을 인쇄하는 uniq -d 를 사용할 수 있습니다. 모두 모아서 실행하면 중복 항목이 있는지 알 수 있습니다.

aws s3 ls <your-bucket> --recursive | awk '{print $4}' | xargs -I {} basename {} | uniq -d
image3.png


우리는 그것을 실행합니다. 그것이 비어 있다면, 우리는 좋고, 병합을 바로 수행할 수 있습니다. 그렇지 않다면 파일을 병합한 후에 어떤 파일도 충돌하지 않도록 파일 이름을 어떻게든 수정해야 합니다. 파일 쓰기/읽기 방법에 따라 이름 변경을 남겨두겠습니다. 네 경우에는 posts/3/images/image3.pngposts/3/images/image4.png 로 이름을 변경했습니다.

2단계: 파일 이동



다음 단계는 파일을 이동하거나 복제하는 것입니다. 다운타임 없는 마이그레이션이 필요한 경우 먼저 복사하고 나중에 삭제할 수 있습니다. 다운타임 없는 마이그레이션이 필요하지 않은 경우 이전 위치에서 새 위치로 파일을 이동할 수 있습니다. 그러면 파일을 찾을 수 없는 짧은 기간이 있습니다.
xargs 명령을 사용하여 보이는 대로 각 파일을 이동합니다.

aws s3 ls <your-bucket> --recursive | awk '{print $4}' | xargs -I {} sh -c 'aws s3 mv s3://<your-bucket>/{} s3://<your-bucket>/posts/images/$(basename {})'


분해하자! 첫 번째 부분은 이전과 동일합니다. 그런 다음 xargs가 비슷하게 시작되지만 명령을 실행하는 대신 서브쉘을 만들고 명령을 전달한 다음 {}를 파일 이름으로 바꿉니다.

실행하고 싶지만 계획대로 진행될지 확신이 서지 않는 경우 --dryrun 명령에 aws s3 mv 옵션을 추가하면 명령이 실행되지 않고 시뮬레이션되고 결과가 인쇄됩니다.

일부 개인 메모



이것은 파일을 이동해야 하는 경우 매우 편리한 트릭입니다. 적은 양의 파일에서 훌륭하게 작동합니다. 또한 인터넷 연결 실패에도 강합니다. 연결이 실패하면(또는 프로세스를 종료하거나, 죽으면) 다시 실행할 수 있으며, 연결은 남아 있던 곳에서 선택합니다.

더 많은 양의 파일이 있는 경우 이 명령을 실행하는 많은 백그라운드 프로세스를 시작할 수 있으며 작동해야 합니다(결과에 페이지를 매기거나 현명하게 분할하고 싶을 수 있음). 반면에 파일의 양이 너무 많으면 쓰기 중 복사 또는 읽기 중 복사 전략이 더 잘 작동하지만 이를 위해 약간의 프로그래밍이 필요합니다.

도움이 되었기를 바랍니다! 질문이 있으시면 댓글로 알려주세요.

좋은 웹페이지 즐겨찾기