วิธีการจัดเรียงไฟล์ขนาดใหญ่?


35

ฉันมีพีซีที่ใช้ Intel (R) Pentium (R) CPU G640 @ 2.80 GHz และ RAM 8 GB ฉันใช้ Scientific Linux 6.5 บนระบบไฟล์ EXT3

ในการตั้งค่านี้วิธีที่เร็วที่สุดที่ฉันสามารถทำได้sort -uบนไฟล์ 200 กิกะไบต์คืออะไร?

ฉันควรแบ่งไฟล์ออกเป็นไฟล์ที่เล็กกว่า (เล็กกว่า 8 GB) sort -uรวมเข้าด้วยกันแล้วแยกเป็นขนาดอื่นsort -uอีกครั้งหรือไม่ หรือมีสคริปต์การเรียงลำดับโปรแกรมที่สามารถจัดการไฟล์ขนาดใหญ่นี้ด้วย RAM ที่มีจำนวน จำกัด ของฉันได้หรือไม่


6
โปรดแก้ไขคำถามของคุณและอธิบายสิ่งที่เกิดขึ้นเมื่อคุณลองคำสั่งที่คุณโพสต์ คุณใช้พื้นที่ดิสก์หมดหรือไม่ /tmpคำสั่งควรจะทำงานตราบเท่าที่คุณมีพื้นที่ว่างเพียงพอบน
terdon


1
คำตอบที่ได้รับการแต่งตั้งโดยทั่วไปว่าสิ่งที่ @terdon จะพูด แต่ยังตรวจสอบหนึ่งนี้ - stackoverflow.com/a/13025731/2801913 คุณจะต้องใช้ GNU parallelสำหรับสิ่งนี้ฉันคิดว่าแทนที่จะใช้มากกว่าparallelนั้นที่ติดตั้งตามค่าเริ่มต้นในบางระบบ
แกรม

1
คุณสามารถอัปโหลดไฟล์ไปที่ Amazon S3 จากนั้นหมุน Elastic Map ย่อขนาดงานที่มีกี่ร้อยโหนดเพื่อจัดเรียง!
Alan Shutko

2
sort(1)สามารถเรียกใช้พื้นที่ว่างบน/tmp; ถ้าเป็นเช่นนั้นคุณสามารถกำหนดพื้นที่อื่นสำหรับไฟล์ชั่วคราวด้วยตัวแปรสภาพแวดล้อมTMPDIRหรือตั้งค่าสถานะ-T=<tmpdir>
vonbrand

คำตอบ:


45

GNU sort(ซึ่งเป็นค่าเริ่มต้นในระบบ Linux ส่วนใหญ่) มี--parallelตัวเลือก จากhttp://www.gnu.org/software/coreutils/manual/html_node/sort-invocation.html :

'--parallel = n'

ตั้งค่าจำนวนการเรียงลำดับการทำงานแบบขนานเป็น n โดยค่าเริ่มต้น n ถูกกำหนดเป็นจำนวนของตัวประมวลผลที่มีอยู่ แต่ จำกัด ไว้ที่ 8 เนื่องจากมีการลดลงของประสิทธิภาพที่เพิ่มขึ้นหลังจากนั้น โปรดทราบว่าการใช้เธรด n เพิ่มการใช้หน่วยความจำด้วยปัจจัยการบันทึก n ดูที่การเรียก nproc ด้วย

เนื่องจาก cpu ของคุณมี 2 คอร์คุณสามารถทำได้:

sort --parallel=2 -uo list-sorted.txt list.txt

มันจะดีกว่าที่จะระบุจำนวนที่แท้จริงของแกนเนื่องจากมีอาจจะเป็นมากขึ้นเนื่องจากการประมวลผลที่มีHyper-Threading

คุณสามารถทดสอบด้วยniceเพื่อให้มีผลกับลำดับความสำคัญของตัวประมวลผลและioniceมีผลต่อการตั้งเวลา I / O คุณสามารถเพิ่มลำดับความสำคัญเหนือกระบวนการอื่น ๆ เช่นนี้ฉันไม่คิดว่าสิ่งนี้จะช่วยให้คุณประหยัดได้มากเนื่องจากพวกเขามักจะดีกว่าเพื่อให้แน่ใจว่ากระบวนการพื้นหลังไม่ได้ใช้ทรัพยากรมากเกินไป คุณสามารถรวมเข้ากับสิ่งที่ชอบได้

nice -n -20 ionice -c2 -n7 sort --parallel=2 -uo list-sorted.txt list.txt

โปรดทราบว่าเมื่อGillesแสดงความคิดเห็นการใช้คำสั่งการจัดเรียง GNU เดียวจะเร็วกว่าวิธีอื่นใดในการแยกการเรียงลำดับเนื่องจากอัลกอริทึมได้รับการปรับให้เหมาะสมเพื่อจัดการกับไฟล์ขนาดใหญ่แล้ว สิ่งอื่นใดที่จะทำให้ช้าลง


10
และคุณควรทราบว่าการโทรsortโดยตรงนั้นดีกว่าสิ่งอื่นใดที่คุณสามารถนำมาต่อได้ การจัดเรียง GNU ได้รับการออกแบบมาเพื่อรองรับไฟล์ที่มีขนาดใหญ่กว่า RAM มาก
Gilles 'ดังนั้นหยุดความชั่วร้าย'

ตัวเลือก - เรียงลำดับแบบขนานไม่ทำงานบนเซิร์ฟเวอร์ RH6.5 ของฉัน Sort - รุ่นที่คิดว่ามันมาจาก coreutils 8.4 ฉันต้องใช้เวอร์ชันใดกับเวอร์ชันขนาน
markus_b

