การย้าย 2TB (10 ล้านไฟล์ + dirs) ปัญหาคอขวดของฉันคืออะไร


21

พื้นหลัง

ฉันวิ่งออกมาจากพื้นที่บน/home/dataและความจำเป็นในการถ่ายโอนไป/home/data/repo/home/data2

/home/data/repoมี 1M dirs ซึ่งแต่ละไฟล์มี 11 dirs และ 10 ไฟล์ มันรวม 2TB

/home/dataเปิดใช้ ext3 เมื่อเปิดใช้งาน dir_index /home/data2อยู่ใน ext4 CentOS กำลังใช้งาน 6.4

ฉันคิดว่าวิธีการเหล่านี้ช้าเพราะความจริงที่ว่าrepo/มี 1 ล้าน dirs อยู่ข้างใต้


ความพยายามที่ 1: mvเร็ว แต่ขัดจังหวะ

ฉันสามารถทำได้ถ้าสิ่งนี้เสร็จสิ้น:

/home/data> mv repo ../data2

แต่มันถูกขัดจังหวะหลังจากถ่ายโอน 1.5TB มันเขียนที่ประมาณ 1GB / นาที

ความพยายามที่ 2: rsyncรวบรวมข้อมูลหลังจากสร้างรายการไฟล์ 8 ชั่วโมง

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

ใช้เวลาหลายชั่วโมงในการสร้าง 'รายการไฟล์ที่เพิ่มขึ้น' จากนั้นจะถ่ายโอนที่ 100MB / นาที

ฉันยกเลิกเพื่อลองใช้วิธีที่รวดเร็วกว่า

พยายาม 3a: mvบ่น

ทดสอบในไดเรกทอรีย่อย:

/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

ฉันไม่แน่ใจว่านี่เป็นข้อผิดพลาดเกี่ยวกับอะไร แต่อาจcpประกันตัวฉัน

พยายาม 3b: cpหายไปหลังจาก 8 ชั่วโมง

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

มันอ่านดิสก์เป็นเวลา 8 ชั่วโมงและฉันตัดสินใจที่จะยกเลิกและกลับไปที่ rsync

ความพยายามที่ 4: rsyncรวบรวมข้อมูลหลังจากสร้างรายการไฟล์ 8 ชั่วโมง

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

ฉันเคย--remove-source-filesคิดว่ามันอาจทำให้เร็วขึ้นถ้าฉันเริ่มล้างข้อมูลตอนนี้

ใช้เวลาอย่างน้อย 6 ชั่วโมงในการสร้างรายการไฟล์จากนั้นถ่ายโอนที่ 100-200MB / นาที

แต่เซิร์ฟเวอร์นั้นค้างคืนและการเชื่อมต่อของฉันปิด

ความพยายามที่ 5: มีเพียง 300GB ทางซ้ายเพื่อย้ายทำไมจึงเป็นเช่นนี้

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

ขัดจังหวะอีกครั้ง -Wเกือบดูเหมือนจะทำให้ "การส่งรายชื่อไฟล์ที่เพิ่มขึ้น" เร็วขึ้นซึ่งความเข้าใจของเราไม่ควรทำให้ความรู้สึก ไม่ว่าการถ่ายโอนจะช้าอย่างน่ากลัวและฉันก็ยอมแพ้กับมัน

พยายาม 6: tar

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

โดยทั่วไปพยายามที่จะคัดลอกทุกอย่าง แต่ไม่สนใจไฟล์ที่มีอยู่ ต้องลุยไฟล์ที่มีอยู่ 1.7TB แต่อย่างน้อยก็อ่านได้ที่ 1.2GB / นาที

จนถึงตอนนี้เป็นคำสั่งเดียวที่ให้ความพึงพอใจทันที

Update: ขัดจังหวะอีกครั้งอย่างใดแม้จะมี nohup ..

ความพยายามที่ 7: ฮาราคีรี

ยังคงถกเถียงกันเรื่องนี้

ความพยายามที่ 8: สคริปต์ 'รวม' กับ mv

ปลายทางของฉันมีที่ว่างเปล่าประมาณ 120k ดังนั้นฉันจึงวิ่ง

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

สคริปต์ 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

DONE


คุณถูกต้องมันจะต้องค้นหาและแจกแจงแต่ละไดเรกทอรีและ 1 ล้าน dirs จะเจ็บปวด
cybernard

2
ดูด้านสว่าง ... ถ้าเป็น Windows คุณจะไม่สามารถมีไดเรกทอรีย่อยได้นับล้านและยังมีระบบปฏิบัติการที่ใช้งานได้ :)
แจ็ค

1
@ เวลาทำไมคุณไม่ทำmvอีกครั้ง ในทางทฤษฎีmvจะลบไฟล์ต้นฉบับเฉพาะเมื่อไฟล์ปลายทางได้รับการคัดลอกอย่างสมบูรณ์ดังนั้นจึงควรใช้งานได้ คุณมีการเข้าถึงเครื่องหรือทำผ่านการsshเชื่อมต่อหรือไม่?
terdon

