1 คะแนน โดย GN⁺ 2024-05-28 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • Tantivy เป็นไลบรารีเอนจินค้นหาแบบฟูลเท็กซ์ความเร็วสูงที่เขียนด้วย Rust และมีลักษณะใกล้เคียงกับ crate สำหรับใช้สร้างเอนจินค้นหา มากกว่าจะเป็นเซิร์ฟเวอร์ค้นหาที่เสร็จสมบูรณ์พร้อมใช้งาน
  • การออกแบบได้รับแรงบันดาลใจอย่างมากจาก Apache Lucene และหากกำลังมองหาเซิร์ฟเวอร์ทางเลือกแทน Elasticsearch หรือ Apache Solr ก็แนะนำให้ดูเอนจินค้นหาแบบกระจายศูนย์ Quickwit ที่สร้างอยู่บน Tantivy
  • ความสามารถประกอบด้วยการค้นหาแบบฟูลเท็กซ์, การให้คะแนน BM25, คำค้นภาษาธรรมชาติ, การค้นหาวลี, incremental indexing, multithreaded indexing, mmap directory, การบีบอัดจำนวนเต็มด้วย SIMD, faceted search, ฟิลด์ JSON, Aggregation Collector เป็นต้น
  • ทำงานบน stable Rust รองรับ Linux, macOS, Windows และระบุว่าใช้เวลาเริ่มต้น ต่ำกว่า 10ms จึงเหมาะกับเครื่องมือบรรทัดคำสั่ง
  • การค้นหาแบบกระจายศูนย์อยู่นอกขอบเขตของ Tantivy และการแก้ไขเอกสารต้องลบเอกสารเดิมแล้วทำดัชนีใหม่ โดยเอกสารใหม่จะค้นหาได้หลัง commit จากนั้นต้องรีโหลด IndexReader และรับ Searcher ตัวใหม่

ตำแหน่งและแนวทางการออกแบบของ Tantivy

  • Tantivy เป็นไลบรารีเอนจินค้นหาแบบฟูลเท็กซ์ความเร็วสูงที่เขียนด้วย Rust
  • ไม่ใช่เซิร์ฟเวอร์เอนจินค้นหาที่รันได้ทันทีแบบ Elasticsearch หรือ Apache Solr แต่เป็น crate ที่สามารถนำไปใช้สร้างเอนจินค้นหาลักษณะนั้นได้
  • ในแง่การออกแบบ มันใกล้เคียงกับ Apache Lucene มากกว่า และได้รับแรงบันดาลใจอย่างมากจากแนวทางของ Lucene
  • หากกำลังมองหาทางเลือกแทน Elasticsearch หรือ Apache Solr ก็แนะนำให้ดูเอนจินค้นหาแบบกระจายศูนย์ Quickwit ที่สร้างอยู่บน Tantivy

ประสิทธิภาพและเบนช์มาร์ก

  • Tantivy มี benchmark ที่แยกประสิทธิภาพตามประเภทของคำค้นและคอลเลกชัน
  • ผลเบนช์มาร์กอาจแตกต่างกันตามลักษณะของคำค้นและภาระงาน
  • ดูรายละเอียดของเบนช์มาร์กได้ที่รีโพซิทอรี search-benchmark-game
  • ตาม FAQ ในเบนช์มาร์กด้าน search latency นั้น Tantivy เร็วกว่า Lucene โดยเฉลี่ยประมาณ 2 เท่า

