Staramy się, aby Service Broker działał w naszym środowisku, aby rozwiązać przypadek biznesowy. Nie wiem, czy tytuł wiadomości jest dobry, ale moje pytanie jest poniżej. Ale może to nie być dobre pytanie, więc po tym jest to, co robimy i dlaczego uważam, że jest to właściwe pytanie.
Ile wiadomości należy wysłać w rozmowie przed jej zakończeniem?
Chcemy użyć Service Brokera, aby asynchronicznie zaktualizować tabelę wyników. Tabela wyników jest spłaszczona i szybka. Mamy wyzwalacze w tabelach podstawowych, które wysyłają komunikat z ich tabelą i kluczem podstawowym. Mamy trzy kolejki:
- Niskie opóźnienie - realizacja celu trwa 15 sekund. Obsługuje elementy, które zmieniają się w odniesieniu do określonego elementu.
- Kolejka masowa - realizacja celu zajmuje 5 minut. Zajmuje się, gdy coś się zmienia, co wpływa na setki (lub tysiące) przedmiotów. Rozbija listę elementów, których dotyczy problem, i podaje je do kolejki o opóźnionym niskim opóźnieniu
- Odroczone niskie opóźnienie - realizacja celu zajmuje 30 minut. Przetwarza elementy, ale tylko z kolejki zbiorczej.
Zasadniczo, jeśli informacje klienta są aktualizowane; wpływa to na wiele produktów, dlatego jest wysyłane do kolejki zbiorczej w celu spowolnienia przetwarzania. Jeśli jednak produkt zostanie zaktualizowany, zostanie wysłany do kolejki o niskim opóźnieniu.
Ponownie wykorzystujemy rozmowy podobne do bloga Remusa Rusanu http://rusanu.com/2007/04/25/reusing-conversations/ , z tym wyjątkiem, że robimy to w oparciu o moduł klucza podstawowego. Ma to dodatkową zaletę polegającą na pomocy w usuwaniu duplikacji kluczy głównych.
Dlatego ponownie wykorzystujemy rozmowy i jesteśmy w zgodzie z naszymi wytycznymi. Dzięki dwóm wątkom udało mi się wypalić 125 wiadomości na sekundę (sztuczny spadek kilku tysięcy wiadomości), co jest więcej niż w stanie nadążyć za produkcją (szacunkowo 15 wiadomości na sekundę).
Jednak problem, z jakim się spotykamy, polega na tym, że po pewnym czasie ~ 4 godzin lub 120 000 wiadomości zaczęliśmy widzieć bloki i dużą rywalizację o sysdesend i tabelę kolejek. Zamki są LCK_M_U i są zamkami KEY. Czasami hobt decyduje się na sysdesend, a innym razem na określoną tablicę kolejek (kolejka_).
Mamy wdrożony proces, który zakończy rozmowy już po 24 godzinach lub 30 minutach bezczynności, dzięki czemu moglibyśmy po prostu wydłużyć czas przed przejściem do rozmowy.
Używamy SQL 2016 Enterprise (13.0.4001.0)
- Wyzwalanie pożarów (wysyłanie do małych opóźnień lub luzem)
- Wyszukaj lub utwórz uchwyt konwersacji.
- Wyślij wiadomość
- Procedura aktywowana w kolejce
- Zaktualizuj tabelę wyników
Proces czyszczenia jest uruchamiany co 10 minut, aby sprawdzić, czy są jakieś bezczynne rozmowy. jeśli znajdzie je więcej niż trzy razy z rzędu, oznacza to jako nieaktywne i kończy rozmowy.
Daj mi znać, jeśli są jakieś dodatkowe szczegóły, które mogą być korzystne. Nie mam dużego doświadczenia z Service Brokerem, więc nie wiem, czy nasze wiadomości / s są niskie, wysokie czy obojętne.
AKTUALIZACJA
Więc spróbowaliśmy dzisiaj jeszcze raz i napotkaliśmy ten sam problem. Zmieniliśmy czas trwania rozmowy na 2 godziny i to nie miało żadnego efektu. Więc wdrożyliśmy lewę 150; który miał ten sam problem.
Mnóstwo oczekiwań na WYŚLIJ KONWERSACJĘ, czeka na sysdesend. Czy ktoś ma jakieś dalsze pomysły?
AKTUALIZACJA 2
Dzisiaj przeprowadziliśmy test dłużej i przez jeden z przykładowych okresów 17 minut przetworzyliśmy 41 000 wiadomości na 4 uchwytach konwersacji. Byliśmy w stanie nadążyć za wyjątkiem końca, kiedy blokady na sysdesend i tabela kolejek stały się zbyt duże i zaczęliśmy dryfować z tyłu, zanim go zatrzymaliśmy. Wydaje się, że nie mamy problemu z przetwarzaniem wiadomości, bez rzeczy wchodzących do kolejki możemy je ściągnąć i przetworzyć co najmniej 5 razy szybciej. Nasza prędkość wydaje się być ograniczona w oparciu o dodawanie wiadomości.
W późniejszym teście usunęliśmy jeden z wyzwalaczy, które stanowiły 80% wiadomości. Nawet przy tak znacznie zmniejszonym obciążeniu zaczęliśmy widzieć te same oczekiwania.
AKTUALIZACJA 3
Dziękuję, Remus za radę (i dziękuję za opublikowanie tak doskonałych artykułów na blogu na ten temat, które przyczyniły się do osiągnięcia tego celu).
Ponownie uruchomiliśmy go dzisiaj i zrobiliśmy lepiej (ponieważ poszliśmy dłużej, zanim zobaczyliśmy oczekiwania, a nawet dłużej, zanim nas kaleczył). A więc szczegóły.
Zmieniliśmy: * Zwiększono liczbę utrzymywanych rozmów w wątku z 1: 1 do 2: 1. Zasadniczo mieliśmy 8 uchwytów konwersacji dla 4 wątków.
- skonsolidował kolejkę zbiorczą (ponieważ jedna wiadomość przychodząca może oznaczać setki wiadomości wychodzących), aby skonsolidować ją w mniejszą, większą liczbę wiadomości.
Uwagi na temat tej próby:
wyłączenie procedury aktywacji kolejki docelowej. brak zmian w blokowaniu (czekaliśmy 5 minut) i wiadomości zostały wysłane do sys.transmission_queues.
monitorowanie sys.conversation_endpoints. Liczba ta wzrosła bardzo szybko od 0 13K, a następnie wolniej rosła w ciągu dnia, kończąc na około 25K po ~ 5 godzinach. Blokowanie nie zaczęło się pojawiać, dopóki nie osiągnęło 16K +/-
Poszedłem do DAC-a i uruchomiłem polecenia DBREINDEX dla kolejek, chociaż po zapytaniu rekordy duchów nigdy nie przekroczyły wartości około 200 przed nadejściem czyszczenia i spadły do zera.
sysdesend i sysdercv miały identyczną liczbę 24 932, kiedy zakończyłem test.
przetworzyliśmy ~ 310 000 wiadomości w ciągu 5 godzin.
Przeszliśmy tak długo, zanim wszystko się rozpadło, że naprawdę myślałem, że tym razem się uda. Jutro spróbujemy zmusić wiadomości do przejścia przez drut.
sys.conversation_endpoints
podczas testu (stała lub rośnie i jak duża jest, gdy nastąpi blokowanie). 2) Gdy nastąpi blokowanie, powoduje wyłączenie kolejki docelowej robi różnicę w blokowaniu SEND (wyłączenie kolejki powinno kierować SEND do sys.transmission_queue). i 3) Zmuszenie wiadomości, aby przechodziły na drut, nawet lokalnie (skonfiguruj punkt końcowy SSB, dodaj trasy) zmienia zachowanie na dłuższą metę
ALTER QUEUE ... REBUILD
robi różnicę po rozpoczęciu blokowania?
we started seeing blocks and high contention on sysdesend and the queue table.
-> Jaki jest typ oczekiwania -PAGELATCH_EX/SH and WRITELOG
? Czy wykorzystałeś już lewę 150 ? Jeśli twoje tabele systemowe są twoim punktem spornym, trik 150 będzie bardzo przydatny.