วิธีการนำคิวข้อความไปใช้กับ Redis


29

ทำไม Redis ถึงเข้าคิว?

ฉันอยู่ภายใต้ความประทับใจที่ Redis สามารถสร้างผู้สมัครที่ดีสำหรับการนำระบบคิวเข้ามาใช้ จนถึงตอนนี้เราได้ใช้ฐานข้อมูล MySQL กับโพลหรือ RabbitMQ ด้วย RabbitMQ เรามีปัญหามากมาย - ห้องสมุดลูกค้านั้นแย่มากและบั๊กกี้และเราไม่ต้องการลงทุนชั่วโมงนักพัฒนามากเกินไปในการแก้ไขปัญหาเหล่านี้ปัญหาบางอย่างเกี่ยวกับคอนโซลการจัดการเซิร์ฟเวอร์ ฯลฯ และในเวลานั้น อย่างน้อยเราก็ไม่ได้จับเป็นมิลลิวินาทีหรือผลักดันประสิทธิภาพอย่างจริงจังดังนั้นตราบใดที่ระบบมีสถาปัตยกรรมที่รองรับคิวอย่างชาญฉลาดเราอาจมีรูปร่างที่ดี

ตกลงนั่นคือพื้นหลัง โดยพื้นฐานแล้วฉันมีโมเดลคิวที่เรียบง่ายคลาสสิกผู้ผลิตหลายรายผลิตงานและบริโภคผู้บริโภคจำนวนมากและทั้งผู้ผลิตและผู้บริโภคต้องสามารถปรับขนาดได้อย่างชาญฉลาด ปรากฎว่าไร้เดียงสาPUBSUBไม่ทำงานเนื่องจากฉันไม่ต้องการให้สมาชิกทั้งหมดใช้งานฉันแค่ต้องการสมาชิกหนึ่งคนเพื่อรับงาน ที่ผ่านครั้งแรกมันดูเหมือนฉันชอบBRPOPLPUSHคือการออกแบบที่ชาญฉลาด

เราสามารถใช้ BRPOPLPUSH ได้หรือไม่?

การออกแบบพื้นฐานด้วยBRPOPLPUSHคือคุณมีคิวงานหนึ่งคิวและคิวความคืบหน้า เมื่อผู้บริโภคได้รับการทำงานมันอะตอมผลักดันรายการลงในคิวความคืบหน้าและเมื่อเสร็จสิ้นการทำงานมันLREMเป็นมัน สิ่งนี้จะช่วยป้องกันไม่ให้เกิดการปิดกั้นการทำงานหากลูกค้าตายและทำการตรวจสอบได้อย่างง่ายดาย - ตัวอย่างเช่นเราสามารถบอกได้ว่ามีปัญหาที่ทำให้ผู้บริโภคต้องใช้เวลานานในการปฏิบัติงานนอกเหนือจากการบอกว่ามีงานจำนวนมากหรือไม่

มันทำให้มั่นใจ

  • ส่งมอบงานให้กับผู้บริโภคเพียงรายเดียว
  • ทำงานช้าลงในคิวที่กำลังดำเนินการอยู่ดังนั้นจึงไม่สามารถปิดกั้นผู้บริโภคได้

ข้อเสียเปรียบ

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

เพิ่มแท็ก node.js ด้วยเพราะนั่นคือภาษาที่ฉันใช้เป็นหลัก โหนดอาจเสนอการทำให้เรียบง่ายบางอย่างในการดำเนินการเนื่องจากลักษณะแบบเธรดเดียวและไม่มีการปิดกั้น แต่ยิ่งไปกว่านั้นฉันใช้ไลบรารี่ node-redis และวิธีแก้ปัญหาควรหรืออาจอ่อนไหวต่อจุดแข็งและจุดอ่อนของมัน

คำตอบ:


5

หากคุณต้องการใช้ Redis สำหรับคิวข้อความใน Node.js และคุณไม่สนใจใช้โมดูลสำหรับสิ่งนั้นคุณอาจลองRSMQ - Redis Simple Message Queue สำหรับโหนด ไม่สามารถใช้งานได้ในเวลาที่คำถามนี้ถูกถาม แต่วันนี้มันเป็นตัวเลือกที่ทำงานได้

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

ดู:


ฉันจะยอมรับสิ่งนี้หากฉันไม่ได้เรียนรู้ในภายหลังว่ามันมีข้อบกพร่องหรือแตกหักหรือบางสิ่งบางอย่างในภายหลัง
djechlin

22

ฉันพบปัญหาบางอย่างแล้วในตอนนี้ฉันต้องการเอกสารที่นี่

คุณจะจัดการตรรกะการเชื่อมต่อใหม่ได้อย่างไร?

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