ความสามารถด้านการค้นหาและการทำดัชนี

  • ความสามารถด้านการค้นหา

    • การค้นหาแบบฟูลเท็กซ์
    • การให้คะแนนแบบ BM25 เช่นเดียวกับ Lucene
    • รองรับคำค้นภาษาธรรมชาติ: (michael AND jackson) OR "king of pop"
    • รองรับการค้นหาวลี: "michael jackson"
    • range query
    • faceted search
    • JSON Field
    • Aggregation Collector: histogram, range buckets, average, stats metrics
  • ความสามารถด้านการทำดัชนี

    • รองรับ incremental indexing
    • รองรับ multithreaded indexing
    • ระบุว่าการทำดัชนี Wikipedia ภาษาอังกฤษใช้เวลาไม่ถึง 3 นาทีบนเดสก์ท็อป
    • ตั้งค่าการทำดัชนีได้ผ่าน term frequency แบบเลือกได้และ position indexing
    • รองรับ LogMergePolicy with deletes
    • มี Searcher Warmer API
  • การจัดเก็บและฟิลด์

    • รองรับ mmap directory
    • รองรับ fast fields แบบ single-valued และ multivalued สำหรับ u64, i64, f64
    • รองรับ fast fields ของ &[u8]
    • รองรับฟิลด์ text, i64, u64, f64, dates, ip, bool, hierarchical facet
    • การบีบอัด document store รองรับ LZ4, Zstd, None

โทเค็นไนเซอร์และการรองรับภาษา

  • โทเค็นไนเซอร์สามารถตั้งค่าได้ และรองรับ stemming สำหรับ 17 ภาษาในตระกูลละติน
  • ยังรองรับโทเค็นไนเซอร์จาก third party ด้วย
  • เมื่อต้องการพัฒนาโทเค็นไนเซอร์สำหรับ Tantivy จำเป็นต้องพึ่งพา crate tantivy-tokenizer-api

สภาพแวดล้อมการทำงานและวิธีเริ่มต้น

  • Tantivy ทำงานบน stable Rust
  • ระบบปฏิบัติการที่รองรับคือ Linux, macOS, Windows
  • ใช้เวลาเริ่มต้น ต่ำกว่า 10ms จึงเหมาะกับเครื่องมือบรรทัดคำสั่ง
  • เอกสารเริ่มต้น
  • การ build และทดสอบบนเครื่องทำได้ด้วยคำสั่งต่อไปนี้
git clone https://github.com/quickwit-oss/tantivy.git
cd tantivy
cargo test

ความสามารถที่อยู่นอกขอบเขตและโมเดลการเปลี่ยนแปลงข้อมูล

  • การค้นหาแบบกระจายศูนย์ อยู่นอกขอบเขตของ Tantivy
  • หากต้องการการค้นหาแบบกระจายศูนย์ แนะนำให้ดู Quickwit
  • ข้อมูลของ Tantivy เป็นแบบ immutable
  • หากต้องการแก้ไขเอกสาร ต้องลบเอกสารเดิมแล้วทำดัชนีใหม่
  • เอกสารที่กำลังทำดัชนีจะค้นหาได้หลังจากมีการเรียก commit ใน IndexWriter
  • IndexReader เดิมต้องถูกรีโหลดเพื่อให้สะท้อนการเปลี่ยนแปลง
  • การเปลี่ยนแปลงจะมองเห็นได้เฉพาะใน Searcher ตัวใหม่ที่ดึงมาเท่านั้น

ไบน์ดิงและกรณีการใช้งาน

  • ไบน์ดิงที่ใช้ได้จากภาษาอื่น
    • Python: tantivy-py
    • Ruby: tantiny
    • ยังหาไบน์ดิงอื่นได้บน GitHub แต่การดูแลรักษาอาจไม่ต่อเนื่องนัก
  • ตัวอย่างการใช้งาน Tantivy
    • seshat: ฐานข้อมูล/ตัวทำดัชนีข้อความของ Matrix
    • tantiny: การค้นหาแบบฟูลเท็กซ์ขนาดเล็กสำหรับ Ruby
    • lnx: เอนจินค้นหาที่ปรับตัวได้ รองรับการพิมพ์ผิด และมี REST API
    • Bichon: ตัวเก็บถาวรอีเมล Rust ประสิทธิภาพสูงขนาดเบาพร้อม WebUI
  • บริษัทที่ระบุว่าใช้งาน Tantivy ได้แก่ Etsy, ParadeDB, Nuclia, Humanfirst.ai, Element.io

