เพิ่มความเร็วในการคัดลอกไฟล์ขนาดเล็ก 1000000


11

ฉันมี 1000000 4-20 kb ไฟล์ใน dir ฉันต้องการคัดลอกผบ. แต่ดูเหมือนว่าฉันต้องทำการค้นหาไฟล์แต่ละไฟล์ดังนั้นจึงใช้เวลาค่อนข้างนาน

มีวิธีใดบ้างที่ฉันจะเร่งความเร็วนี้?

ฉันกำลังคิดว่าถ้าฉันสามารถรับบล็อกดิสก์ที่ไฟล์เหล่านี้ครอบครองฉันสามารถเรียงลำดับเหล่านั้นรวมบล็อกที่อยู่ใกล้ (เนื่องจากการอ่านตามลำดับมักจะเร็วกว่าการค้นหา) และอ่านบล็อกเหล่านี้เพื่อให้พวกเขาอยู่ใน RAM แคช (ฉันมี RAM 32 GB) ก่อนทำสำเนา

แต่สำหรับการทำงานฉันต้องการวิธีที่จะระบุว่าบล็อกใดที่เปิดอยู่

ฉันใช้ EXT4 บนอุปกรณ์แม่เหล็ก (เช่นไม่ใช่ SSD)

แก้ไข:

สิ่งนี้ควรใช้งานได้ แต่ไม่ได้:

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'

เมื่อทำการทดสอบกับไฟล์ขนาดใหญ่มันจะไม่ทำการแคชไฟล์

Edit2:

นี่คือมาตรฐานบางอย่าง แคชถูกล้าง ( echo 3 >/proc/sys/vm/drop_caches) ระหว่างการรันแต่ละครั้ง 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

แล้วเราจะเรียนรู้อะไรได้บ้าง?

ดูเหมือนว่าการเรียงลำดับโดย inode เป็นความคิดที่ดี แต่ดูเหมือนว่าการทำงานแบบหลายขนานจะcpเพิ่มประสิทธิภาพให้ดียิ่งขึ้นไปอีก เป็นการเน้นว่าแหล่งข้อมูลfoo/นั้นเป็นดิสก์แม่เหล็กดังนั้นการโจมตีตำนานที่ขนาน I / O กับแกนหมุนเดี่ยวจะไม่เพิ่มความเร็ว I / O: การขนานอย่างชัดเจนและเร่งความเร็วในการคัดลอกที่นี่อย่างสม่ำเสมอ


ไดเรกทอรีของคุณมีเฉพาะไฟล์หรือไม่ ตำแหน่งเป้าหมายของคุณอยู่ในระบบไฟล์เดียวกันหรือไม่?
โจเซฟอาร์

