Przeniesienie 2 TB (10 milionów plików + katalogi), jakie jest moje wąskie gardło?

21

tło

I zabrakło miejsca na /home/datai trzeba przenieść /home/data/repodo /home/data2.

/home/data/repozawiera 1M katalogów, z których każdy zawiera 11 katalogów i 10 plików. Łącznie wynosi 2 TB.

/home/datajest na ext3 z włączonym dir_index. /home/data2jest na ext4. Uruchamianie CentOS 6.4.

Zakładam, że te podejścia są powolne, ponieważ repo/bezpośrednio pod nimi znajduje się 1 milion reż.


Próba 1: mvjest szybka, ale zostaje przerwana

Mógłbym to zrobić, gdyby to się skończyło:

/home/data> mv repo ../data2

Ale zostało przerwane po przeniesieniu 1,5 TB. Pisał z prędkością około 1 GB / min.

Próba 2: rsyncindeksuje się po 8 godzinach budowania listy plików

/home/data> rsync --ignore-existing -rv repo ../data2

Utworzenie „przyrostowej listy plików” zajęło kilka godzin, a następnie przesyłano z prędkością 100 MB / min.

Anuluję to, aby spróbować szybszego podejścia.

Próba 3a: mvnarzeka

Testowanie w podkatalogu:

/home/data/repo> mv -f foobar ../../data2/repo/
mv: inter-device move failed: '(foobar)' to '../../data2/repo/foobar'; unable to remove target: Is a directory

Nie jestem pewien, o co chodzi z tym błędem, ale może cpmnie uratuje ...

Próba 3b: cpnigdzie nie dotrze po 8 godzinach

/home/data> cp -nr repo ../data2

Czyta dysk przez 8 godzin i postanawiam go anulować i wrócić do rsync.

Próba 4: rsyncindeksuje się po 8 godzinach budowania listy plików

/home/data> rsync --ignore-existing --remove-source-files -rv repo ../data2

Myślałem, --remove-source-filesże może to przyspieszyć, jeśli zacznę teraz czyszczenie.

Tworzenie listy plików zajmuje co najmniej 6 godzin, a następnie przesyła z prędkością 100-200 MB / min.

Ale serwer był z dnia na dzień obciążony i moje połączenie zostało zamknięte.

Próba 5: POSTĘPUJE TYLKO 300 GB, DLACZEGO JEST TO TAK Bolesne

/home/data> rsync --ignore-existing --remove-source-files -rvW repo ../data2

Znów przerwane. -WPrawie wydawało się „wysyłanie przyrostową listę plików” szybciej, co w moim rozumieniu nie powinno mieć sens. Niezależnie od tego transfer jest strasznie powolny i rezygnuję z tego.

Próba 6: tar

/home/data> nohup tar cf - . |(cd ../data2; tar xvfk -)

Zasadniczo próba skopiowania wszystkiego, ale ignorowanie istniejących plików. Musi przebrnąć przez 1,7 TB istniejących plików, ale przynajmniej odczytuje z prędkością 1,2 GB / min.

Jak dotąd jest to jedyne polecenie, które daje natychmiastową satysfakcję.

Aktualizacja: jakoś przerwana, nawet bez nohup ..

Próba 7: harakiri

Nadal debatuję nad tym

Próba 8: skryptowe „scalenie” z mv

Docelowy katalog miał około 120 tysięcy pustych katalogów, więc pobiegłem

/home/data2/repo> find . -type d -empty -exec rmdir {} \;

Skrypt Ruby:

SRC  = "/home/data/repo"
DEST = "/home/data2/repo"

`ls #{SRC}  --color=never > lst1.tmp`
`ls #{DEST} --color=never > lst2.tmp`
`diff lst1.tmp lst2.tmp | grep '<' > /home/data/missing.tmp`

t = `cat /home/data/missing.tmp | wc -l`.to_i
puts "Todo: #{t}"

# Manually `mv` each missing directory
File.open('missing.tmp').each do |line|
  dir = line.strip.gsub('< ', '')
  puts `mv #{SRC}/#{dir} #{DEST}/`
end

GOTOWY.