3
ดูเพิ่มเติมที่superuser.com/questions/938558/sort-parallel-isnt-parallelizing - คุณอาจต้องระบุบางอย่างเช่น -S512M หากคุณสังเกตว่ามันไม่ได้ขนานกันจริง ๆ
unhammer

46

การใช้sortคำสั่งอาจเป็นตัวเลือกที่เร็วที่สุด

แต่คุณอาจต้องการแก้ไขสถานที่ให้เป็น C

sort -uไม่ได้รายงานบรรทัดที่ไม่ซ้ำกัน แต่หนึ่งในชุดของแต่ละบรรทัดที่เรียงลำดับเดียวกัน ในโลแคล C บรรทัดที่ต่างกัน 2 บรรทัดนั้นไม่จำเป็นต้องเรียงลำดับเหมือนกัน แต่นั่นไม่ใช่ในกรณีส่วนใหญ่ตามโลแคล UTF-8 บนระบบ GNU

นอกจากนี้การใช้โลแคล C หลีกเลี่ยงค่าใช้จ่ายในการแยก UTF-8 และประมวลผลคำสั่งการเรียงลำดับที่ซับซ้อนดังนั้นจะช่วยปรับปรุงประสิทธิภาพได้อย่างมาก

ดังนั้น:

LC_ALL=C sort -u file

คุณสามารถปรับปรุงประสิทธิภาพโดยใช้ไดรฟ์ที่เร็วขึ้น (หรือไดรฟ์ที่แตกต่างจากไดรฟ์ที่มีอินพุตและ / หรือไฟล์เอาท์พุต) สำหรับไฟล์ชั่วคราว (โดยใช้-Tหรือ$TMPDIRตัวแปรสภาพแวดล้อม) หรือโดยเล่นซอกับ-Sตัวเลือกที่รองรับโดยsortการใช้งานบางอย่าง) .

สำหรับอินพุตบางประเภทหรือสำหรับที่เก็บข้อมูลช้าการใช้--compress-programตัวเลือกของ GNU sort(ตัวอย่างเช่นlzop) อาจปรับปรุงประสิทธิภาพนอกเหนือจากการใช้พื้นที่เก็บข้อมูล


ตอนนี้เพียงแค่ทราบสำหรับการคัดค้านเหล่านั้น (ถูกต้องในระดับหนึ่ง) ว่ามันจะไม่เป็นลำดับที่ถูกต้อง :

ฉันยอมรับว่าในฐานะมนุษย์ฉันต้องการเห็นStéphaneจัดเรียงระหว่างStefanและStephanieแต่:

  • คอมพิวเตอร์ต้องการStéphaneในการเรียงลำดับหลังจากที่ตั้งแต่é(อย่างน้อยเมื่อแสดงเป็น U + 00E9) เป็นอักขระหรือไบต์ของ UTF-8 ประเภทการเข้ารหัสหลัง (ในแง่ของจุดโค้ดหรือค่าไบต์) นั่นเป็นลำดับการเรียงที่ง่ายมากที่จะใช้และเป็นคำสั่งทั้งหมดที่เข้มงวดและไม่แปลกใจ
  • ลำดับการเรียงของสถานที่ของคุณอาจไม่เป็นที่น่าพอใจในหลาย ๆ กรณีไม่ว่าจะเป็นกับมนุษย์ก็ตาม ตัวอย่างเช่นในระบบของฉันที่มีค่าเริ่มต้น en_GB.utf8 ตำแหน่งที่ตั้ง:

    • StéphaneและStéphane (อันที่มี U + 00E9, อีกอันที่มี eU + 0301) ไม่ได้เรียงแบบเดียวกัน:

      $ printf '%b\n' 'Ste\u0301phane' 'St\u00e9phane' | sort -u
      Stéphane
      Stéphane
      
    • แต่③, ①, ②เรียงลำดับเดียวกันทั้งหมด (เห็นได้ชัดว่ามีข้อบกพร่องในคำจำกัดความของสถานที่เหล่านั้น):

      $ printf '%s\n' ③ ① ② | sort -u
      ③
      

      ที่นี่มันคือ③ แต่มันอาจเป็น①หรือ②ได้เช่นกัน

ดังนั้น IMO โอกาสที่คุณต้องการsort -uด้วย LC_ALL = C เสมอหากคุณต้องการเส้นที่ไม่ซ้ำกัน และถ้าคุณต้องการให้เรียงลำดับรายการผลลัพธ์ในการเรียงลำดับของผู้ใช้ให้ไพพ์ไปที่sortอีกครั้ง:

LC_ALL=C sort -u | sort

LC_ALL=C sort | LC_ALL=C uniq -c | sort -k2

8
+1 สำหรับการตั้งค่าสถานที่: มันสามารถมีผลอย่างมากต่อประสิทธิภาพการทำงาน
Adrian Pronk

1
ใช่. ไฟล์การเรียงลำดับที่มี 250000 บรรทัด LC_ALL จะเร่งความเร็วได้ 8 เท่า
Jan Vlcinsky

-1

นี่คือสคริปต์สคริปต์ทุบตีที่พร้อมใช้งานสำหรับการเรียงลำดับข้อมูลมาตราส่วน TB บนเครื่องปกติที่มีหน่วยความจำสอง GB: http://sgolconda.blogspot.com/2015/11/sort-very-large-dataset.html ตรวจสอบจำนวน แกนเครื่องของคุณเป็นและใช้แกนทั้งหมด สามารถเรียงลำดับตัวเลขหรือไฟล์สตริง สามารถใช้เพื่อค้นหาบันทึกที่ไม่ซ้ำในข้อมูลมาตราส่วนของวัณโรค


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