จะใช้แคชระดับที่สองในโหมดไฮเบอร์เนตเมื่อใดและอย่างไร


91

ฉันมีปัญหาในการทำความเข้าใจเมื่อไฮเบอร์เนตถึงแคชระดับที่สองและเมื่อใดที่แคชไม่ถูกต้อง

นี่คือสิ่งที่ฉันเข้าใจในปัจจุบัน:

  • แคชระดับที่สองเก็บเอนทิตีระหว่างเซสชันขอบเขตคือ SessionFactory
  • คุณต้องบอกว่าเอนทิตีใดที่จะแคชไม่มีเอนทิตีใดจะถูกแคชโดยค่าเริ่มต้น
  • แคชแบบสอบถามจะเก็บผลลัพธ์ของคิวรีไว้ในแคช

สิ่งที่ฉันไม่เข้าใจคือ

  • เมื่อใดที่ไฮเบอร์เนตจะเข้าสู่แคชนี้
  • สมมติว่าฉันได้ตั้งค่าแคชระดับที่สองแล้ว แต่ไม่ใช่การแคชแบบสอบถาม ฉันต้องการแคชลูกค้าของฉันมี 50000 คน ฉันจะดึงข้อมูลลูกค้าจากแคชด้วยวิธีใดได้บ้าง
  • ฉันคิดว่าฉันสามารถรับได้โดย id จากแคช ซึ่งจะเป็นเรื่องง่าย แต่ก็ไม่คุ้มค่ากับการแคช แต่ถ้าฉันต้องการคำนวณกับลูกค้าทั้งหมดของฉัน สมมติว่าฉันต้องการแสดงรายชื่อลูกค้าแล้วฉันจะเข้าถึงได้อย่างไร
  • ฉันจะหาลูกค้าทั้งหมดได้อย่างไรหากปิดใช้งานการแคชแบบสอบถาม
  • จะเกิดอะไรขึ้นหากมีคนอัปเดตลูกค้ารายใดรายหนึ่ง
    • ลูกค้ารายนั้นจะถูกทำให้แคชเป็นโมฆะหรือลูกค้าทั้งหมดจะไม่ถูกต้อง

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

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


คำตอบ:


102

ก่อนอื่นเรามาพูดถึงแคชระดับกระบวนการ (หรือแคชระดับที่ 2 ตามที่พวกเขาเรียกในไฮเบอร์เนต) เพื่อให้มันใช้งานได้คุณควร

  1. กำหนดค่าผู้ให้บริการแคช
  2. บอกจำศีลว่าเอนทิตีใดที่จะแคช (ในไฟล์ hbm.xml หากคุณใช้การแมปประเภทนี้)

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

  • คุณเขียนลงในฐานข้อมูลผ่าน Hibernate เท่านั้น (เนื่องจากต้องการวิธีที่จะทราบว่าเมื่อใดควรเปลี่ยนหรือทำให้เอนทิตีในแคชไม่ถูกต้อง)
  • คุณอ่านวัตถุบ่อยๆ
  • คุณมีโหนดเดียวและคุณไม่มีการจำลองแบบ มิฉะนั้นคุณจะต้องจำลองแคชเอง (ใช้แคชแบบกระจายเช่น JGroups) ซึ่งจะเพิ่มความซับซ้อนมากขึ้นและไม่ได้ปรับขนาดได้ดีเท่ากับแอปที่ไม่ต้องแชร์

แคชทำงานเมื่อใด

  • เมื่อคุณsession.get()หรือsession.load()วัตถุที่เลือกไว้ก่อนหน้านี้และอยู่ในแคช แคชคือที่เก็บข้อมูลที่ ID เป็นคีย์และคุณสมบัติคือค่า ดังนั้นเมื่อมีความเป็นไปได้ที่จะค้นหาด้วย ID คุณสามารถกำจัดการกดปุ่ม DB ได้
  • เมื่อการเชื่อมโยงของคุณขี้เกียจโหลด (หรือกระตือรือร้นที่จะโหลดด้วยการเลือกแทนการรวม)

แต่ไม่ได้ผลเมื่อ:

  • หากคุณไม่ได้เลือกด้วย ID อีกครั้ง - แคชระดับที่ 2 จะจัดเก็บแผนที่ของ ID ของเอนทิตีไปยังคุณสมบัติอื่น ๆ (จริงๆแล้วไม่ได้เก็บออบเจ็กต์ แต่เป็นข้อมูลเอง) ดังนั้นหากการค้นหาของคุณมีลักษณะเช่นนี้from Authors where name = :nameคุณจะไม่โดนแคช
  • เมื่อคุณใช้ HQL (แม้ว่าคุณจะใช้where id = ?)
  • หากคุณตั้งค่าไว้ในการแม็ปfetch="join"หมายความว่าการโหลดการเชื่อมโยงจะถูกใช้ทุกที่แทนที่จะใช้คำสั่งที่เลือกแยกต่างหาก แคชระดับกระบวนการทำงานบนอ็อบเจ็กต์ชายน์ต่อเมื่อfetch="select"ถูกใช้
  • แม้ว่าคุณจะมีfetch="select"แต่ใน HQL คุณใช้การรวมเพื่อเลือกการเชื่อมโยง - การรวมเหล่านั้นจะออกทันทีและจะเขียนทับสิ่งที่คุณระบุใน hbm.xml หรือคำอธิบายประกอบ

