จะเริ่ม grep แบบหลายเธรดในเทอร์มินัลได้อย่างไร?


38

ฉันมีโฟลเดอร์ที่มี 250 ไฟล์ไฟล์ละ 2 GB ฉันต้องการค้นหาสตริง / รูปแบบในไฟล์เหล่านั้นและส่งออกผลลัพธ์ในoutputไฟล์ ฉันรู้ว่าฉันสามารถเรียกใช้คำสั่งต่อไปนี้ แต่ช้าเกินไป !!

grep mypattern * > output

ฉันต้องการเพิ่มความเร็ว การเป็นโปรแกรมเมอร์ใน Java ฉันรู้ว่าสามารถใช้มัลติเธรดเพื่อเร่งกระบวนการได้ ฉันติดอยู่กับวิธีการเริ่มต้นgrepใน "โหมดมัลติเธรด" และเขียนผลลัพธ์ลงในoutputไฟล์เดียว


ดูเพิ่มเติมที่unix.stackexchange.com/q/131535
Stéphane Chazelas


1
การค้นหาชุดไฟล์ขนาดใหญ่เป็นตัวอย่างคลาสสิกของปัญหาที่ถูกผูกไว้กับ IO ดังนั้นการใช้หลายเธรดจะไม่ช่วย
Jonathan Hartley

คำตอบ:


31

มีสองวิธีแก้ปัญหาสำหรับเรื่องนี้ โดยทั่วไปใช้หรือxargsparallel

xargs วิธีการ:

คุณสามารถใช้xargsกับfindดังนี้:

find . -type f -print0  | xargs -0 -P number_of_processes grep mypattern > output

คุณจะแทนที่number_of_processesด้วยจำนวนกระบวนการสูงสุดที่คุณต้องการเปิดใช้ อย่างไรก็ตามสิ่งนี้ไม่รับประกันว่าจะให้ประสิทธิภาพที่สำคัญในกรณีที่ประสิทธิภาพของคุณคือ I / O จำกัด ในกรณีนี้คุณอาจลองเริ่มกระบวนการเพิ่มเติมเพื่อชดเชยเวลาที่เสียไปที่รอ I / Os

นอกจากนี้เมื่อรวมการค้นหาคุณสามารถระบุตัวเลือกขั้นสูงเพิ่มเติมแทนรูปแบบไฟล์เช่นเวลาการแก้ไข ฯลฯ ...

ปัญหาที่เป็นไปได้อย่างหนึ่งในแนวทางนี้ตามที่อธิบายโดยความคิดเห็นของStéphaneหากมีไฟล์ไม่กี่ไฟล์xargsอาจไม่เริ่มกระบวนการหลายอย่างเพียงพอสำหรับพวกเขา ทางออกหนึ่งคือการใช้-nตัวเลือกสำหรับxargsระบุจำนวนอาร์กิวเมนต์ที่ควรใช้จากไพพ์ในแต่ละครั้ง การตั้งค่า-n1จะบังคับxargsให้เริ่มกระบวนการใหม่สำหรับแต่ละไฟล์ นี่อาจเป็นพฤติกรรมที่ต้องการหากไฟล์มีขนาดใหญ่มาก (เช่นในกรณีของคำถามนี้) และมีจำนวนไฟล์ค่อนข้างน้อย อย่างไรก็ตามหากไฟล์มีขนาดเล็กค่าใช้จ่ายในการเริ่มต้นกระบวนการใหม่อาจบ่อนทำลายความได้เปรียบของการขนานซึ่งในกรณีนี้-nค่าที่มากกว่าจะดีกว่า ดังนั้น-nตัวเลือกอาจปรับละเอียดตามขนาดและหมายเลขไฟล์

วิธีการแบบขนาน:

อีกวิธีในการทำคือใช้เครื่องมือ Ole Tange GNU Parallel parallel(มีให้ที่นี่ ) สิ่งนี้นำเสนอการควบคุมเกรนละเอียดยิ่งขึ้นสำหรับการขนานและยังสามารถกระจายไปยังหลาย ๆ โฮสต์ได้ (จะเป็นประโยชน์ถ้าไดเรกทอรีของคุณถูกแชร์เช่นกัน) ไวยากรณ์ที่ง่ายที่สุดโดยใช้ขนานจะเป็น:

