โครงสร้างข้อมูล snapshottable ที่ดีสำหรับดัชนีในหน่วยความจำ


12

ฉันออกแบบฐานข้อมูลวัตถุในหน่วยความจำสำหรับกรณีการใช้งานที่เฉพาะเจาะจง เป็นนักเขียนเดียว แต่ต้องสนับสนุนการอ่านพร้อมกันอย่างมีประสิทธิภาพ การอ่านต้องถูกแยกออก ไม่มีภาษาของแบบสอบถามฐานข้อมูลรองรับเท่านั้น:

  • รับวัตถุ / -s โดยคุณลักษณะ / ชุดของคุณลักษณะ (อาจมีการสนับสนุนสำหรับการแสดงออกเช่นx.count < 5)
  • รับคุณลักษณะของวัตถุ

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

สิ่งที่ฉันต้องการคือโครงสร้างข้อมูลสำหรับดัชนีแอ็ตทริบิวต์ของวัตถุซึ่งสามารถเป็น O (n) กับการเขียนไม่สนับสนุนการเขียนพร้อมกัน แต่ควรสนับสนุนการถ่ายภาพ O (1) อย่างสมบูรณ์ (อาจคัดลอกบนการเขียน) และ O (logN) เป็นการดีที่มันจะช่วยให้การทำงานพร้อมกันสูงในการอ่านที่มีการแบ่งปันโครงสร้างสูงสุดระหว่างรุ่น

ฉันกำลังดูCTries , BSTsที่เกิดขึ้นพร้อมกันและต้นไม้ Splay ที่เกิดขึ้นพร้อมกันแต่ฉันไม่แน่ใจว่าฉันกำลังมองไปในทิศทางที่ถูกต้องที่นี่หรือไม่ โครงสร้างด้านบนให้ความสนใจอย่างมากกับความซับซ้อนของเม็ดมีดซึ่งฉันไม่สนใจ

คำถาม : มีโครงสร้างข้อมูลที่รู้จักที่เหมาะสมกับกรณีการใช้งานของฉันหรือไม่?

แก้ไข : หลังจากคิดเพิ่มเติมบางอย่างดูเหมือนว่าต้นไม้ BST / Splay ถาวรจะทำงาน ผู้เขียนจะอัปเดตสำเนา 'ต้นแบบ' และข้อความค้นหาจะได้รับต้นไม้ตั้งแต่เริ่มต้นการดำเนินการและโยนทิ้งหลังจากเสร็จสิ้น อย่างไรก็ตามฉันยังสนใจถ้ามีทางออกที่ดีกว่า


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

มันอยู่ในความทรงจำทั้งหมด ฉันสงสัยว่าอาจมีเวอร์ชันที่ไม่แน่นอนที่มีประสิทธิภาพพร้อมสแนปชอตเวลาคงที่ (เช่น CTrie โดยไม่มีการเขียนพร้อมกัน)
dm3

2
ปัญหาของคุณอาจน้อยกว่าตัวเลือกโครงสร้างข้อมูล แต่เป็นการควบคุมภาวะพร้อมกัน
Raphael

มันอาจเป็นไปได้ไหมที่คุณจะอธิบายเพิ่มเติมอีกหน่อย?
dm3

คำตอบ:


5

ใช้โครงสร้างข้อมูลแบบต้นไม้ที่คงอยู่ / ไม่เปลี่ยนแปลง (เช่นการทำงาน) กุญแจคือการล็อคขวา @Raphael ชี้ให้เห็นในความคิดเห็น

สิ่งที่ดีเกี่ยวกับโครงสร้างข้อมูลแบบต้นไม้ / การทำงาน / ถาวรคือคุณได้รับ "ภาพรวม" ได้ฟรี สมมติว่าคุณใช้treap (แผนภูมิการค้นหาแบบสุ่มไบนารี) สำหรับโครงสร้างข้อมูลของคุณ นี่คือตัวอย่างของหนึ่งเขียนในไปนี้: https://github.com/steveyen/gtreap ผู้เขียนอธิบายว่า:

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

ณ เวลาใด ๆ สถานะ "ปัจจุบัน" ของต้นไม้จะถูกแสดงโดยตัวชี้ไปยังรากของต้นไม้ ส่วนแทรกนั้นไม่ใช่การกลายพันธุ์ แต่การแทรกจะรักษาเวอร์ชันก่อนหน้าของต้นไม้ไว้โดยสมบูรณ์สร้างโหนดใหม่สำหรับเส้นทางจากรูตไปยังจุดแทรกที่ถูกต้องโดยที่พอยน์เตอร์จะกลับไปที่โหนดของเวอร์ชันก่อนหน้าที่สามารถแชร์ได้O(logn)

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

lock
tmp = ptr_to_root
unlock
value = search(tmp, <value to search for>)
return value

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

การเขียนคือ:

lock
old_ptr_to_root = ptr_to_root
ptr_to_root = insert(old_ptr_to_root, <new key/value pair>)
unlock

ในรุ่นนี้การเขียนจะต้องระงับการล็อคในระหว่างกระบวนการทั้งหมดในการสร้างทรีเวอร์ชั่นใหม่ คุณสามารถปรับปรุงประสิทธิภาพการอ่าน (ในบางครั้งการทำธุรกรรมการเขียนล้มเหลว) โดยการเปลี่ยนการเขียนเป็นดังนี้:

top:
  lock
  old_ptr_to_root = ptr_to_root
  unlock
  new_ptr_to_root = insert(old_ptr_to_root, <new key/value pair>)
  lock
  if (ptr_to_root == old_ptr_to_root)   # make sure no other write happened in the interim
    ptr_to_root = new_ptr_to_root
    unlock
  else                                  # transaction fails, try again
    unlock
    goto top

คุณอาจจะทำได้ดีขึ้นเล็กน้อย (ทำให้ "ล็อคฟรี") หากภาษาการเขียนโปรแกรมของคุณมีตัวแปรอะตอมมิกที่มีการดำเนินการเปรียบเทียบและสลับอะตอม (ตัวอย่างเช่นโดยใช้ภาษา C ++ 11 atomic<T*>)


ขอบคุณสำหรับคำตอบที่บรรจง ฉันรู้ว่าบางทีฉันอาจจะไม่ได้พูดให้ชัดเจนในคำถาม อย่างไรก็ตามคำตอบก็ยังยอดเยี่ยม!
dm3

รุ่น "ปรับปรุง" ของคุณขึ้นอยู่กับรุ่นหน่วยความจำของระบบที่ใช้งานอยู่ มันอาจต้องใช้ verables ที่จะประกาศให้ทราบถึงความผันผวนในบางระบบและต้องการทักษะที่ยอดเยี่ยมในการเขียนโค้ดให้ถูกต้อง
Ian Ringrose

1

Microsoft ได้เผยแพร่รายละเอียดเกี่ยวกับฐานข้อมูลหน่วยความจำใหม่ซึ่งมีดัชนีที่ไม่บล็อกการอ่านในขณะที่กำลังเขียน

ตัวอย่างเช่น:

Justin Levandoski, David Lomet และ Sudipta Sengupta, The Bw-Tree: B-tree สำหรับฮาร์ดแวร์ใหม่ในปี 2013 IEEE 29 การประชุมนานาชาติทางวิศวกรรมข้อมูล (ICDE) การประชุมระหว่างประเทศเกี่ยวกับวิศวกรรมข้อมูล 8 เมษายน 2013

ดูhttp://research.microsoft.com/en-us/projects/main-memory_dbs/เพื่อดูรายการสิ่งพิมพ์ของพวกเขา

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