นอกจากนี้การดำเนินการฟังควรง่ายที่สุด เป็นการดีที่ควรมีคุณสมบัติเหล่านี้:

  • การฟังคือ idempotent
  • ผู้บริโภคกำลังฟังอยู่เสมอและตรรกะการควบคุมปริมาณจะถูกประมวลผลภายนอกรหัสฟังการฟัง RabbitMQ ห่อหุ้มสิ่งนี้โดยการให้ผู้ใช้เชื่อมโยงจำนวนข้อความที่ไม่ได้รับมันที่มี
    โดยเฉพาะอย่างยิ่งฉันไปกับการออกแบบที่ไม่ดีซึ่งการที่ป๊อปอัพบล็อกเข้ามาใหม่นั้นขึ้นอยู่กับความสำเร็จของการปฏิบัติการก่อนหน้านี้ซึ่งเปราะบางและต้องใช้ความคิดอย่างหนัก

ตอนนี้ฉันนิยมใช้โซลูชัน Redis PUBSUB + RPOPLPUSH decouples นี้แจ้งเตือนการทำงานจากการใช้งานซึ่งช่วยให้เราแยกตัวเลือกโซลูชั่นการฟังที่สะอาด PUBSUB รับผิดชอบต่อการแจ้งเตือนการทำงานเท่านั้น ธรรมชาติของ RPOPLPUSH มีความรับผิดชอบต่อการบริโภคและการมอบหมายงานให้กับผู้บริโภคเพียงรายเดียว ในตอนแรกโซลูชันนี้ดูเหมือนซับซ้อนโดยไม่จำเป็นเมื่อเทียบกับป๊อปบล็อก แต่ตอนนี้ฉันเห็นแล้วว่าภาวะแทรกซ้อนไม่จำเป็นเลย มันเป็นการแก้ปัญหาที่ยาก

อย่างไรก็ตามวิธีการแก้ปัญหานี้ไม่ได้ค่อนข้างสำคัญ:

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

โปรดทราบว่าการออกแบบ PUBSUB / RPOPLPUSH ยังมีปัญหาการปรับขนาด ผู้บริโภคทุกคนได้รับการแจ้งเตือนเบาของทุกข้อความซึ่งหมายความว่าสิ่งนี้มีปัญหาคอขวดที่ไม่จำเป็น ฉันคิดว่าเป็นไปได้ที่จะใช้ช่องทางในการทำงาน แต่นี่อาจเป็นการออกแบบที่ยุ่งยาก


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

9
ฉันอยากรู้ว่าคุณมาไกลแค่ไหนตั้งแต่เดือนสิงหาคมปีที่แล้ว คุณสามารถแก้ปัญหาเพื่อความพึงพอใจของคุณได้หรือไม่? คุณแก้ปัญหาพวกเขาอย่างไร
AaronM

3
AAA: เหมือนกับ @AaronM ฉันชอบที่จะได้ยินว่าคุณก้าวหน้าอย่างไร
bjornl

ตกลง สิ่งนี้ก้าวหน้าไปได้อย่างไร? ฉันชอบความคิดในการลบ RabbitMQ ออกจากสแต็กและใช้ Redis ที่มีอยู่แล้ว ปัญหาของฉันคือวิธีการลงทะเบียนผู้บริโภคโดยใช้ RSMQ (node ​​lib)
ra9r

@raiglstorfer ยังไม่ได้ทำงานอยู่ที่นั่นเป็นเวลาสองปี: P รู้สึกฟรีเพื่อการวิจัยและการโพสต์ ...
djechlin

0

ดังนั้นเหตุผลที่ดีที่สุดสำหรับการเลือกใช้ RabbitMQ ผ่าน Redis คือสถานการณ์ความล้มเหลวและการรวมกลุ่ม

บทความนี้จะอธิบายได้ดีที่สุดดังนั้นฉันจะให้ลิงค์:

https://aphyr.com/posts/283-jepsen-redis

Sentinel Redis และ Redis Clustering เมื่อเร็ว ๆ นี้ไม่สามารถจัดการกับสถานการณ์ความล้มเหลวขั้นพื้นฐานจำนวนมากซึ่งทำให้เป็นตัวเลือกที่ไม่ดีสำหรับคิว

RabbitMQ มีปัญหาของตัวเองอย่างไรก็ตามมันบอกว่ามันมีความมั่นคงในการผลิตและเป็นคิวข้อความที่ดี

นี่คือโพสต์สำหรับกระต่าย:

https://aphyr.com/posts/315-jepsen-rabbitmq

เมื่อคุณดูที่ CAP theorum (ความสอดคล้องความพร้อมใช้งานและการจัดการพาร์ติชัน) คุณสามารถเลือก 2 จาก 3 เท่านั้นเราใช้ประโยชน์จาก RMQ สำหรับ CP (ความสอดคล้องและการจัดการพาร์ติชัน) ด้วยการโหลดข้อความของเราหากเราไม่พร้อมใช้งาน จุดสิ้นสุดของโลก เพื่อไม่ให้สูญเสียข้อความเราใช้ละเว้นการจัดการพาร์ติชันเพื่อไม่ให้สูญเสียข้อความ สามารถทำสำเนาซ้ำได้เนื่องจากแหล่งที่มาจัดการ UUID

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