Ми намагаємось змусити Сервісного брокера працювати в нашому середовищі для вирішення ділової справи. Я не знаю, чи хороша назва повідомлення, але моє питання нижче. Але це може бути не надто хорошим питанням, тому після цього ми робимо те, чому я вважаю, що це правильне питання.
Скільки повідомлень слід надіслати на розмову, перш ніж закінчити розмову?
Ми хочемо скористатися Service Broker для асинхронного оновлення таблиці результатів. Таблиця результатів вирівняна і швидка. У базових таблицях є тригери, які надсилають повідомлення зі своєю таблицею та первинним ключем. У нас три черги:
- Низька затримка - ціль - 15 секунд для обробки. Він обробляє елементи, які змінюються стосовно певного предмета.
- Об'ємна черга - обробка полягає в 5 хвилин. Він обробляє, коли щось змінюється, що впливає на багато сотень (або тисяч) предметів. Він розбиває список предметів, на які постраждали, і подає їх до черги із відкладеною низькою затримкою
- Відкладена низька затримка - ціль - 30 хвилин для обробки. Це обробляє елементи, але тільки з масової черги.
В основному, якщо інформація клієнта оновлюється; що впливає на багато продуктів, тому надсилається до масової черги для повільнішої обробки. Однак, якщо продукт оновлюється, він надсилається до черги з низькою затримкою.
Ми повторно використовуємо розмови, подібні до блогу Ремуса Русану http://rusanu.com/2007/04/25/reusing-conversations/ , за винятком того, що ми робимо це на основі модуля первинного ключа. Це має побічну перевагу в наданні допомоги в дедублюванні первинного ключа.
Таким чином, ми повторно використовуємо бесіди і перебуваємо в межах наших рекомендацій. За допомогою двох потоків я зміг пропустити 125 повідомлень / секунду (штучне падіння декількох тисяч повідомлень), що більш ніж здатне йти в ногу з виробництвом (приблизно 15 повідомлень / сек).
Однак проблема, з якою ми стикаємося, полягає в тому, що через певний проміжок часу, ~ 4 години або 120K повідомлень, ми почали бачити блоки та великі суперечки в Sysdesend та таблиці черг. Замки мають LCK_M_U і є ключами KEY. Іноді hobt вирішується до sysdesend, а в інший раз конкретної таблиці черг (queue_).
У нас є процес, який закінчить розмови вже через 24 години або 30 хвилин бездіяльності, тому ми могли просто збільшити час, перш ніж переходити до розмов.
Ми використовуємо SQL 2016 Enterprise (13.0.4001.0)
- Тригерні пожежі (надіслати або з низькою затримкою, або з масовою)
- Знайдіть або створіть ручку для розмови.
- відправити повідомлення
- Процедура, що активується в черзі
- Оновіть таблицю результатів
Процес очищення запускається кожні 10 хвилин, щоб перевірити, чи є бесіди в режимі очікування. якщо він знаходить їх більше трьох разів поспіль, він позначає це як неактивні і закінчує розмови.
Будь ласка, дайте мені знати, чи є якісь додаткові деталі, які можуть бути корисними. Я не маю великого досвіду роботи з Service Broker, тому не знаю, чи є наші повідомлення / сек низькими, високими чи байдужими.
ОНОВЛЕННЯ
Тому ми сьогодні спробували знову і зіткнулися з тією ж проблемою. Ми змінили життя розмови на 2 години, і це не мало ефекту. Тож ми реалізували трюк 150; які мали те саме питання.
Тон чекає на НАДІСЛОВУ ПОВЕРНЕННЯ, чекаючи на sysdesend. Хтось має якісь подальші ідеї?
ОНОВЛЕННЯ 2
Сьогодні ми провели тест довше, і за один із 17-ти типових періодів ми обробили 41K повідомлень на 4-х ручках для розмови. Нам вдалося не відставати, окрім кінця, коли замків на Sysdesend та таблиці черг стало занадто багато, і ми почали відходити перед тим, як зупинити його. У нас, здається, немає проблем з обробкою повідомлень, без речей, що потрапляють у чергу, ми можемо витягнути їх та обробити їх принаймні 5 разів із такою швидкістю. Здається, наша швидкість обмежена на основі додавання повідомлень.
На пізньому тесті ми видалили один з тригерів, на який припадало 80% повідомлень. Навіть при цьому значно зниженому навантаженні ми почали бачити однакові очікування.
ОНОВЛЕННЯ 3
Дякую, Ремус за пораду (і дякую, що ви опублікували такі чудові статті в блозі на цю тему, вони допомогли досягти цієї мети).
Ми побігли це сьогодні сьогодні і зробили краще (як ми пішли довше, перш ніж побачити очікування і навіть довше, перш ніж це покалічило нас). Отже, деталі.
Ми змінили: * Збільшено кількість підтримуваних розмов на потоку з 1: 1 до 2: 1. В основному у нас було 8 ручок для розмов на 4 теми.
- консолідована об'ємна черга (оскільки одне вхідне повідомлення може означати сотні вихідних повідомлень) для консолідації в меншу кількість більших повідомлень.
Примітки щодо цієї спроби:
відключення процедури активації цільової черги. жодних змін у блокуванні (ми чекали 5 хвилин), і повідомлення надійшли на sys.transmission_queues.
моніторинг sys.conversation_endpoints. Це число швидко зросло від 0 13K, а потім повільніше зростало протягом дня, закінчуючи приблизно 25K через ~ 5 годин. Блокування не почалося, поки воно не досягло 16K +/-
Я зайшов у ЦАП і запустив команди 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 буде дуже корисною.