นายหน้าบริการ - อายุการสนทนาหรือไม่


9

เราพยายามให้ 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)

  1. Trigger Fires (ส่งไปยังเวลาหน่วงต่ำหรือเป็นกลุ่ม)
  2. ค้นหาหรือสร้างการจัดการการสนทนา
  3. ส่งข้อความ
  4. ขั้นตอนการเปิดใช้งานคิว
  5. อัปเดตตารางผลลัพธ์

กระบวนการล้างข้อมูลจะทำงานทุก ๆ 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 ชั่วโมง

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


1
we started seeing blocks and high contention on sysdesend and the queue table.-> ประเภทการรอ - PAGELATCH_EX/SH and WRITELOGคืออะไร คุณใช้เคล็ดลับ 150 ข้อแล้วหรือยัง? หากตารางระบบเป็นจุดโต้แย้งของคุณ 150 เคล็ดลับจะเป็นประโยชน์อย่างมาก
Kin Shah

@kin ฉันได้อัปเดตคำถามแล้ว แต่ประเภทการล็อคคือ LCK_M_U หรือ LCK_M_X ฉันได้อ่านเกี่ยวกับ 150 เคล็ดลับ แต่หวังว่ามันไม่จำเป็นในปี 2559 (เนื่องจากพวกเขาแก้ไขปัญหาการรั่วของ tempdb ด้วย) แต่ก็เพราะดูเหมือนว่าแฮ็คดังกล่าว เราจะทำการแทงอีกครั้งในการผลิต (เราเศร้าเพียงแค่พบสิ่งนี้กับปริมาณงานการผลิต) และจะลองบทสนทนาสั้น ๆ ตลอดชีวิตก่อน ฉันจะอัปเดตที่นี่พร้อมผลการค้นหา ถัดไปจะเป็น 150 เคล็ดลับที่คุณอ้างถึง
Jonathan Fite

ฉันได้ถาม@RemusRusanuบน Twitter - เขาเป็นผู้เชี่ยวชาญในเรื่องนายหน้าบริการ :-)
Kin Shah

นี่ไม่ใช่สิ่งที่ฉันเคยเห็นมาก่อน (การสลายตัวของ SEND หลังจากใช้เวลานาน) 1) โปรดบอกฉันว่าจำนวนแถวในsys.conversation_endpointsระหว่างการทดสอบคืออะไร (ค่าคงที่หรือเพิ่มขึ้นและขนาดใหญ่ขึ้นเมื่อการบล็อคเกิดขึ้น) 2) เมื่อการบล็อคเกิดขึ้นการปิดใช้งานคิวเป้าหมายจะสร้างความแตกต่างในการบล็อก SEND (การปิดใช้งานคิวควรจัดเส้นทาง SEND ไปยัง sys.transmission_queue) และ 3) การบังคับให้ข้อความไปที่สายแม้ในเครื่อง (ตั้งค่าจุดสิ้นสุด SSB เพิ่มเส้นทาง) เปลี่ยนพฤติกรรมในระยะยาว
Remus Rusanu

ความคิดเพิ่มเติม: 4) เมื่อการบล็อกเกิดขึ้นการหยุด RECEIVE บนเป้าหมายจะสร้างความแตกต่าง (ปิดใช้งาน proc ที่เปิดใช้งานถ้ามี) และ 5) มีจำนวนโกสต์ผีในคิวเป้าหมายหรือไม่ การใช้งานALTER QUEUE ... REBUILDสร้างความแตกต่างเมื่อการบล็อกเริ่มขึ้นหรือไม่
Remus Rusanu

คำตอบ:


3

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

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

ตอนแรกเรามีทริกเกอร์ที่ทำเคอร์เซอร์เหนือบันทึกที่ถูกแก้ไขในทุก ๆ คำสั่ง update / insert (ควรเป็นหนึ่งแถวในกรณีส่วนใหญ่) และส่งคีย์หลักแต่ละอันในข้อความไปยังนายหน้าบริการ นายหน้าบริการภายในโดยเฉพาะคิวจำนวนมากเป็นเคอร์เซอร์เพิ่มเติมซึ่งดำเนินการขั้นตอนการเพิ่มยอดสำหรับรายงาน (การดำเนินการหนึ่งครั้งต่อคีย์หลัก)

สิ่งที่ทำให้เราทำงานได้ในที่สุด:

  • เราลบเคอร์เซอร์และตัดสินในการส่งข้อความขนาดใหญ่ ยังคงมีข้อความหนึ่งข้อความต่อธุรกรรมของผู้ใช้ต่อตาราง แต่ตอนนี้เราส่งข้อความที่มีคีย์หลักมากกว่าหนึ่งรายการ

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

  • ตารางที่มีความผันผวนมากที่สุด (ตารางข้อมูลอุปกรณ์มือถือของเรา) มีการเรียกทริกเกอร์ เราอัปเดตขั้นตอนการอัพเพิร์ตเพื่อรวมคีย์ต่างประเทศที่เหมาะสมและตอนนี้เราเพิ่งเข้าร่วมในตารางนั้นเมื่อดึงผลลัพธ์ให้ผู้ใช้ ตารางนี้มีส่วนร่วม 80% ของข้อความที่เราต้องดำเนินการในหนึ่งวัน

เราประมวลผลข้อความประมาณ 1M ต่อวัน (โดยไม่มีตารางมือถือ) และส่วนใหญ่ (99% +) ของข้อความของเราจะถูกประมวลผลภายในวัตถุประสงค์ของเรา เรายังคงมีค่าผิดปกติเป็นครั้งคราว แต่ได้รับลักษณะที่หายากของที่ถือว่าเป็นที่ยอมรับ

ปัจจัยสนับสนุน:

  • ฉันพบข้อผิดพลาดในขั้นตอนการล้างข้อมูลการสนทนาที่กล่าวถึงก่อนหน้านี้ซึ่งไม่ได้ทำความสะอาดการสนทนาอย่างเหมาะสมและสิ้นสุดก่อนกำหนด ตอนนี้สิ่งนี้ส่งผลให้จำนวน sysdesend ของเราไม่เกินสองสามพัน (ส่วนใหญ่มาจากการใช้ 150 เคล็ดลับ)

  • เคอร์เซอร์ในทริกเกอร์ดูเหมือนว่าจะล็อคมากกว่าที่คาดไว้ (แม้จะมีแบบคงที่, forward_only) การลบสิ่งที่ดูเหมือนจะทำให้ล็อคที่เราเห็นใน SEND CONVERSATION มีลักษณะชั่วคราวมากขึ้น (หรืออย่างน้อยเวลาที่เราเห็นนั้นต่ำกว่ามาก)

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

ข้อดีอีกประการหนึ่งคือการเปิดโปงปัญหา Ghost Record Cleanup และในขณะที่มันไม่ได้อยู่ในตาราง Service Broker (ระบบหรือคิว) มันค่อนข้างอาละวาดในระบบของเราและอาการต่าง ๆ เข้ากันได้ดีกับ "ไม่มีสาเหตุชัดเจน" ปัญหาที่เราพบในบางครั้ง การตรวจสอบอย่างต่อเนื่องนั้นเรากำลังพยายามหาตารางที่มีส่วนร่วมและเราอาจจะสร้างดัชนีของพวกเขาเป็นประจำ

ขอบคุณอีกครั้ง.


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