약 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
목록이 올바르게 읽혔는지 확인할 수 있습니다 .