ทุกชุดข้อมูลถูกแบ่งเป็นเซ็กเม้นต์ แต่ละเซ็กเม้นต์มีการจัดเก็บเวกเตอร์อิสระ การจัดเก็บเปรียบเสมือน, และดัชนี

ข้อมูลในเซ็กเม้นต์มักจะไม่ทับซ้อนกัน อย่างไรก็ตาม การจัดเก็บจุดเดียวกันในเซ็กเม้นต์ที่แตกต่างกันไม่ทำให้เกิดปัญหา เนื่องจากการค้นหามีกลไกการตัดซ้ำ

เซ็กเม้นต์ประกอบด้วยการจัดเก็บเวกเตอร์, การจัดเก็บข้อมูลแบบเปรียบเสมือน, ดัชนีเวกเตอร์, ดัชนีข้อมูลแบบเปรียบเสมือน, และตัวแม็ปเพื่อจัดเก็บความสัมพันธ์ระหว่างตัวระบุภายในและต่างประเทศ

เซ็กเม้นต์สามารถเป็น "เพิ่มเติม" หรือ "ไม่เพิ่มเติม" ขึ้นอยู่กับประเภทของการจัดเก็บและดัชนีที่ใช้ คุณสามารถเพิ่ม, ลบ, และค้นข้อมูลในเซ็กเม้นต์ "เพิ่มเติม" โดยอิสระ, ในขณะที่เซ็กเม้นต์ "ไม่เพิ่มเติม" สามารถอ่านและลบข้อมูลเท่านั้น

การกำหนดค่าของเซ็กเม้นต์ในชุดข้อมูลอาจแตกต่างกันและอยู่อิสระจากกัน อย่างไรก็ตาม ต้องมีเซ็กเม้นต์ "เพิ่มเติม" อย่างน้อยหนึ่งเซ็กเม้นต์

การจัดเก็บเวกเตอร์

ขึ้นอยู่กับความต้องการของแอปพลิเคชัน Qdrant สามารถใช้ตัวเลือกการจัดเก็บข้อมูลต่อไปนี้ การเลือกต้องสมดุลระหว่างความเร็วในการค้นหาและการใช้ RAM

การจัดเก็บในหน่วยความจำ - จัดเก็บเวกเตอร์ทั้งหมดในหน่วยความจำ มีความเร็วสูงสุดเนื่องจากต้องการเข้าถึงดิสก์เท่านั้นในขณะที่ทำการจัดเก็บ

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

การกำหนดค่าการจัดเก็บผ่านเมมแม็ป

มีวิธีการกำหนดค่าการใช้เมมแมป (ที่เรียกว่าการจัดเก็บบนดิสก์) อย่างน้อย 2 วิธี:

  • ตั้งค่าตัวเลือก on_disk สำหรับเวกเตอร์ใน API การสร้างชุดข้อมูล:

ใช้ได้เฉพาะเวอร์ชัน 1.2.0 และสูงกว่า

PUT /collections/{collection_name}

{
    "vectors": {
      "size": 768,
      "distance": "Cosine",
      "on_disk": true
    }
}

นี้จะสร้างชุดข้อมูลที่จัดเก็บเวกเตอร์ทั้งหมดในการจัดเก็บผ่านเมมแมปทันที นี่คือวิธีที่แนะนำเมื่อ Qdrant ใช้ดิสก์ที่เร็วและต้องจัดการกับชุดข้อมูลขนาดใหญ่

  • ตั้งค่าตัวเลือก memmap_threshold_kb ตัวเลือกนี้จะกำหนดค่าเกณฑ์สําหรับการแปลงเซกเม้นต์เพื่อจัดเก็บผ่านเมมแมป

มีวิธีการสมบูรณ์ ๆ ในการทำเช่นนี้:

  1. ตั้งค่าเกณฑ์เป็นระดับโลกในไฟล์กําหนดระบบ ชื่อพารามิเตอร์คือ memmap_threshold_kb
  2. ตั้งค่าเกณฑ์เป็นระดับกำลังพิเศษสําหรับแต่ละชุดข้อมูลภายในการสร้างหรือการปรับปรุง
PUT /collections/{collection_name}

{
    "vectors": {
      "size": 768,
      "distance": "Cosine"
    },
    "optimizers_config": {
        "memmap_threshold": 20000
    }
}

กฎของมือสำหรับการกำหนดค่าเกณฑ์เมมแมปคือง่าย ๆ:

  • หากสถานการณ์การใช้งานสมดุลแล้ว – ตั้งค่าเกณฑ์เมมแมปเท่ากับ indexing_threshold (ค่าเริ่มต้นคือ 20000) ในกรณีนี้ ตัวปรับปรุงจะไม่ดำเนินการรันเพิ่มเติมและจะปรับปรุงทุกเกณฑ์พร้อม ๆ กัน
  • หากภาระงานเขียนสูงและหน่วยความจำน้อย – ตั้งค่าเกณฑ์เมมแมปต่ำกว่า indexing_threshold เช่น 10000 ในกรณีนี้ ตัวปรับปรุงจะแปลงเซกเม้นต์เพื่อจัดเก็บผ่านเมมแมปก่อน แล้วจึงทำการใช้ดัชนี

อีกทั้งคุณสามารถใช้การจัดเก็บผ่านเมมแมปไม่เพียงแต่สําหรับเวกเตอร์ แต่ยังสําหรับดัชนี HNSW ด้วย เพื่อเปิดใช้คุณสมบัตินี้ ตั้งค่าพารามิเตอร์ hnsw_config.on_disk เป็น true เมื่อสร้างชุดข้อมูล

PUT /collections/{collection_name}

{
    "vectors": {
      "size": 768,
      "distance": "Cosine"
    },
    "optimizers_config": {
        "memmap_threshold": 20000
    },
    "hnsw_config": {
        "on_disk": true
    }
}

การเก็บข้อมูล Payload

Qdrant รองรับการเก็บข้อมูล payload 2 ประเภท: InMemory และ OnDisk

การเก็บข้อมูล payload แบบ InMemory จัดระเบียบข้อมูล payload ในลักษณะเดียวกับเวกเตอร์ในหน่วยความจำ ข้อมูล payload จะถูกโหลดเข้าสู่หน่วยความจำเมื่อบริการเริ่มต้น ในขณะเดียวกันหน่วยความจำและ RocksDB ถูกใช้เพื่อคงทนเท่านั้น ประเภทนี้เป็นการเก็บข้อมูลที่มีความเร็วมากอย่างมาก แต่อาจต้องใช้พื้นที่หน่วยความจำสูงเพื่อเก็บข้อมูลทั้งหมดโดยเฉพาะถ้า payload มีค่าขนาดใหญ่ (เช่น สรุปข้อความหรือภาพ)

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

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

การควบคุมเวอร์ชัน

เพื่อให้มั่นใจในความถูกต้องของข้อมูล Qdrant ดำเนินการเปลี่ยนแปลงข้อมูลทั้งหมดใน 2 ขั้นตอน ก่อนอื่น ข้อมูลถูกเขียนลงใน Write-ahead-log (WAL) ซึ่งทำการเรียงลำดับและกำหนดหมายเลขต่อท้ายแต่ละการดำเนินการ

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