5
ไม่มันไม่สามารถ mvไม่ให้อภัยหากคุณยังคงถูกตัดการเชื่อมต่อคุณอาจสูญเสียข้อมูลและไม่รู้ตัวเลย อย่างที่คุณบอกว่าคุณกำลังทำสิ่งนี้อยู่sshฉันขอแนะนำให้ใช้screenและถอดออก เปิดใช้งานการบันทึกและติดตามวิธีนั้น หากคุณกำลังใช้ verbose มันจะใช้เวลานาน นอกจากนี้ยังพยายามiotop
justbrowsing

2
@justbrowsing - screenโทรดีใน ฉันสงสัยเกี่ยวกับ verbose แต่ฉันเดาว่ามันสายเกินไปที่จะเริ่มต้นใหม่tarในขณะนี้ และiotopได้รับยูทิลิตี้ที่ชื่นชอบสำหรับไม่กี่วันที่ผ่านมา :)
ทิม

คำตอบ:


6

เคยได้ยินเรื่องการแยกงานใหญ่เป็นงานเล็ก ๆ ไหม?

/ home / data / repo มี 1M dirs ซึ่งแต่ละไฟล์มี 11 dirs และ 10 ไฟล์ มันรวม 2TB

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/

(...)

เวลาพักดื่มกาแฟ


1
ประโยชน์ที่ฉันเน้นอย่างชัดเจนคือคุณติดตามความคืบหน้าในชิ้นส่วนเล็ก ๆด้วยตนเองเพื่อให้การทำงานต่อไปใช้เวลาน้อยลงหากบางส่วนถูกยกเลิก (เพราะคุณรู้ว่าขั้นตอนใดเสร็จสมบูรณ์)
ЯрославРахматуллин

mvนี้นั้นเป็นสิ่งที่ฉันสิ้นสุดที่ทำในท้ายที่สุดแล้วยกเว้น น่าเสียดายที่ไม่มีการประชุมเครื่องมือmvและrsyncอยู่ครึ่งทาง
ทิม

4

นี่คือสิ่งที่เกิดขึ้น:

  • ตอนแรก rsync จะสร้างรายการของไฟล์
  • การสร้างรายการนี้ช้ามากเนื่องจากการเรียงลำดับเริ่มต้นของรายการไฟล์
  • สิ่งนี้สามารถหลีกเลี่ยงได้โดยใช้ ls -f -1 และรวมกับ xargs สำหรับการสร้างชุดของไฟล์ที่ rsync จะใช้หรือเปลี่ยนเส้นทางเอาต์พุตไปยังไฟล์ที่มีรายการไฟล์
  • ผ่านรายการนี้ไปยัง rsync แทนที่จะเป็นโฟลเดอร์จะทำให้ rsync เริ่มทำงานได้ทันที
  • เคล็ดลับของ ls -f -1 ผ่านโฟลเดอร์ที่มีไฟล์นับล้านไฟล์ได้อธิบายไว้อย่างสมบูรณ์ในบทความนี้: http://unixetc.co.uk/2012/05/20/large-directory-causes-ls-to-hang/

1
คุณสามารถยกตัวอย่างวิธีใช้ ls กับ rsync ได้หรือไม่? ฉันมีสถานการณ์ที่คล้ายกัน แต่ไม่เหมือนกัน บนเครื่อง AI ทำงาน rsyncd และโครงสร้างไดเรกทอรีขนาดใหญ่ที่ฉันต้องการถ่ายโอนไปยังเครื่อง B (จริง ๆ แล้ว 90% ของไดเรกทอรีอยู่ที่ B) ปัญหาคือฉันต้องทำสิ่งนี้โดยใช้การเชื่อมต่อมือถือที่ไม่เสถียรที่ลดลงบ่อยครั้ง การใช้เวลาหนึ่งชั่วโมงในการสร้างรายชื่อไฟล์ทุกครั้งที่ฉันรีสตาร์ทนั้นค่อนข้างไม่มีประสิทธิภาพ นอกจากนี้ B อยู่เบื้องหลัง NAT ที่ฉันไม่ควบคุมดังนั้นจึงยากที่จะเชื่อมต่อ A -> B ในขณะที่ B -> A นั้นง่าย
db

เห็นด้วยกับ @db หากสามารถยกตัวอย่างได้นั่นจะทำให้คำตอบนี้มีประโยชน์มากขึ้น
redfox05

1

แม้ว่า rsync จะช้า (ทำไมช้า? อาจจะ -z จะช่วยได้) ดูเหมือนว่าคุณจะได้รับมันมากมายดังนั้นคุณสามารถลองต่อไปได้:

หากคุณใช้ --remove-source-files คุณสามารถติดตามได้โดยลบไดเรกทอรีว่าง ๆ - ลบซอร์สไฟล์จะลบไฟล์ทั้งหมด แต่จะออกจากไดเรคทอรี่นั้น

เพียงให้แน่ใจว่าคุณไม่ได้ใช้ - ลบไฟล์ต้นฉบับด้วย - ลบเพื่อทำการส่งหลายครั้ง

นอกจากนี้สำหรับความเร็วที่เพิ่มขึ้นคุณสามารถใช้ - แทนที่

หากคุณถูกไล่ออกเนื่องจากคุณพยายามทำสิ่งนี้จากระยะไกลบนเซิร์ฟเวอร์ให้ดำเนินการต่อในเซสชัน 'หน้าจอ' อย่างน้อยคุณก็ปล่อยให้มันวิ่งได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.