Mam pliki 1000000 4-20 kb w reż. Muszę skopiować ten reż. Ale wydaje się, że muszę szukać każdego pliku, więc zajmuje to sporo czasu.
Czy jest sposób, aby przyspieszyć to?
Obecnie myślę, że gdybym mógł uzyskać bloki dyskowe zajmowane przez te pliki, mógłbym je posortować, scalić bloki, które były blisko (biorąc pod uwagę, że sekwencyjny odczyt jest często szybszy niż wyszukiwanie) i odczytać te bloki, aby były w pamięci RAM pamięć podręczna (mam 32 GB pamięci RAM) przed wykonaniem kopii.
Ale żeby to zadziałało, potrzebuję sposobu, aby określić, które bloki są na plikach.
Używam EXT4 na urządzeniu magnetycznym (tj. Nie SSD).
Edytować:
To powinno zadziałać, ale nie:
ls |
parallel -IOO --pipe "sudo parallel -j100 hdparm --fibmap {}'|tail -n +5'" |
sort -nk 2 |
perl -ane 'if($u+10000 < $F[1]) { print "$l ",($u-$l),"\n"; $l=$F[1] } $u=$F[2]' |
sudo parallel --colsep ' ' dd if=/dev/sda1 skip={1} bs=512 count={2} '| cat >/dev/null'
Podczas testowania na dużym pliku plik nie jest buforowany.
Edycja2:
Oto kilka punktów odniesienia. Pamięć podręczna została opróżniona ( echo 3 >/proc/sys/vm/drop_caches
) między każdym uruchomieniem. Pomiary wykonane za pomocą iostats -dkx 5
.
rsync -Hav foo/ bar/: 1800 KB/s
cp -a foo/ bar/: 3600 KB/s
cat sort-by-inode | parallel -j1 -X cp foo/{} bar/: 5000 KB/s
cat sort-by-inode | shuf | parallel -j1 -X cp foo/{} bar/: 3000 KB/s
cat sort-by-inode | shuf | parallel -j10 -X cp foo/{} bar/: 7000 KB/s
cat sort-by-inode | parallel -j10 -X cp foo/{} bar/: 8000 KB/s
cat sort-by-inode | parallel -j100 -X cp foo/{} bar/: 9000 KB/s
cat sort-by-inode | parallel -j500 -X cp foo/{} bar/: 10000 KB/s
Czego możemy się z tego nauczyć?
Wygląda na to, że sortowanie według i-węzłów jest dobrym pomysłem. Ale wydaje się, że równoległe wielokrotne cp
zwiększenie wydajności jeszcze bardziej. Warto podkreślić, że źródłem foo/
jest dysk magnetyczny, więc to atakuje mit, że równoległe we / wy do pojedynczego wrzeciona nie przyspieszy we / wy: równoległe wyraźnie i konsekwentnie przyspiesza kopiowanie.
źródło
cp -r /mnt/dir1 /mnt/dirdest
lub coś takiegocp /mnt/dir1/* /mnt/dirdest
?Odpowiedzi:
Przy założeniu, że
readdir
nie są sortowane według numeru i-węzłamożesz spróbować przyspieszyć kopiowanie poprzez kopiowanie plików w kolejności i-węzłów.
Oznacza to użycie czegoś takiego:
źródło
ls -U
to za mało, ponieważ nie sortuje według numerów i-węzłów ... i dlaczego miałbym chcieć-1
?-1
wyświetla tylko „jeden plik w wierszu” - nie pomaga w przypadku nowych wierszy w nazwach plików. Do tego możesz użyćfind -print0/xargs -O
.mkdir tmp; cd tmp; touch foo"<RETURN>"bar; ls
wypisuje „foo? Bar”.ls -1
Również 'foo? Bar' odbitek. Als -1 | wc -l
drukuje '2'. Afind -ls
drukuje nazwy pliku jako './foo\nbar. Acp -i
ls -1` x` kończy się niepowodzeniem z „cp: target” x ”nie jest katalogiem”.-q
robi to, co myślałem-1
, że zrobię ! Jeszcze raz przepraszam - nie wspominając o podziękowaniach.GNU
tar
- zgodnie zpax
tradycją - samodzielnie obsługuje łącza twarde.W ten sposób masz tylko dwa
tar
procesy i nie musisz ciągle powoływaćcp
się.źródło
W podobnym tonie do użytkownika @ maxschlepzig odpowiedź, można analizować dane wyjściowe
filefrag
do plików sortowane w kolejności ich pierwsze fragmenty pojawiają się na dysku:MMV z powyższym
sed
skryptem, więc należy dokładnie przetestować.W przeciwnym razie cokolwiek zrobisz
filefrag
(częśće2fsprogs
) będzie znacznie szybsze w użyciu, niżhdparm
może wymagać wielu argumentów pliku. Samo obciążenie związane z uruchomieniemhdparm
1 000 000 razy spowoduje znaczne obciążenie.Również prawdopodobnie nie byłoby tak trudno napisać
perl
skrypt (lub program C),FIEMAP
ioctl
dla każdego pliku, utworzyć posortowaną tablicę bloków, które należy skopiować, a pliki należy do, a następnie skopiować wszystko w kolejności według odczytanie rozmiaru każdego bloku z odpowiedniego pliku (uważaj, aby nie zabrakło deskryptorów plików).źródło
tar
dla ich plików.qtar
jako open source; jest teraz na github.com/chlunde/qtar