สำหรับคำสั่งที่แน่นอนที่คุณใช้สำหรับการคัดลอก? อะไรที่คล้ายกันcp -r /mnt/dir1 /mnt/dirdestหรืออะไรทำนองนั้นcp /mnt/dir1/* /mnt/dirdest?
maxschlepzig

เฉพาะไฟล์ แต่ไม่ใช่ระบบไฟล์เดียวกัน: cp -r / mnt / dir1 / mnt2 / dirdest
Ole Tange

btw ฉันไม่คิดว่าจะช่วยถ้าคุณเรียกใช้การเข้าถึงฮาร์ดดิสก์แบบขนานเมื่อคุณต้องการลดการค้นหาดิสก์
maxschlepzig

ฉันเขียนโปรแกรมที่สั่งซื้อไฟล์ตามจำนวนขอบเขต (มีแนวโน้มที่จะเกิดขึ้นบนดิสก์) ที่นี่: github.com/nh2/diskorder
nh2

คำตอบ:


9

สมมติว่า

  • รายการที่ส่งคืนโดยreaddirไม่เรียงลำดับตามหมายเลข inode
  • การอ่านไฟล์ตามลำดับ inode จะลดจำนวนการดำเนินการค้นหา
  • เนื้อหาของไฟล์ส่วนใหญ่อยู่ในการจัดสรรเริ่มต้น 8k (การเพิ่มประสิทธิภาพ ext4) ซึ่งควรให้ผลการค้นหาน้อยลง

คุณสามารถลองเพิ่มความเร็วการคัดลอกผ่านการคัดลอกไฟล์ตามลำดับ inode

นั่นหมายถึงการใช้สิ่งนี้:

$ cd /mnt/src
$ ls -U -i | sort -k1,1 -n | cut -d' ' -f2- > ~/clist
$ xargs cp -t /mnt2/dst < ~/clist

@mikeserv คุณหมายถึงอะไร ls -Uไม่เพียงพอเพราะมันไม่ได้เรียงลำดับตามหมายเลขไอโหนด ... และทำไมฉันจึงควรต้องการ-1?
maxschlepzig

@mikeserv 'in order directory' ไม่เหมือนกับ inode order! หากเป็นกรณีนี้คุณจะไม่ต้องใช้คำอื่นในการนี้ สิ่งที่คุณพบว่าแปลกไม่เกี่ยวข้อง ฉันได้ทดสอบกับระบบไฟล์ ext4 แล้ว และมีคำสั่งไดเรกทอรีแตกต่างจากลำดับ inode -1เพียงแค่แสดง 'หนึ่งไฟล์ต่อบรรทัด' - มันไม่ช่วยให้มีบรรทัดใหม่ในชื่อไฟล์ find -print0/xargs -Oเพื่อที่คุณจะสามารถใช้
maxschlepzig

@mikeserv คุณกำลังพูดถึงอะไร ตัวอย่างตัวนับ: mkdir tmp; cd tmp; touch foo"<RETURN>"bar; lsพิมพ์ 'foo? bar' ls -1ยัง 'foo? บาร์' พิมพ์ ls -1 | wc -lพิมพ์ '2' find -lsพิมพ์ชื่อไฟล์เป็น './foo\nbar' cp -i LS -1 x` ล้มเหลวด้วย 'ซีพี: เป้าหมาย 'x' ไม่ได้เป็นไดเรกทอรี'
maxschlepzig

ประณาม - คุณกำลังสอนฉันไปทางซ้ายและขวา! -qทำในสิ่งที่ฉันคิดว่า-1จะ! อีกครั้งฉันขอโทษ - ไม่ต้องพูดถึงขอบคุณ
mikeserv

4

GNU tar- ตามpaxธรรมเนียม - จัดการฮาร์ดลิงก์ด้วยตัวมันเอง

cd "$srcdir" ; tar --hard-dereference -cf - ./* |
    tar -C"${tgtdir}" -vxf -

ด้วยวิธีนี้คุณมีเพียงสองtarกระบวนการและคุณไม่จำเป็นต้องเรียกใช้cpซ้ำแล้วซ้ำอีก


2

ในหลอดเลือดดำที่คล้ายกับคำตอบของ @ maxschlepzigคุณสามารถแยกวิเคราะห์ผลลัพธ์ของfilefragการเรียงลำดับไฟล์ตามลำดับที่แฟรกเมนต์แรกของพวกเขาปรากฏบนดิสก์:

find . -maxdepth 1 -type f |
  xargs -d'\n' filefrag -v |
  sed -n '
    /^   0:        0../ {
      s/^.\{28\}\([0-9][0-9]*\).*/\1/
      h
      }
    / found$/ {
      s/:[^:]*$//
      H
      g
      s/\n/ /p
      }' |
    sort -nk 1,1 |
    cut -d' ' -f 2- |
    cpio -p dest_dir

MMV ด้วยsedสคริปต์ด้านบนดังนั้นโปรดทดสอบอย่างละเอียด

มิฉะนั้นสิ่งที่คุณทำfilefrag(ส่วนหนึ่งe2fsprogs) จะเร็วกว่าการใช้มากกว่าhdparmที่จะใช้อาร์กิวเมนต์ไฟล์หลายไฟล์ แค่ค่าใช้จ่ายในการวิ่งhdparm1,000,000 ครั้งก็จะเป็นการเพิ่มค่าใช้จ่ายจำนวนมาก

นอกจากนี้อาจเป็นเรื่องยากที่จะเขียนperlสคริปต์ (หรือโปรแกรม C) ไปยังFIEMAP ioctlไฟล์แต่ละไฟล์สร้างอาเรย์เรียงลำดับของบล็อกที่ควรคัดลอกและไฟล์ที่เป็นของแล้วคัดลอกทุกอย่างตามลำดับ อ่านขนาดของแต่ละบล็อกจากไฟล์ที่เกี่ยวข้อง (ระวังอย่าให้ไฟล์ descriptor หมด)


นี่เป็นสิ่งที่ดีโปรดดูhome.ifi.uio.no/paalh/publications/files/ipccc09.pdfสำหรับกระดาษที่อธิบายวิธีการและแสดงการเร่งความเร็ว 4x tarสำหรับไฟล์ของพวกเขา
nh2

1
ฉันได้ส่งอีเมลถึงผู้เขียนบทความโดยถามว่าพวกเขาสามารถเผยแพร่qtarเป็นโอเพ่นซอร์สหรือไม่ ได้แล้วที่github.com/chlunde/qtar
nh2
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.