มีอะไรเร็วไปกว่า grep? [ปิด]


4

ฉันกำลังมองหาเครื่องมือที่จะเร็วกว่า grep บางที grep แบบมัลติเธรดหรือสิ่งที่คล้ายกัน ... ฉันได้ดูที่ indexers หลายอัน แต่ฉันไม่ได้ขายที่ฉันต้องการ index ...

ฉันมีไฟล์ข้อความประมาณ 100 ล้านไฟล์ซึ่งฉันต้อง grep สำหรับการจับคู่สตริงที่แน่นอนเมื่อค้นหาการจับคู่สตริงฉันต้องการชื่อไฟล์ที่พบการจับคู่

ie: grep -r 'exact match' > filepaths.log

มันมีข้อมูลประมาณ 4TB และฉันเริ่มการค้นหาครั้งแรกเมื่อ 6 วันก่อนและ grep ยังคงทำงานอยู่ ฉันมีการค้นหาอีกหลายสิบครั้งและฉันไม่สามารถรอ 2 เดือนเพื่อเรียกชื่อไฟล์เหล่านี้ทั้งหมด =]

ฉันได้ตรวจสอบสิ่งต่อไปนี้แล้ว แต่ฉันไม่คิดว่าฉันต้องการระฆังและนกหวีดทั้งหมดที่ตัวสร้างดัชนีเหล่านี้มาพร้อมกับฉันแค่ต้องการชื่อไฟล์ที่มีการแข่งขันเกิดขึ้น ...

  • dtSearch
  • เทอร์เรี
  • Lucene
  • Xapian
  • หดตัว
  • บุคคลลึกลับ

และหลังจากใช้เวลาอ่านเกี่ยวกับเครื่องยนต์เหล่านั้นหลายชั่วโมงหัวของฉันก็หมุนและฉันก็หวังว่าฉันจะมี grep ฮ่า ๆ ๆ ที่มีหลายเธรดความคิดใด ๆ และ / หรือคำแนะนำต่าง ๆ ได้รับการชื่นชมอย่างมาก!

PS: ฉันใช้ CentOS 6.5

แก้ไข: การค้นหา grep แบบมัลติเธรดส่งคืนหลายรายการคำถามของฉันคือ grep แบบมัลติเธรดเป็นตัวเลือกที่ดีที่สุดสำหรับสิ่งที่ฉันกำลังทำอยู่หรือไม่?

แก้ไข 2: หลังจาก tweaking นี่คือสิ่งที่ฉันได้มาด้วยและมันจะเร็วกว่า grep ปกติฉันยังคงหวังว่ามันจะเร็วกว่าแม้ว่า ... ฉันกำลังดูดิสก์ของฉันรอ io และยังไม่ได้สร้างขึ้น ฉันอาจทำการปรับแต่งเพิ่มเติมและ def ยังสนใจคำแนะนำใด ๆ =]

find . -type f -print0 | xargs -0 -n10 -P4 grep -m 1 -H -l 'search string'

ดังนั้นคุณวางแผนที่จะค้นหามากกว่าหนึ่งสตริงใช่ไหม การมัลติเธรดจะไม่ช่วยเพราะคุณถูก จำกัด ด้วยปริมาณงานดิสก์และ (ที่สำคัญกว่า) ค้นหาประสิทธิภาพ
Daniel B

ยาดิสก์มี def คอขวดที่นี่
เจฟฟรีย์แอลโรเบิร์ต

"100 ล้านไฟล์ข้อความ" ... จริงเหรอ? และวิธีการที่จะใช้จริงทั้งหมดขึ้นอยู่กับว่าสิ่งนี้เป็นเพียงครั้งเดียวหรือข้อมูลที่จำเป็นต้องมีการจัดทำดัชนีสำหรับการใช้ในอนาคต
Tyson

ใช่ ... จริง ๆ lol =] มากกว่าหรือน้อยกว่าหนึ่งครั้งสำหรับการค้นหาทั้งหมด 2 โหล
Jeffrey L. Roberts

คำตอบ:


10

grepI / O ถูกผูกไว้หมายถึงความเร็วถูกครอบงำโดยความเร็วในการอ่านไฟล์ที่กำลังค้นหา การค้นหาหลายรายการพร้อมกันสามารถแข่งขันกันเพื่อหาดิสก์ I / O ดังนั้นคุณอาจไม่เห็นความเร็วมากนัก

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

หากคุณกำลังมองหาสตริงคงที่มากกว่าการแสดงออกปกติแล้วคุณอาจลองใช้มากกว่าfgrep grepFgrep เป็นตัวแปรของ grep ที่ค้นหาสตริงคงที่และการค้นหาสตริงคงที่เร็วกว่าการค้นหานิพจน์ปกติ คุณอาจหรืออาจไม่เห็นการปรับปรุงใด ๆ จากสิ่งนี้เพราะ grep รุ่นที่ทันสมัยน่าจะฉลาดพอที่จะปรับการค้นหาสตริงคง

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

find /path/to/files -type f -print | split -l 10000000 list.
for file in list.*; do
    grep -f ${file} -l 'some text' > ${file}.out &
done
wait
cat $*.out > filepaths.log
rm list.*

ใช้findเพื่อค้นหาไฟล์แยกรายชื่อไฟล์เป็นกลุ่มสิบล้านและเรียกใช้ grep แบบขนานสำหรับแต่ละกลุ่ม เอาท์พุทของ greps ทั้งหมดมารวมกันในตอนท้าย สิ่งนี้ควรทำงานกับไฟล์ที่มีชื่อทั่วไป แต่มันจะล้มเหลวสำหรับไฟล์ที่มีบรรทัดใหม่ในชื่อของพวกเขา

อีกวิธีใช้ xargs ก่อนอื่นคุณต้องเขียนเชลล์สคริปต์แบบง่าย ๆ ที่รัน grep ในพื้นหลัง:

#!/bin/bash
grep -l 'search text' "$@" >> grep.$$.out &

สิ่งนี้จะรัน grep ในรายการไฟล์ที่ระบุเป็นอาร์กิวเมนต์ไปยังสคริปต์เขียนผลลัพธ์ไปยังไฟล์ที่ตั้งชื่อตาม PID ของกระบวนการ กระบวนการ grep ทำงานในพื้นหลัง

จากนั้นคุณจะเรียกใช้สคริปต์เช่นนี้:

find /path/to/files -type f -print0 | xargs -0 -r /my/grep/script
[ wait for those to finish ]
cat grep.*.out > filepaths.log
rm grep.*.out

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


ถ้าคุณไม่จำเป็นต้อง regex หนึ่งประโยชน์ของfgrepคือคุณไม่ต้องกังวลเกี่ยวกับการหลบหนีตัวละครลิขสิทธิ์เช่นแทนfgrep '..' grep '\.\.'
thdoan

Grep ไม่ได้เป็น I / O เสมอไป ฉันกำลังใช้ grep ที่เชื่อมโยงกับ CPU อยู่ในขณะนี้
iAdjunct

0

ดูเหมือนว่าคุณต้องการสคริปต์หรือโปรแกรมขนาดเล็กที่จะทำงานหลาย ๆ อินสแตนซ์ (เช่น 8 x grep สามารถทำงานแบบขนานบน i7 ที่ทันสมัยพร้อม 4 คอร์ / 8threads) ของ grep และเชื่อมหรือรวมเอาท์พุทมากกว่าที่คุณต้องการ grep ที่เร็วขึ้น .

วิธีทำสคริปต์ดังกล่าวเป็นคำถามอื่นทั้งหมด แต่นั่นคือวิธีที่ฉันจะโจมตีปัญหาของคุณ


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