Tim
źródło
Masz rację, musi znaleźć i wyliczyć każdy katalog, a 1 milion katalogów będzie bolesny.
cybernard
2
Spójrz na jasną stronę ... gdyby to był Windows, nie byłoby nawet miliona podkatalogów i nadal działałby system operacyjny. :)
Jack
1
@ Tim, dlaczego jeszcze nie mvraz? Teoretycznie mvusunie plik źródłowy tylko wtedy, gdy plik docelowy został całkowicie skopiowany, więc powinien działać poprawnie. Ponadto, czy masz fizyczny dostęp do maszyny, czy jest to wykonywane przez sshpołączenie?
terdon
5
Nie, nie może. mvnie wybacza, jeśli będziesz się rozłączać, możesz stracić dane, a nawet ich nie znać. Jak powiedziałeś, że robisz to po raz kolejny ssh, zdecydowanie polecam używanie screeni odłączanie. Włącz rejestrowanie i śledź w ten sposób. Jeśli używasz pełnego tekstu, potrwa to dłużej. Spróbuj takżeiotop
wystarczy przeglądać
2
@ justbrowsing - Good call on screen. Zastanawiałem się nad gadatliwością, ale wydaje mi się, że jest już za późno na ponowne uruchomienie tar. I iotopbył moim ulubionym narzędziem od kilku ostatnich dni :)
Tim

Odpowiedzi:

6

Słyszałeś kiedyś o dzieleniu dużych zadań na mniejsze?

/ home / data / repo zawiera 1 mln katalogów, z których każdy zawiera 11 katalogów i 10 plików. Łącznie wynosi 2 TB.

rsync -a /source/1/ /destination/1/
rsync -a /source/2/ /destination/2/
rsync -a /source/3/ /destination/3/
rsync -a /source/4/ /destination/4/
rsync -a /source/5/ /destination/5/
rsync -a /source/6/ /destination/6/
rsync -a /source/7/ /destination/7/
rsync -a /source/8/ /destination/8/
rsync -a /source/9/ /destination/9/
rsync -a /source/10/ /destination/10/
rsync -a /source/11/ /destination/11/

(...)

Czas na kawę.

Ярослав Рахматуллин
źródło
1
Korzyść, którą niejasno podkreślam, polega na tym , że ręcznie śledzisz postęp w małych częściach, dzięki czemu wznowienie zadania zajmie mniej czasu, jeśli część zostanie przerwana (ponieważ wiesz, które kroki zostały pomyślnie zakończone).
Ярослав Рахматуллин
To w zasadzie to, co ostatecznie skończyłem, z wyjątkiem mv. Niefortunne spotkanie nie jest narzędziem mvi rsyncpołowy.
Tim
4

Oto co się dzieje:

  • Początkowo rsync zbuduje listę plików.
  • Budowanie tej listy jest bardzo powolne, ze względu na wstępne sortowanie listy plików.
  • Można tego uniknąć, używając ls -f -1 i łącząc go z xargs do budowania zestawu plików, które będzie używane przez rsync, lub przekierowując dane wyjściowe do pliku z listą plików.
  • Przekazanie tej listy do rsync zamiast do folderu spowoduje, że rsync zacznie działać natychmiast.
  • Ta sztuczka ls -f -1 na folderach z milionami plików jest doskonale opisana w tym artykule: http://unixetc.co.uk/2012/05/20/large-directory-causes-ls-to-hang/
maki
źródło
1
Czy możesz podać przykład użycia ls z rsync? Mam podobną, ale nie identyczną sytuację. Na komputerze AI uruchomiono rsyncd i duże drzewo katalogów, które chcę przenieść na maszynę B (w rzeczywistości 90% katalogu jest już w B). Problem polega na tym, że muszę to zrobić za pomocą niestabilnego połączenia mobilnego, które często spada. Spędzanie godziny na tworzeniu listy plików przy każdym ponownym uruchomieniu jest dość nieefektywne. Ponadto B jest za NAT, którego nie kontroluję, więc trudno jest połączyć A -> B, podczas gdy B -> A jest łatwe.
db
Zgadzam się z @db. Gdyby można podać przykład, ta odpowiedź byłaby znacznie bardziej przydatna.
redfox05
1

Nawet jeśli rsync jest wolny (dlaczego jest wolny? Może -z pomoże), brzmi to tak, jakbyś dużo go przeniósł, więc możesz po prostu spróbować:

Jeśli użyłeś --remove-source-files, możesz kontynuować, usuwając puste katalogi. --remove-source-files usunie wszystkie pliki, ale pozostawi tam katalogi.

Tylko upewnij się, że NIE korzystasz z --remove-source-files z opcją --delete do wykonywania wielu przejść.

Również w celu zwiększenia prędkości możesz użyć - inplace

Jeśli jesteś wyrzucany, ponieważ próbujesz to zrobić zdalnie na serwerze, śmiało i uruchom to w sesji „screen”. Przynajmniej w ten sposób możesz pozwolić mu działać.

Angelo
źródło