단 2시간 후에도 rsync 파일이 수정되지 않았습니까?

단 2시간 후에도 rsync 파일이 수정되지 않았습니까?

약 2시간마다 새 바이너리를 생성하는 원격 서버에 애플리케이션이 있습니다. 6분마다 새 데이터가 있으면 파일이 업데이트됩니다. 19번의 추가 후에 닫힙니다. 즉, 6분마다 새 데이터가 있으면 1시간 54분 후에 닫힙니다.

쪽모이 세공 파일입니다.

  • Parquet 파일은 닫히지 않을 때까지 첨부할 수 있습니다. 이것이 바로 내 응용 프로그램이 수행하는 작업입니다.
  • 쪽모이 세공 파일은 닫힐 때까지 열 수 없습니다.

파일 이름은 아래와 같은 형식을 취합니다. 마지막 숫자는 파일이 생성된 타임스탬프입니다. 이 타임스탬프는 이후에 업데이트되지 않습니다.

my-data-1602915797.parquet
my-data-1609890860.parquet
my-other-d-1609990998.parquet
my-other-d-1610000010.parquet

전체 파일이 작성되고 로컬(8To 로컬 하드 드라이브)에 안전하게 복사되면 원격에서 삭제해야 합니다(원격에는 160Go 하드 드라이브만 있음). 애플리케이션은 4~5 Go의 하늘 당 데이터.

한 달에 한 번 이 파일 전송을 시작할 계획입니다.

그래서 이미 마감된 것들만 옮기고 싶습니다. 이를 선택하려면 SSH를 사용할 수 있습니다.

# IP address is a dummy address ;)
ssh [email protected] "find /root/my_data -name *.parquet -maxdepth 1 -type f -mmin +180"

그런 다음 에 입력합니다 rsync.

그런데 그러다가 알게 됐어요이 스레드를 이용하면 해결이 가능하다고 합니다 rsync -a.

rsync 매뉴얼 페이지를 보면 이 매개변수가 이러한 요구를 어떻게 충족하는지 알 수 없습니다. 누구든지 내가 이것을 이해하도록 도와줄 수 있나요?

피드백을 보내주셔서 감사합니다. 정말 감사합니다.

답변1

rsync설명에 따라 파일을 복사하고 복사가 성공한 후 삭제할 수 있습니다 .

rsync --dry-run -avz --remove-source-files [email protected]:'$(find /root/my_data -maxdepth 1 -name "*.parquet" -type f -mmin +30)' /my/destination

참고하시기 바랍니다,

  • $( find ... )로컬 서버 대신 원격 서버의 컨텍스트에서 실행되도록 계산된 명령을 큰따옴표 대신 작은따옴표로 묶습니다.
  • *.parquet쉘이 하나 이상의 쪽모이 세공 파일과 일치하는 것을 방지하는 방법을 인용했습니다.
  • 마지막 업데이트 이후 지연 시간을 180분에서 단 30분으로 줄였습니다. (최신 파일이 6분마다 업데이트된다고 했으니 30분이면 충분합니다.)
  • -z나는 네트워크 연결에서 데이터 스트림을 압축 하곤 했습니다 . 사전 압축된 데이터를 사용하더라도 이는 약간의 도움이 될 것입니다.
  • 이 디렉토리는 /my/destination쪽모이 세공 파일이 이동된 로컬 디렉토리입니다.

--dry-run이 기능을 활성화하여 무슨 일이 일어날지 확인한 다음 예상 결과에 만족하면 매개변수를 제거하는 것이 좋습니다.

--progress각 파일의 전송 진행 상황을 실시간으로 보고 싶다면 추가하세요. -P또는 여기를 사용하지 마십시오 --partial.

"닫힌" 파일을 식별하는 쉬운 방법은 없다는 점을 지적하고 싶습니다. 를 사용할 코드를 작성 하거나 제품군에서 제공되는 lsof일부 코드를 작성할 수 있습니다 . inotify내가 여기서 하고 있는 일은 운영 체제가 이에 따라 파일 수정 시간을 자동으로 업데이트할 수 있도록 응용 프로그램을 사용하여 마지막 업데이트 후 30분 이내에 현재 파일에 쓰는 것입니다. 응용 프로그램이 파일 수정 시간(파일 이름이 아닌 메타데이터)을 조작하면 문제가 발생합니다.

가장 깔끔한 해결책은 애플리케이션을 수정하여 파일을 생성한 *.parquet.tmp다음 , *.parquet작성이 완료되면 해당 파일의 이름을 바꾸는 것입니다. (이렇게 하면 파일만 완전하여 복사에 적합하다는 것을 보장할 수 있습니다 *parquet.) 그러나 이것이 불가능할 수도 있다는 것을 알고 있습니다.

답변2

파일을 실제로 복사할 수 없는 경우(파일이 닫히지 않은 경우) find파일 목록 생성을 사용할 수 있습니다.rsync

직접 사용할 수도 있습니다 rsync. 열린 파일의 일부를 복사하지만 그게 왜 중요한가요? 변경되면 rsync업데이트된 것을 확인하고 동기화할 수 있습니다.

답변3

@Lucas의 제안을 사용하여 탐색하면서 lsof다음 두 줄을 생각해 냈습니다.

명령 출력을 lsof깔끔한 파일 이름 목록으로 형식화하는 것은 상당히 복잡해집니다. 그러나 이 방법을 사용하면 파일을 생성한 응용 프로그램에서 어떤 변경이 이루어졌는지에 관계없이 닫힌 파일만 보관됩니다.

ssh root@"$RMT_IP" "lsof +D "$RMT_PATH_DATA" | tr -s ' ' | cut -d' ' -f9 | tail -n +2 | grep '.parquet$' | xargs -n 1 basename"  > "$OPEN_FILES"
rsync --dry-run -avv --remove-source-files --exclude-from="$OPEN_FILES" root@"$RMT_IP":"$RMT_PATH_DATA"/*.txt "$TEMP_LOC_PATH"

-vv 매개변수는 rsync건너뛴 자세한 정보 파일을 생성합니다. 내 테스트 파일에서 $OPEN_FILES목록이 올바르게 읽혔는지 확인할 수 있습니다 .

관련 정보