ตอนนี้เกี่ยวกับ Query Cache คุณควรทราบว่าไม่ใช่แคชแยกต่างหาก แต่เป็นส่วนเพิ่มเติมของแคชระดับกระบวนการ สมมติว่าคุณมีนิติบุคคลประเทศ from Countryมันเป็นแบบคงที่เพื่อให้คุณรู้ว่าทุกครั้งที่จะมีชุดผลลัพธ์เดียวกันเมื่อคุณพูด นี่เป็นตัวเลือกที่สมบูรณ์แบบสำหรับแคชการสืบค้นโดยจะเก็บรายการIDไว้ในตัวเองและเมื่อคุณเลือกทุกประเทศในครั้งต่อไประบบจะส่งรายการนี้กลับไปยังแคชระดับกระบวนการและในทางกลับกันจะส่งคืนวัตถุสำหรับแต่ละ ID เนื่องจากวัตถุเหล่านี้ถูกเก็บไว้ในแคชระดับที่ 2 แล้ว แคชการค้นหาไม่ถูกต้องทุกครั้งที่มีการเปลี่ยนแปลงใด ๆ ที่เกี่ยวข้องกับเอนทิตี สมมติว่าคุณกำหนดค่าfrom Authorsให้วางไว้ใน Query Cache จะไม่มีผลเนื่องจากผู้เขียนมีการเปลี่ยนแปลงบ่อยครั้ง


การสืบค้น "จากผู้สร้างการดึงข้อมูลเข้าร่วม a.books" ต้องการแคชการสืบค้นเพื่อดึงข้อมูลผู้เขียนจากแคชหรือไม่
palto

1
ไม่แคชแบบสอบถามใช้สำหรับข้อมูลคงที่เท่านั้นและเก็บเฉพาะ ID ผู้เขียนจะถูกนำมาจากแคชระดับที่ 2
Stanislav Bashkyrtsev

@ctapobep: ไม่จริงอย่างที่พูด! "จาก Author a fetch เข้าร่วม a.books" ใช้ได้ดีหากมีการใส่คำอธิบายประกอบหนังสือภาคสนามของเอนทิตีผู้เขียน (ดึงข้อมูล EAGER) ... มันสายเกินไปฉันคิดว่า
Bilal BBB

คำตอบที่ดีมาก! ฉันจะจำมันตลอดเวลา! : d
Mohammadreza Khatami

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

43
  • แคชระดับที่ 2 เป็นที่เก็บคีย์ - ค่า จะใช้งานได้ก็ต่อเมื่อคุณได้รับเอนทิตีด้วยรหัส
  • แคชระดับที่ 2 ไม่ถูกต้อง / อัปเดตต่อเอนทิตีเมื่อมีการอัปเดต / ลบเอนทิตีผ่านโหมดไฮเบอร์เนต จะไม่เป็นโมฆะหากฐานข้อมูลถูกอัพเดตด้วยวิธีอื่น
  • สำหรับข้อความค้นหา (เช่นรายชื่อลูกค้า) ให้ใช้แคชของแบบสอบถาม

ในความเป็นจริงการมีแคชแบบกระจายคีย์ - ค่านั้นมีประโยชน์นั่นคือสิ่งที่ memcached คือและเพิ่มพลังให้กับ facebook, twitter และอื่น ๆ อีกมากมาย แต่ถ้าคุณไม่มีการค้นหาด้วย id ก็จะไม่มีประโยชน์มากนัก


แคชแบบสอบถาม (ทำงานร่วมกับ Projections, ResultTransformers สำหรับรูปแบบ DTO) และจะไม่ถูกต้องหากคุณอัปเดตเอนทิตีที่ใช้กับแบบสอบถามที่แคชไว้ ดังที่คุณกล่าวไว้แคชระดับที่ 2 จะใช้งานได้เฉพาะกับแบบสอบถามที่คุณได้รับเอนทิตีด้วยรหัส (ใช้ไม่ได้กับข้อ จำกัด ของเกณฑ์) หรือเกณฑ์ที่มีการคาดการณ์ (เลือกเฉพาะบางคุณสมบัติ) BTW เป็นคำตอบที่ดีที่สุด (กลับมาทำงานต่อ) สำหรับ "แคชไฮเบอร์เนตทำงานอย่างไร"
ics_mauricio

12

สายไปงานปาร์ตี้ แต่ต้องการตอบคำถามเหล่านี้อย่างเป็นระบบซึ่งนักพัฒนาหลายคนถาม

การตอบคำถามของคุณทีละคำถามนี่คือคำตอบของฉัน

