Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Redis

การเรียนรู้ระบบล็อคแบบกระจาย Redis:รูปแบบที่ได้รับการพิสูจน์แล้ว ข้อผิดพลาดทั่วไป และการใช้งานจริง

การเรียนรู้ระบบล็อคแบบกระจาย Redis:รูปแบบที่ได้รับการพิสูจน์แล้ว ข้อผิดพลาดทั่วไป และการใช้งานจริง

บทนำ

การล็อคแบบกระจายฟังดูเรียบง่ายจนกว่าคุณจะพึ่งพาการล็อคเหล่านี้ในการใช้งานจริง

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

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

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

การล็อคแบบกระจายจริงๆ คืออะไร

การล็อคแบบกระจายไม่เหมือนกับ mutex ในหน่วยความจำ ไม่ได้รับประกันโดยสมบูรณ์ และไม่สามารถขจัดความล้มเหลวได้

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

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

ขั้นตอนแรกในการใช้ Redis lock อย่างปลอดภัยคือการปรับความคาดหวัง

เมื่อ Redis Lock สมเหตุสมผล

การล็อคแบบกระจาย Redis มีความเหมาะสมเมื่อ:

  • คุณต้องป้องกันการดำเนินการส่วนสำคัญพร้อมกัน

  • งานต้องได้รับการประสานงานข้ามเซิร์ฟเวอร์หลายเครื่อง

  • การดำเนินการมีอายุสั้น

  • การลองใหม่เป็นที่ยอมรับ

กรณีการใช้งานทั่วไป ได้แก่ การขจัดความซ้ำซ้อนของงาน การประสานงานงานตามกำหนดเวลา การสร้างแคชใหม่ และการป้องกันการประมวลผลซ้ำซ้อน

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

ระบบล็อคแบบปลอดภัยเพียงรุ่นเดียวใน Redis

วิธีดั้งเดิมในการล็อก Redis ที่ปลอดภัยที่สุดคือคำสั่งอะตอมมิกคำสั่งเดียว:

ตั้งค่าคีย์ NX EX ttl

คำสั่งนี้สร้างการล็อคเฉพาะในกรณีที่ยังไม่มีอยู่ กำหนดค่าเจ้าของที่ไม่ซ้ำกัน และตั้งค่า TTL เพื่อให้การล็อคหมดอายุโดยอัตโนมัติ

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

เหตุใดจึงต้องล็อค TTL

หากไม่มี TTL ล็อค Redis จะคงอยู่ตลอดไป หากกระบวนการล้มเหลวในขณะที่ล็อคไว้ ระบบจะหยุดทำงานอย่างเงียบ ๆ

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

ล็อคที่ไม่มีวันหมดอายุนั้นอันตรายมากกว่าการล็อคเลย

ล็อคการเป็นเจ้าของและการปล่อยอย่างปลอดภัย

การล็อค Redis จะต้องปลดล็อคโดยกระบวนการที่ได้มาเท่านั้น นี่คือสาเหตุที่ค่าล็อคควรเป็นตัวระบุที่ไม่ซ้ำกัน ไม่ใช่สตริงคงที่

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

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

การเลือกระยะเวลาล็อคแบบปลอดภัย

การล็อก TTL ต้องเกินเวลาดำเนินการสูงสุดที่คาดไว้ของการดำเนินการที่ได้รับการป้องกัน การใช้เวลาดำเนินการโดยเฉลี่ยไม่เพียงพอ

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

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

การทำให้งานที่ถูกล็อกมีขนาดเล็กและมีขอบเขตเป็นแนวทางที่ปลอดภัยที่สุด

ล็อคส่วนขยายและฮาร์ทบีท

การดำเนินการบางอย่างใช้เวลานานกว่าที่คาดไว้ สามารถขยายการล็อคโดยการรีเฟรช TTL เป็นระยะๆ ได้ แต่จะเพิ่มความซับซ้อนและโหมดความล้มเหลวใหม่

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

