เราพยายามให้ Service Broker ทำงานในสภาพแวดล้อมของเราเพื่อแก้ไขปัญหาทางธุรกิจ ฉันไม่รู้ว่าชื่อข้อความนั้นดีหรือไม่ แต่คำถามของฉันอยู่ด้านล่าง แต่มันอาจไม่ใช่คำถามที่ดีดังนั้นหลังจากนั้นคือสิ่งที่เรากำลังทำอยู่และทำไมฉันจึงคิดว่ามันเป็นคำถามที่ถูกต้อง
ควรส่งข้อความในการสนทนากี่ข้อความก่อนที่จะสิ้นสุดการสนทนา
เราต้องการใช้ Service Broker เพื่ออัพเดทตารางผลลัพธ์แบบอะซิงโครนัส ตารางผลลัพธ์แบนและรวดเร็ว เรามีทริกเกอร์ในตารางฐานที่ส่งข้อความพร้อมกับตารางและคีย์หลัก เรามีสามคิว:
- เวลาตอบสนองต่ำ - เป้าหมายคือ 15 วินาทีในการประมวลผล มันจัดการรายการที่เปลี่ยนแปลงที่เกี่ยวข้องกับรายการที่เฉพาะเจาะจง
- คิวจำนวนมาก - วัตถุประสงค์คือ 5 นาทีในการดำเนินการ มันจัดการเมื่อมีการเปลี่ยนแปลงบางอย่างที่มีผลต่อหลายร้อย (หรือหลายพัน) รายการ มันแบ่งรายชื่อของรายการที่ได้รับผลกระทบและฟีดพวกเขาไปยังคิวเวลาแฝงต่ำรอการตัดบัญชี
- เวลารอตอบสนองต่ำรอการตัดบัญชี - วัตถุประสงค์คือ 30 นาทีในการดำเนินการ สิ่งนี้จะประมวลผลรายการ แต่จากคิวจำนวนมากเท่านั้น
โดยทั่วไปหากข้อมูลของลูกค้าอัพเดท ที่มีผลต่อผลิตภัณฑ์จำนวนมากเพื่อให้ส่งไปยังคิวจำนวนมากเพื่อการประมวลผลที่ช้าลง อย่างไรก็ตามหากผลิตภัณฑ์ได้รับการอัพเดตผลิตภัณฑ์นั้นจะถูกส่งไปยังคิวเวลาแฝงต่ำ
เราใช้การสนทนาที่คล้ายกับบล็อกของ Remus Rusanu อีกครั้งhttp://rusanu.com/2007/04/25/reusing-conversations/ยกเว้นว่าเราดำเนินการตามโมดูลัสของคีย์หลัก สิ่งนี้มีประโยชน์ด้านการช่วยเหลือในการทำซ้ำของคีย์หลัก
ดังนั้นเราจึงใช้การสนทนาอีกครั้งและอยู่ในหลักเกณฑ์ของเรา ด้วยสองเธรดฉันสามารถเขียนข้อความถึง 125 ข้อความ / วินาที (หยดเทียมหลายพันข้อความ) ซึ่งมากกว่าความสามารถในการติดตามการผลิต (ประมาณ 15 ข้อความ / วินาที)
อย่างไรก็ตามปัญหาที่เราประสบคือหลังจากช่วงระยะเวลาหนึ่งข้อความ ~ 4 ชั่วโมงหรือ 120K เราเริ่มเห็นการบล็อกและการช่วงชิงสูงใน sysdesend และคิวคิว ล็อคคือ LCK_M_U และเป็นกุญแจล็อค บางครั้ง hobt แก้ไขเป็น sysdesend และอื่น ๆ ในตารางคิวเฉพาะ (queue_)
เรามีกระบวนการที่จะสิ้นสุดการสนทนาหลังจากที่ไม่มีกิจกรรมใด ๆ เป็นเวลา 24 ชั่วโมงหรือ 30 นาทีดังนั้นเราจึงสามารถเพิ่มเวลาก่อนที่จะขี่บทสนทนา
เรากำลังใช้ SQL 2016 Enterprise (13.0.4001.0)
- Trigger Fires (ส่งไปยังเวลาหน่วงต่ำหรือเป็นกลุ่ม)
- ค้นหาหรือสร้างการจัดการการสนทนา
- ส่งข้อความ
- ขั้นตอนการเปิดใช้งานคิว
- อัปเดตตารางผลลัพธ์
กระบวนการล้างข้อมูลจะทำงานทุก ๆ 10 นาทีเพื่อดูว่ามีการสนทนาว่างหรือไม่ หากพบว่ามีมากกว่าสามครั้งติดต่อกันจะทำเครื่องหมายว่าไม่ใช้งานและสิ้นสุดการสนทนา
โปรดแจ้งให้เราทราบหากมีรายละเอียดเพิ่มเติมใด ๆ ที่อาจเป็นประโยชน์ ฉันไม่มีประสบการณ์มากกับ Service Broker ดังนั้นฉันไม่รู้ว่าข้อความ / วินาทีของเราต่ำ, สูงหรือไม่แยแส
UPDATE
ดังนั้นเราจึงลองอีกครั้งในวันนี้และพบปัญหาเดียวกัน เราเปลี่ยนอายุการสนทนาเป็น 2 ชั่วโมงและไม่มีผลใด ๆ ดังนั้นเราจึงใช้ 150 เคล็ดลับ; ซึ่งมีปัญหาเดียวกัน
ตันรอการส่งการแปลงรอ sysdesend ไม่มีใครมีความคิดเพิ่มเติมหรือไม่
อัพเดท 2
เราวิ่งทดสอบนานขึ้นในวันนี้และหนึ่งในช่วงเวลาตัวอย่าง 17 นาทีเราประมวลผลข้อความ 41K ในการจัดการการสนทนา 4 รายการ เราสามารถติดตามได้จนกว่าจะถึงจุดจบเมื่อล็อกบน sysdesend และตารางคิวมากเกินไปและเราเริ่มดริฟท์ก่อนที่จะหยุดมัน ดูเหมือนว่าเราจะไม่มีปัญหาในการประมวลผลข้อความหากไม่มีสิ่งใดเข้ามาในคิวเราสามารถดึงมันออกและประมวลผลอย่างน้อย 5x ความเร็วนั้น ความเร็วของเราดูเหมือนจะถูก จำกัด ตามการเพิ่มข้อความ
ในการทดสอบในภายหลังเราลบหนึ่งในทริกเกอร์ซึ่งคิดเป็น 80% ของข้อความ แม้ว่าภาระที่ลดลงนี้เราก็เริ่มเห็นการรอคอยเหมือนกัน
อัพเดท 3
ขอขอบคุณรีมัสสำหรับคำแนะนำของคุณ (และขอขอบคุณสำหรับการโพสต์บทความบล็อกที่ยอดเยี่ยมเช่นนี้ในหัวข้อเรื่องพวกเขามีส่วนช่วยในจุดนี้)
เราวิ่งได้อีกครั้งในวันนี้และทำได้ดีกว่า (เช่นเดียวกับที่เราไปนานกว่าก่อนที่จะเห็นการรอคอยและอีกต่อไปก่อนที่มันจะทำให้เราพิการ) ดังนั้นรายละเอียด
เราเปลี่ยน: * เพิ่มจำนวนการสนทนาที่คงไว้ต่อเธรดจาก 1: 1 เป็น 2: 1 โดยทั่วไปเรามี 8 การสนทนาที่จัดการสำหรับ 4 กระทู้
- รวมคิวจำนวนมาก (เนื่องจากข้อความขาเข้าหนึ่งข้อความอาจหมายถึงข้อความขาออกหลายร้อยรายการ) เพื่อรวมเป็นข้อความที่น้อยกว่าและมีขนาดใหญ่กว่า
หมายเหตุเกี่ยวกับความพยายามนี้:
ปิดใช้งานขั้นตอนการเปิดใช้งานคิวเป้าหมาย ไม่มีการเปลี่ยนแปลงในการบล็อก (เรารอ 5 นาที) และข้อความได้ถูกส่งไปยัง sys.transmission_queues
การมอนิเตอร์ sys.conversation_endpoints จำนวนนี้เพิ่มขึ้นจาก 0 13K อย่างรวดเร็วจากนั้นเพิ่มขึ้นช้ากว่าตลอดทั้งวันซึ่งสิ้นสุดประมาณ 25K หลังจาก ~ 5 ชั่วโมง การบล็อกไม่เริ่มเกิดขึ้นจนกว่าจะถึง 16K +/-
ฉันเข้าไปใน DAC และรันคำสั่ง DBREINDEX สำหรับคิวแม้ว่าจะมีคิวรีเรคคอร์ดผีไม่เคยสูงกว่า 200 หรือมากกว่านั้นก่อนที่การล้างข้อมูลจะมาและลดจำนวนเป็น 0
sysdesend และ sysdercv มีจำนวนเหมือนกัน 24,932 เมื่อฉันสิ้นสุดการทดสอบ
เราประมวลผลข้อความ ~ 310K ใน 5 ชั่วโมง
เราไปนานก่อนที่สิ่งต่าง ๆ จะพังทลายซึ่งฉันคิดว่าเราจะทำให้มันเป็นจริงในครั้งนี้ พรุ่งนี้เราจะพยายามบังคับให้ข้อความผ่านสาย
sys.conversation_endpoints
ระหว่างการทดสอบคืออะไร (ค่าคงที่หรือเพิ่มขึ้นและขนาดใหญ่ขึ้นเมื่อการบล็อคเกิดขึ้น) 2) เมื่อการบล็อคเกิดขึ้นการปิดใช้งานคิวเป้าหมายจะสร้างความแตกต่างในการบล็อก SEND (การปิดใช้งานคิวควรจัดเส้นทาง SEND ไปยัง sys.transmission_queue) และ 3) การบังคับให้ข้อความไปที่สายแม้ในเครื่อง (ตั้งค่าจุดสิ้นสุด SSB เพิ่มเส้นทาง) เปลี่ยนพฤติกรรมในระยะยาว
ALTER QUEUE ... REBUILD
สร้างความแตกต่างเมื่อการบล็อกเริ่มขึ้นหรือไม่
we started seeing blocks and high contention on sysdesend and the queue table.
-> ประเภทการรอ -PAGELATCH_EX/SH and WRITELOG
คืออะไร คุณใช้เคล็ดลับ 150 ข้อแล้วหรือยัง? หากตารางระบบเป็นจุดโต้แย้งของคุณ 150 เคล็ดลับจะเป็นประโยชน์อย่างมาก