[EDIT: я решил (?) Проблему самостоятельно и соответственно обновил вопрос]
У меня есть сценарий Python, который выполняет ежедневное резервное копирование большой папки (с подпапками). Поскольку папка стала слишком большой, а процесс резервного копирования занимает слишком много времени, из-за того, что процесс связан с ЦП, мне потребовалось изменить сценарий, чтобы использовать несколько ядер ЦП на сервере.
ПРИМЕЧАНИЕ. вероятно, это лучшие модули и функции для использования в этом варианте использования, но использование multiprocessing.Pool()
применительно к subprocess.call
к rsync
является требованием, от которого я не мог отклониться.
- I пару недель боролся с этим, потому что у меня всегда было несколько дубликатов в папке назначения (отсюда исходный вопрос); Теперь я нашел неуклюжее, но работающее решение, разделив пути к файлам / папкам и снова объединив их (используя
os.path.join
): есть ли лучший способ сделать это? - Хотя сценарий создает точную резервную копию исходной папке, я все еще получаю некоторые подозрительные сообщения об ошибках rsyn c во время выполнения, и я беспокоюсь, что все рухнет, как только будет выполнена неправильная комбинация процессов: может ли кто-нибудь взглянуть на них и сказать мне, если я нужно беспокоиться?
Вот (минимальная рабочая версия) кода, который я написал, прокомментировал:
#!/usr/bin/env python3
import os
import multiprocessing
import subprocess
#In this test /src/ and /dest/ are in the same folder of the script
source = os.path.join(os.getcwd(),"src")
destination = os.path.join(os.getcwd(),"dest")
def get_pathlist(folder):
pathlist = []
#No need for the FULL path of the dir/file
#The source directory is in a global variable
for root,dirs,files in os.walk(folder):
for f in files:
#Extract the sub-folder (if any)
path = root[len(folder):]
#Extract the filename
item = f
#Store the RELATIVE path in a tuple
pathlist.append((path,item))
for d in dirs:
#Extract the sub-folder (if any)
path = root[len(folder):]
#Extract the folder name
item = d
#Store the RELATIVE path in a tuple
pathlist.append((path,item))
#Return the list of tuples
return pathlist
def backup(path):
#Source = root, path[0] = sub-folder, path[1] = file/dir name
#NB: We input the FULL path of the source file/folder
src = os.path.join(source,path[0],path[1])
#Destination = root, path[0] = sub-folder
#NB: We input the destination folder only (no need for the file/folder name)
dest = os.path.join(destination,path[0])
subprocess.call(['rsync', '-azq', src, dest])
if __name__ == "__main__":
src_pathlist = get_pathlist(source)
with multiprocessing.Pool(len(src_pathlist),maxtasksperchild=1) as mpool:
mpool.map(backup,src_pathlist)
Как я уже упоминал, сценарий дает желаемый результат, но я получаю какие-то странные ошибки от rsyn c. Структура / src / выглядит следующим образом (для справки):
/src/
/1.txt
/Folder
/Folder/2.txt
/Folder/New_folder-A
/Folder/New_folder-B
/Folder/New_folder-C
/Folder/New_folder-A/3A.txt
/Folder/New_folder-B/3B.txt
Я получаю следующие ошибки:
rsync: change_dir "/Folder" failed: No such file or directory (2)
rsync: change_dir "/Folder" failed: No such file or directory (2)
rsync: change_dir "/Folder" failed: No such file or directory (2)
rsync: change_dir "/Folder" failed: No such file or directory (2)
rsync: change_dir "/Folder/New_folder-A" failed: No such file or directory (2)
rsync: change_dir#3 "/Folder" failed: No such file or directory (2)
rsync error: errors selecting input/output files, dirs (code 3) at main.c(720) [Receiver=3.1.3]
rsync: change_dir "/Folder/New_folder-B" failed: No such file or directory (2)
rsync: change_dir#3 "/Folder" failed: No such file or directory (2)
rsync error: errors selecting input/output files, dirs (code 3) at main.c(720) [Receiver=3.1.3]
rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1207) [sender=3.1.3]
rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1207) [sender=3.1.3]
rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1207) [sender=3.1.3]
rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1207) [sender=3.1.3]
Может ли кто-нибудь пролить свет на это? Любые предложения по улучшению ОЧЕНЬ приветствуются.