ถาม: เมื่อใดที่ไฮเบอร์เนตจะเข้าสู่แคชนี้

เอแคชระดับแรกที่เกี่ยวข้องกับวัตถุเซสชัน แคชระดับที่สองมีความเกี่ยวข้องกับวัตถุโรงงานเซสชัน หากไม่พบวัตถุในครั้งแรกระดับที่สองจะถูกตรวจสอบ

ถามสมมติว่าฉันได้ตั้งค่าแคชระดับที่สองแล้ว แต่ไม่ใช่การแคชแบบสอบถาม ฉันต้องการแคชลูกค้าของฉันมี 50000 คน ฉันจะดึงข้อมูลลูกค้าจากแคชด้วยวิธีใดได้บ้าง

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

ถามฉันคิดว่าฉันสามารถรับได้โดย id จากแคช ซึ่งจะเป็นเรื่องง่าย แต่ก็ไม่คุ้มค่ากับการแคช แต่ถ้าฉันต้องการคำนวณกับลูกค้าทั้งหมดของฉัน สมมติว่าฉันต้องการแสดงรายชื่อลูกค้าแล้วฉันจะเข้าถึงได้อย่างไร

ตอบข้างบนแล้ว

ถาม: ฉันจะหาลูกค้าทั้งหมดได้อย่างไรหากปิดใช้งานการแคชแบบสอบถาม

ตอบข้างบนแล้ว

ถามจะเกิดอะไรขึ้นหากมีคนอัปเดตลูกค้ารายใดรายหนึ่ง ลูกค้ารายนั้นจะถูกทำให้แคชเป็นโมฆะหรือลูกค้าทั้งหมดจะไม่ถูกต้อง

A. Hibernate ไม่มีความคิด แต่คุณสามารถใช้ IMDG ของบุคคลที่สาม / แคชแบบกระจายอื่น ๆ เพื่อนำไปใช้เป็นแคชระดับที่สองที่จำศีลและทำให้แคชเหล่านั้นไม่ถูกต้อง เช่นTayzGridเป็นหนึ่งในผลิตภัณฑ์ดังกล่าวและมีอีกมากมายที่ฉันเดา


0

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

เมื่อใดที่ไฮเบอร์เนตเข้าสู่แคชนี้

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

สมมติว่าฉันได้ตั้งค่าแคชระดับที่สองแล้ว แต่ไม่ใช่การแคชแบบสอบถาม ฉันต้องการแคชลูกค้าของฉันมี 50000 คน ฉันจะดึงข้อมูลลูกค้าจากแคชด้วยวิธีใดได้บ้าง

การแคชแบบสอบถามจะดีที่สุดสำหรับกรณีการใช้งานนี้เนื่องจากข้อมูลลูกค้าเป็นแบบคงที่และดึงมาจากฐานข้อมูลเชิงสัมพันธ์

จะเกิดอะไรขึ้นหากมีคนอัปเดตลูกค้ารายใดรายหนึ่ง ลูกค้ารายนั้นจะถูกทำให้แคชเป็นโมฆะหรือลูกค้าทั้งหมดจะไม่ถูกต้อง

ขึ้นอยู่กับกลยุทธ์แคชไฮเบอร์เนตเฉพาะที่คุณใช้ ไฮเบอร์เนตมีกลยุทธ์แคชที่แตกต่างกันสี่แบบ:

READ_ONLY : ออบเจ็กต์จะไม่เปลี่ยนแปลงภายในแคช

NONSTRICT_READ_WRITE : อ็อบเจ็กต์เปลี่ยนแปลง (ในที่สุด) หลังจากอัพเดตรายการฐานข้อมูลที่เกี่ยวข้อง สิ่งนี้รับประกันความสอดคล้องในที่สุด

READ_WRITE : ออบเจ็กต์เปลี่ยน (ทันที) หลังจากอัพเดตรายการฐานข้อมูลที่เกี่ยวข้อง สิ่งนี้รับประกันความมั่นคงแข็งแรงโดยใช้ตัวล็อคแบบ "อ่อน"

TRANSACTIONAL : ออบเจ็กต์เปลี่ยนแปลงโดยใช้ธุรกรรม XA แบบกระจายเพื่อให้มั่นใจว่าข้อมูลมีความสมบูรณ์ สิ่งนี้รับประกันความสำเร็จทั้งหมดหรือย้อนกลับการเปลี่ยนแปลงทั้งหมด ในทั้งสี่กรณีนี้การอัปเดตรายการฐานข้อมูลเดียวจะไม่ทำให้รายชื่อลูกค้าทั้งหมดในแคชเป็นโมฆะ ไฮเบอร์เนตฉลาดกว่านั้นเล็กน้อย :)

หากต้องการเรียนรู้เพิ่มเติมเกี่ยวกับวิธีการทำงานของแคช L2 ในไฮเบอร์เนตคุณสามารถอ่านบทความ "แคช Hibernate L2 คืออะไร" หรือบทความเชิงลึกCaching in Hibernate with Redis

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