find . -type f | parallel -j+1 grep mypattern

เมื่อตัวเลือก-j+1สั่งให้ขนานเพื่อเริ่มต้นกระบวนการหนึ่งเกินจำนวนแกนบนเครื่องของคุณ (สิ่งนี้มีประโยชน์สำหรับงาน I / O ที่ จำกัด คุณอาจลองเพิ่มจำนวนมากขึ้น)

Parallel ยังมีข้อได้เปรียบเหนือxargsการรักษาลำดับของเอาต์พุตจากแต่ละกระบวนการและสร้างเอาต์พุตที่ต่อเนื่องกัน ตัวอย่างเช่นxargsหากกระบวนการ 1 สร้างบรรทัดพูดp1L1กระบวนการที่ 2 สร้างบรรทัดp2L1กระบวนการ 1 สร้างบรรทัดอื่นp1L2ผลลัพธ์จะเป็น:

p1L1
p2L1
p1L2

ในขณะparallelที่ผลลัพธ์ควรเป็น:

p1L1
p1L2
p2L1

ซึ่งมักจะมีประโยชน์มากกว่าxargsเอาท์พุท


1
คุณอาจต้องการที่จะใช้ร่วมกับ-n -Pมิฉะนั้นxargsอาจไม่สิ้นสุดการวางไข่หลายกระบวนการหากมีสองสามไฟล์
Stéphane Chazelas

1
ดี -n1 จะเริ่มหนึ่งgrepไฟล์ต่อหนึ่งไฟล์ เว้นแต่ไฟล์จะมีขนาดใหญ่มากและมีไฟล์เพียงไม่กี่ไฟล์คุณอาจต้องการเพิ่มบิตให้มากขึ้นเนื่องจากคุณจะใช้เวลาในการเริ่มต้นและหยุดกระบวนการ grep แทนที่จะค้นหาในไฟล์
Stéphane Chazelas

9

มีอย่างน้อยสองวิธีในการเร่งความเร็ว CPU grep-wise:

  • หากคุณกำลังค้นหาสตริงคงที่แทนที่จะเป็นนิพจน์ทั่วไปให้ระบุ-Fค่าสถานะ

  • หากรูปแบบของคุณเป็น ASCII เท่านั้นให้ใช้สถานที่เกิดเหตุ 8 บิตแทน UTF-8 LC_ALL=C grep ...เช่น

สิ่งเหล่านี้จะไม่ช่วยได้หากฮาร์ดไดรฟ์ของคุณเป็นคอขวด ในกรณีที่อาจขนานกันจะไม่ช่วยอย่างใดอย่างหนึ่ง


1
เพิ่งเห็นในman grep"การเรียกใช้โดยตรงเช่น egrep หรือ fgrep นั้นเลิกใช้ แต่มีไว้เพื่ออนุญาตให้แอปพลิเคชันทางประวัติศาสตร์ที่อาศัยการรันแบบไม่มีการแก้ไข" ไม่แน่ใจว่าเรื่องนี้จริง ๆ แต่เป็นเช่นเดียวกับgrep -F
iyrin

1
นอกจากนี้เมื่อคุณพูดว่า "แทนที่จะเป็นรูปแบบ" คุณหมายถึงการแสดงออกปกติ?
iyrin

การค้นหา "ASCII-only" ใช้ CPU น้อยลงอย่างมาก แต่คุณต้องอ่านคำเตือนที่กล่าวไว้ในความคิดเห็นที่stackoverflow.com/a/11777835/198219
famzah

3

หากปัญหาไม่ใช่ I / O ที่ถูกผูกไว้คุณสามารถใช้เครื่องมือที่ปรับให้เหมาะสำหรับการประมวลผลแบบมัลติคอร์

คุณอาจต้องการดูที่ร่อน ( http://sift-tool.org , ข้อจำกัดความรับผิดชอบ: ฉันเป็นผู้เขียนเครื่องมือนี้) หรือผู้ค้นหาเงิน ( https://github.com/ggreer/the_silver_searcher )

ตัวค้นหาเงินมีขีด จำกัด ขนาดไฟล์ที่ 2GB หากคุณใช้รูปแบบ regex และไม่ใช่การค้นหาสตริง


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