1 ความคิดเห็น

 
GN⁺ 2024-05-28
ความคิดเห็นจาก Hacker News
  • คนที่สร้างไลบรารีนี้สุดยอดจริง ๆ ปีที่แล้วตอนผมแทนที่โค้ดเบส Python2 AppEngine เก่า ๆ ที่ปล่อยทิ้งไว้เป็นเวลานาน ผมก็สร้าง https://progscrape.com [1] ขึ้นมาใหม่บนสิ่งนี้ เป็นไลบรารีที่ยอดเยี่ยมและเร็วมาก
    มันสามารถทำดัชนีสตอรีครบ 1 ล้านรายการบน Raspberry Pi ได้ภายในไม่กี่วินาที
    ผมรันบริการค้นหาแบบ full-text บน Pi ที่บ้าน และแม้โหลดสูงสุดจะมีเพียงไม่กี่ rps จึงไม่ได้มากนัก แต่ CPU ก็แทบไม่เคยกระโดดเกินไม่กี่เปอร์เซ็นต์ ผมทดสอบโหลดการค้นหาบน Pi ได้ราว 100rps และมันก็รับไหว เป็นไลบรารีที่มีประโยชน์มากเพราะแทบจะเอาไปเสียบแทนได้ตรง ๆ ทีมก็ตอบสนองต่อบั๊กรีพอร์ตได้เร็วมาก และมีบั๊กน้อยมากด้วย
    ถ้าอยากดูว่าการตอบสนองของการค้นหาบนอุปกรณ์เล็ก ๆ แบบนี้เป็นอย่างไร ให้กดที่ป้ายกำกับของแต่ละสตอรี มันแทบจะ query ได้ทันที และกำลังยิงไปที่ search shard สูงสุด 10 ปี * 12 เดือน: https://progscrape.com/?search=javascript
    ถ้าเป็นโปรเจ็กต์สมัยใหม่ ผมแนะนำให้ดูตัวนี้แทน Lucene มันสเกลได้ดีขนาดนี้แม้บน ARM64 เครื่องเล็ก ๆ ดังนั้นบนเซิร์ฟเวอร์ที่ใหญ่กว่าน่าจะให้ประสบการณ์ที่ดียิ่งกว่า
    [1] https://github.com/progscrape/progscrape

    • เป็นไลบรารีที่ดีมาก ผมกำลังใช้มันกับ เครื่องมือ CLI สำหรับสำรองอีเมลแบบ incremental ที่ยังทำอยู่มาก สำหรับผู้ให้บริการอีเมลที่ใช้ JMAP
      ผมอยากให้ผู้ใช้ค้นหาในแบ็กอัปของตัวเองได้ และเพราะใช้ Rust อยู่แล้ว Tantivy เลยดูเหมาะพอดี ความเร็วในการทำดัชนีอีเมลหนึ่งฉบับเร็วมากจนไม่จำเป็นต้องย้ายไปไว้ใน thread แยก และการค้นหาอีเมลหลายพันฉบับก็ดูไม่มีปัญหา
      ถ้าแอปพลิเคชัน Rust ของคุณต้องการระบบค้นหา Tantivy ก็น่าลองดู
    • รายงานบั๊กเล็กน้อย: ที่ https://progscrape.com/?search=grep มีข้อความ Error: PersistError(UnexpectedError("Storage fetch panicked")) แสดงอยู่
    • เมื่อไม่กี่วันก่อนผมใช้ meilisearch สำหรับ proof of concept แบบรวดเร็ว แต่พอเห็น repo นี้แล้วคงต้องกลับมาดู Tantivy อีกครั้ง
      โดยพื้นฐานแล้วสิ่งที่ต้องการมีแค่ full-text search
  • ช่วงนี้ผมเพิ่งเจอ Tantivy ภายใน ParadeDB ซึ่ง ParadeDB เป็น ส่วนขยาย Postgres ที่พยายามมาแทน Elastic
    https://github.com/paradedb/paradedb/blob/dev/pg_search/Carg...
    รู้จักจากการฟัง “Extending Postgres for High Performance Analytics (with Philippe Noël)”
    https://www.youtube.com/watch?v=NbOAEJrsbaM
    และมันยังอยู่ในโปรเจ็กต์หลักอย่าง Quickwit ด้วย ซึ่งเป็นโปรเจ็กต์ที่จัดการทั้งล็อก การติดตาม และในไม่ช้าก็เมตริกด้วย
    https://github.com/quickwit-oss/quickwit
    ผมเคยลองใช้ Quickwit คู่กับ ClickHouse ในโปรเจ็กต์ส่วนตัวด้านการค้นหาแบบหลายภาษา แล้วมันดีจนน่าประหลาดใจ ในที่สุดก็มีชุดผสมที่พอใช้ได้จริงสำหรับภาษาจีน ญี่ปุ่น และเกาหลี
    https://quickwit.io/docs/guides/add-full-text-search-to-your...
    to_tsvector ของ PostgreSQL ไม่เคยเข้ากับ use case ของผมได้ดีจริง ๆ เลย
    SELECT * FROM dump WHERE to_tsvector('english'::regconfig, hh_fullname) @@ to_tsquery('english'::regconfig, 'query');
    หวังว่ามันจะไปได้ดี ถ้าบทความไหนมีคำว่า Tantivy อยู่ ผมคงกดโหวตให้อัตโนมัติ

    • การจัดการทั้งการทำดัชนีและ search query แบบ URL/REST ภายใน SQL ทั้งหมดเป็น รูปแบบการออกแบบ ที่เจ๋งมาก แบบเดียวกันนี้ก็ทำได้ด้วย Postgres FDW
  • ไม่นานมานี้เรา deploy Quickwit ซึ่งสร้างบน Tantivy และทำโดยทีมเดียวกัน ไปใช้งาน production เพื่อทำดัชนีออบเจ็กต์หลายพันล้านรายการ และพอใจมาก ความเร็วในการทำดัชนี ยอดเยี่ยม และ latency ของ query ก็แข่งขันได้
    ที่สำคัญที่สุดคือ การแยก compute ออกจาก storage ให้คุณค่ามหาศาล มันทำให้เราสามารถเปิดบริการค้นหาใหม่บนออบเจ็กต์หลายพันล้านรายการใน object storage และทำ aggregation ที่ซับซ้อนได้ โดยไม่ต้องจ่ายค่าเซิร์ฟเวอร์ประสิทธิภาพสูงที่ต้องรันยาว ๆ ซึ่งทำให้ use case ใหม่ที่เดิมคงมีต้นทุนสูงมากกลายเป็นไปได้
    เมื่อ use case ใหญ่พอที่จะคุ้มกับเซิร์ฟเวอร์ประสิทธิภาพสูง Quickwit ก็ยังมีตัวเลือกให้ cache ข้อมูลไว้ในแต่ละเซิร์ฟเวอร์เพื่อเพิ่มประสิทธิภาพด้วย
    โบนัสก้อนใหญ่อีกอย่างคือทีมใน Discord ช่วยเหลือได้เร็วและเป็นมิตรมาก

  • แหล่งข้อมูลอีกอย่างคือ ดัชนีค้นหา trigram ที่เขียนด้วย Go และใช้ใน etsy/hound[0] โดยอิงจากบทความและโค้ดของ Russ Cox ชื่อ “Regular Expression Matching with a Trigram Index”[1]
    [0] https://github.com/hound-search/hound
    [1] http://swtch.com/~rsc/regexp/regexp4.html
    ทางเลือกแทน Lucene ก็มี use case ที่แตกต่างกันไปตามความต้องการ

  • สิ่งที่ต้องระวังคือยัง เพิ่ม/ลบฟิลด์ ไม่ได้: https://github.com/quickwit-oss/tantivy/issues/470
    วิธีเดียวที่จะเพิ่มฟิลด์ได้คือทำดัชนีข้อมูลทั้งหมดใหม่ไปยังดัชนีค้นหาอื่น

  • เจอ Tantivy ระหว่างมองหาทางเลือกแทน Meilisearch ที่ส่งข้อมูล telemetry โดยค่าเริ่มต้น มันใกล้เคียงกับ ตัวสร้างเสิร์ชเอนจิน มากกว่าจะเป็นเสิร์ชเอนจินโดยตัวมันเอง แต่การตั้งค่าดูค่อนข้างเรียบง่าย [0]
    [0]: https://github.com/quickwit-oss/tantivy-cli

    • QuickWit ก็ส่ง telemetry โดยค่าเริ่มต้นเช่นกัน: https://quickwit.io/docs/telemetry
    • สนใจอยู่ แต่ถ้าใช้เป็นไลบรารี Rust ก็อยากจัดการแค่ ชนิดข้อมูล Rust แทน JSON config
      Java SDK ของ Meilisearch ก็ดีเหมือนกัน ไม่ต้องใช้ CLI หรือคอนฟิกด้วยมือ แค่ชี้ไปที่ database entity ก็ทำดัชนีได้ทั้งตาราง
      ถ้า Tantivy มีแนวทางแบบนั้นด้วยก็คงดี
    • ปิดได้ง่าย ๆ แค่เพิ่ม argument ในบรรทัดคำสั่งตัวเดียว แต่จะปฏิเสธเครื่องมือค้นหาเชิงโต้ตอบที่ใช้งานได้ดีเพราะเหตุผลนั้นก็ดูเป็นการคัดค้านเล็กน้อยเกินไป
  • Tantivy ยังถูกใช้เพื่อให้ความสามารถด้าน full-text search ในผลิตภัณฑ์ ฐานข้อมูลเวกเตอร์ ที่น่าสนใจชื่อ LanceDb ด้วย: https://lancedb.github.io/lancedb/fts/
    ตอนที่ดูครั้งล่าสุดยังทำได้ผ่าน Python binding เท่านั้น แต่เข้าใจว่ากำลังจะทำ Rust binding แบบเนทีฟเพื่อรองรับแพลตฟอร์มอื่น

  • เมื่อหลายปีก่อนเริ่มโปรเจกต์ส่วนตัวขึ้นมาเพราะ Elasticsearch เป็น สัตว์ประหลาดกินทรัพยากร ที่น่าหงุดหงิดสุด ๆ แม้แต่เครื่องส่วนตัวของผมยังมีทรัพยากรมากกว่าที่สตาร์ตอัปฐานะดีหลายแห่งจัดให้ผลิตภัณฑ์ของตัวเองเสียอีก
    เหตุผลที่เลือก Tantivy มีสองข้อ อย่างแรกคืออยากทำทุกอย่างด้วย Rust และอีกข้อก็คือ Tantivy เอง ประสิทธิภาพให้ 10/10 เอกสารยอดเยี่ยมมาก และประสบการณ์ใช้งานไลบรารีก็ดีมาก
    น่าเสียดายที่ขอบเขตโปรเจกต์ใหญ่เกินกว่าจะทำคนเดียวในเวลาว่างไหว เลยต้องเลิกไป แต่ถึงอย่างนั้น Tantivy ก็ยอดเยี่ยมจริง ๆ

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

  • ในฐานะคนที่ใช้ Lucene กับ Solr มาเยอะ สิ่งที่อยากได้มากที่สุดคือ การรองรับการอัปเกรด ปกติดัชนีของ Lucene, Solr และ ES มักอัปเกรดไปเวอร์ชันใหม่ไม่ได้ บางกรณีก็พอทำได้ แต่ขอไม่นับเพื่อความสะดวก
    ในโปรเจกต์ขนาดใหญ่ การทำดัชนีใหม่มีค่าใช้จ่ายสูงมาก และบางครั้งก็แทบเป็นไปไม่ได้
    บางกรณีก็มีโอกาสสูงมากที่จะเป็นไปไม่ได้จริง ๆ เช่น เมื่ออัลกอริทึมการทำดัชนีของชนิดข้อมูลในฟิลด์ดัชนีแบบ lossy เปลี่ยนไป แต่ในหลายกรณีข้อมูลทุกอย่างยังอยู่ครบ ดังนั้นถ้าระบุดัชนีแบบนั้นและอัปเกรดได้ก็คงดีมาก