อัลกอริทึม Hi / Lo คืออะไร?
ฉันพบสิ่งนี้ในเอกสารของNHibernate (เป็นวิธีหนึ่งในการสร้างคีย์ที่ไม่ซ้ำกันในส่วน 5.1.4.2) แต่ฉันไม่พบคำอธิบายที่ดีเกี่ยวกับวิธีการทำงาน
ฉันรู้ว่า Nhibernate จัดการกับมันและฉันไม่จำเป็นต้องรู้ว่าข้างใน แต่ฉันแค่อยากรู้
อัลกอริทึม Hi / Lo คืออะไร?
ฉันพบสิ่งนี้ในเอกสารของNHibernate (เป็นวิธีหนึ่งในการสร้างคีย์ที่ไม่ซ้ำกันในส่วน 5.1.4.2) แต่ฉันไม่พบคำอธิบายที่ดีเกี่ยวกับวิธีการทำงาน
ฉันรู้ว่า Nhibernate จัดการกับมันและฉันไม่จำเป็นต้องรู้ว่าข้างใน แต่ฉันแค่อยากรู้
คำตอบ:
แนวคิดพื้นฐานคือคุณมีตัวเลขสองตัวเพื่อสร้างคีย์หลัก - หมายเลข "สูง" และหมายเลข "ต่ำ" โดยทั่วไปแล้วลูกค้าสามารถเพิ่มลำดับ "สูง" โดยรู้ว่าสามารถสร้างคีย์ได้อย่างปลอดภัยจากช่วงทั้งหมดของค่า "สูง" ก่อนหน้านี้ด้วยความหลากหลายของค่า "ต่ำ"
ตัวอย่างเช่นสมมติว่าคุณมีลำดับ "สูง" ที่มีค่าปัจจุบันเท่ากับ 35 และหมายเลข "ต่ำ" อยู่ในช่วง 0-1023 จากนั้นลูกค้าสามารถเพิ่มลำดับเป็น 36 (เพื่อให้ลูกค้ารายอื่นสามารถสร้างคีย์ได้ในขณะที่ใช้งาน 35) และรู้ว่าคีย์ 35/0, 35/1, 35/2, 35/3 ... 35/1023 คือ ที่มีอยู่ทั้งหมด
มันมีประโยชน์มาก (โดยเฉพาะกับ ORMs) เพื่อให้สามารถตั้งค่าคีย์หลักในฝั่งไคลเอ็นต์แทนการแทรกค่าโดยไม่มีคีย์หลักแล้วดึงกลับไปยังไคลเอนต์ นอกเหนือจากสิ่งอื่นก็หมายความว่าคุณสามารถทำให้ผู้ปกครอง / ความสัมพันธ์กับเด็กและมีกุญแจทั้งหมดในสถานที่ก่อนที่คุณทำใด ๆแทรกซึ่งจะทำให้พวกเขา batching ง่าย
นอกจากคำตอบของจอน:
มันถูกใช้เพื่อให้สามารถเชื่อมต่อการทำงาน จากนั้นลูกค้าสามารถขอหมายเลขเซิร์ฟเวอร์และสร้างวัตถุที่เพิ่มจำนวนตัวเองได้ ไม่จำเป็นต้องติดต่อกับเซิร์ฟเวอร์จนกว่าจะใช้ช่วงที่มีค่าหมด
เนื่องจากนี่เป็นคำถามที่พบบ่อยมากฉันจึงเขียนบทความนี้ขึ้นมาซึ่งคำตอบนี้ขึ้นอยู่กับ
อัลกอริทึม hi / lo แยกโดเมนลำดับออกเป็นกลุ่ม "hi" ค่า“ hi” ถูกกำหนดให้พร้อมกัน กลุ่ม "hi" ทุกกลุ่มจะได้รับรายการ "lo" สูงสุดจำนวนสูงสุดซึ่งสามารถกำหนดโดยออฟไลน์โดยไม่ต้องกังวลเกี่ยวกับรายการที่ซ้ำกันที่เกิดขึ้นพร้อมกัน
ช่วงตัวระบุได้รับจากสูตรต่อไปนี้:
[(hi -1) * incrementSize) + 1, (hi * incrementSize) + 1)
และค่า "lo" จะอยู่ในช่วง:
[0, incrementSize)
ถูกนำไปใช้จากค่าเริ่มต้นของ:
[(hi -1) * incrementSize) + 1)
เมื่อใช้ค่า "lo" ทั้งหมดจะมีการเรียกค่า "hi" ใหม่และวัฏจักรจะดำเนินต่อไป
คุณสามารถหาคำอธิบายโดยละเอียดเพิ่มเติมได้ในบทความนี้ :
และการนำเสนอด้วยภาพนี้ง่ายต่อการติดตามเช่นกัน:
ในขณะที่เครื่องมือเพิ่มประสิทธิภาพ hi / lo นั้นใช้งานได้ดีสำหรับการปรับการสร้างตัวระบุ แต่มันก็เล่นได้ไม่ดีนักกับระบบอื่น ๆ ที่แทรกแถวเข้าไปในฐานข้อมูลของเรา
Hibernate เสนอเครื่องมือเพิ่มประสิทธิภาพpooled-loซึ่งนำเสนอข้อดีของกลยุทธ์ตัวสร้าง hi / lo ขณะเดียวกันก็ให้การทำงานร่วมกันกับลูกค้าบุคคลที่สามอื่น ๆ ที่ไม่ทราบถึงกลยุทธ์การจัดสรรลำดับนี้
เนื่องจากทั้งประสิทธิภาพและทำงานร่วมกันกับระบบอื่น ๆ เครื่องมือเพิ่มประสิทธิภาพ pooled-lo เป็นตัวเลือกที่ดีกว่ากลยุทธ์ตัวระบุ hi / lo แบบดั้งเดิม
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "name") @SequenceGenerator(name="name", sequenceName = "name_seq", allocationSize=100)
รหัสประจำตัวของฉัน
, (hi * incrementSize) + 1)
... มันควรจะ, hi * incrementSize)
ใช่มั้ย?
Lo คือตัวจัดสรรแคชที่แยก keyspace ออกเป็นชิ้นใหญ่โดยทั่วไปจะขึ้นอยู่กับขนาดของคำศัพท์ของเครื่องแทนที่จะเป็นช่วงขนาดที่มีความหมาย
การใช้ Hi-Lo มีแนวโน้มที่จะทำให้เสียคีย์จำนวนมากในการรีสตาร์ทเซิร์ฟเวอร์และสร้างค่าคีย์ขนาดใหญ่ที่ไม่เป็นมิตรกับมนุษย์
ดีกว่าตัวจัดสรร Hi-Lo คือตัวจัดสรร "Linear Chunk" สิ่งนี้ใช้หลักการที่อิงกับตารางคล้ายกัน แต่จัดสรรชิ้นขนาดเล็กและสะดวกสบายและสร้างคุณค่าที่เป็นมิตรกับมนุษย์
create table KEY_ALLOC (
SEQ varchar(32) not null,
NEXT bigint not null,
primary key (SEQ)
);
หากต้องการจัดสรรถัดไปให้พูด 200 คีย์ (ซึ่งจะถูกเก็บไว้เป็นช่วงในเซิร์ฟเวอร์ & ใช้ตามต้องการ):
select NEXT from KEY_ALLOC where SEQ=?;
update KEY_ALLOC set NEXT=(old value+200) where SEQ=? and NEXT=(old value);
เพื่อให้คุณสามารถทำธุรกรรมนี้ (ใช้การลองใหม่เพื่อจัดการกับการโต้แย้ง) คุณได้จัดสรร 200 คีย์และสามารถแจกจ่ายได้ตามต้องการ
ด้วยขนาดที่เล็กเพียง 20 โครงร่างนี้เร็วกว่าการจัดสรรจากลำดับ Oracle 10 เท่าและสามารถพกพาได้ 100% ในฐานข้อมูลทั้งหมด ประสิทธิภาพการจัดสรรเทียบเท่ากับ hi-lo
ซึ่งแตกต่างจากความคิดของ Ambler มันถือว่า keyspace เป็นตัวเลขเชิงเส้นที่ต่อเนื่องกัน
สิ่งนี้หลีกเลี่ยงแรงกระตุ้นสำหรับคีย์คอมโพสิต (ซึ่งไม่เคยเป็นความคิดที่ดีจริงๆ) และหลีกเลี่ยงการสูญเสียคำศัพท์ทั้งหมดเมื่อเซิร์ฟเวอร์รีสตาร์ท มันสร้างค่าคีย์มิตร "มิตร" ระดับมนุษย์
ความคิดของนายแอมโบเลอร์โดยการเปรียบเทียบจัดสรร 16-32- บิตสูงและสร้างค่าคีย์ที่ไม่เป็นมิตรกับมนุษย์จำนวนมากเป็นการเพิ่มคำศัพท์
การเปรียบเทียบคีย์ที่จัดสรร:
Linear_Chunk Hi_Lo
100 65536
101 65537
102 65538
.. server restart
120 131072
121 131073
122 131073
.. server restart
140 196608
การออกแบบที่ชาญฉลาดโซลูชันของเขามีความซับซ้อนโดยพื้นฐานบนหมายเลขบรรทัด (คีย์ผสมผลิตภัณฑ์ hi_word ขนาดใหญ่) กว่า Linear_Chunk โดยไม่ได้รับผลประโยชน์เชิงเปรียบเทียบ
การออกแบบ Hi-Lo เกิดขึ้นในช่วงต้นของการทำแผนที่ OO และการคงอยู่ เฟรมเวิร์กการคงอยู่ของวันนี้เช่น Hibernate เสนอตัวจัดสรรที่ง่ายกว่าและดีกว่าเป็นค่าเริ่มต้น
ฉันพบว่าอัลกอริทึม Hi / Lo นั้นสมบูรณ์แบบสำหรับหลายฐานข้อมูลที่มีสถานการณ์การจำลองแบบตามประสบการณ์ ลองนึกภาพสิ่งนี้ คุณมีเซิร์ฟเวอร์ในนิวยอร์ก (นามแฝง 01) และเซิร์ฟเวอร์อื่นในลอสแองเจลิส (นามแฝง 02) จากนั้นคุณมีตารางส่วนบุคคล ... ดังนั้นในนิวยอร์กเมื่อบุคคลสร้าง ... คุณใช้ 01 เป็นค่า HI เสมอ และค่า LO คือ secuential ถัดไป ตัวอย่าง
ในลอสแองเจลิสคุณใช้ HI 02 เสมอเช่น:
ดังนั้นเมื่อคุณใช้การจำลองแบบฐานข้อมูล (ไม่ว่ายี่ห้อใด) คีย์หลักและข้อมูลทั้งหมดจะรวมกันได้อย่างง่ายดายและเป็นธรรมชาติโดยไม่ต้องกังวลกับคีย์หลักที่ซ้ำกันการคอลและอื่น ๆ
นี่เป็นวิธีที่ดีที่สุดในสถานการณ์นี้