ในหลายกรณี การออกแบบงานใหม่เป็นชิ้นเล็กๆ จะปลอดภัยกว่าการใช้ตรรกะส่วนขยายการล็อค

การอภิปราย Redlock

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

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

หากจำเป็นต้องมีการรับประกันระดับ Redlock Redis อาจไม่ใช่เครื่องมือที่เหมาะสม ฐานข้อมูลที่มีการล็อกธุรกรรมหรือระบบประสานงานเฉพาะทางอาจเหมาะสมกว่า

สำหรับกรณีการใช้งาน Redis ส่วนใหญ่ อินสแตนซ์ Redis เดี่ยวที่มีการล็อกแบบ TTL ที่เหมาะสมก็เพียงพอแล้ว

การล็อคไม่ใช่การทำธุรกรรม

การล็อค Redis ไม่ทำให้การดำเนินการเป็นธุรกรรม พวกเขาไม่ได้ให้การย้อนกลับอัตโนมัติหรือรับประกันความสม่ำเสมอเมื่อเกิดความล้มเหลวระหว่างการทำงาน

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

หลักการออกแบบนี้ช่วยลดความเสี่ยงของข้อบกพร่องที่เกี่ยวข้องกับการล็อคได้อย่างมาก

จะเกิดอะไรขึ้นเมื่อ Redis ลงไป

เมื่อ Redis หยุดทำงานหรือรีสตาร์ท การล็อคทั้งหมดจะหายไป นี่คือลักษณะการทำงานที่คาดหวัง

เมื่อ Redis กลับมาออนไลน์ กระบวนการต่างๆ อาจได้รับการล็อคพร้อมกันและเริ่มทำงาน ระบบจะต้องยอมรับความเป็นไปได้นี้

หากการสูญเสียการล็อคระหว่างการรีสตาร์ท Redis ทำให้เกิดความเสียหาย การออกแบบการล็อคจะไม่ปลอดภัยและจำเป็นต้องได้รับการพิจารณาใหม่

การตรวจสอบล็อคในการผลิต

ล็อค Redis ไม่ควรมองไม่เห็น ทีมควรตรวจสอบจำนวนการล็อคที่มีอยู่ ระยะเวลาที่ใช้ และความถี่ในการรับการล็อคที่ล้มเหลว

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

การมองเห็นเป็นสิ่งจำเป็นสำหรับการทำงานที่ปลอดภัย

รูปแบบการป้องกัน Redis Lock ทั่วไป

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

รูปแบบการต่อต้านเหล่านี้ปรากฏบ่อยครั้งในการหยุดทำงานของการผลิตในโลกแห่งความเป็นจริง

รายการตรวจสอบการล็อคที่ใช้งานได้จริง

การใช้งานการล็อก Redis ที่ปลอดภัยประกอบด้วย:

  • ล็อคกุญแจด้วย TTLs

  • ค่าความเป็นเจ้าของล็อคเฉพาะ

  • การยืนยันความเป็นเจ้าของเมื่อเผยแพร่

  • ส่วนสำคัญที่มีอายุสั้น

  • การดำเนินการที่ไม่มีประสิทธิภาพ

  • เส้นทางความล้มเหลวที่ทดสอบแล้ว

หากขาดหายไป ควรพิจารณาการออกแบบตัวล็อคใหม่

แบบจำลองทางจิตที่ดีต่อสุขภาพสำหรับ Redis Locks

ระบบล็อค Redis คือเข็มขัดนิรภัย ไม่ใช่ถุงลมนิรภัย ลดความเสียหายแต่ไม่ได้ป้องกันอุบัติเหตุทั้งหมด

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

สรุป

การล็อคแบบกระจายทำได้ยากเนื่องจากความล้มเหลวเป็นสิ่งที่หลีกเลี่ยงไม่ได้ Redis มีกลไกการล็อคที่รวดเร็ว เรียบง่าย และใช้งานได้จริง ไม่ใช่กลไกที่สมบูรณ์แบบ

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