Bir iş vakasını çözmek için Service Broker'ın çevremizde çalışmasını sağlamaya çalışıyoruz. Mesaj başlığının iyi olup olmadığını bilmiyorum, ancak sorum aşağıda. Ama bu iyi bir soru olmayabilir, bu yüzden bundan sonra yapıyoruz ve neden doğru soru olduğunu düşünüyorum.
Görüşmeyi bitirmeden önce bir görüşmeye kaç mesaj gönderilmelidir?
Bir sonuç tablosunu eşzamansız olarak güncellemek için Hizmet Aracısı'nı kullanmak istiyoruz. Sonuç tablosu düzleştirilmiş ve hızlıdır. Temel tablolarda, tabloları ve birincil anahtarlarıyla ileti gönderen tetikleyiciler var. Üç kuyruğumuz var:
- Düşük Gecikme - hedef işleme için 15 saniyedir. Belirli bir öğeyle ilgili olarak değişen öğeleri işler.
- Toplu Sıra - hedefin işlenmesi 5 dakikadır. Yüzlerce (veya binlerce) öğeyi etkileyen bir şey değiştiğinde işler. Etkilenen öğelerin listesini çıkarır ve bunları Ertelenmiş Düşük Gecikme Kuyruğuna besler
- Ertelenmiş Düşük Gecikme - hedefin işlenmesi 30 dakikadır. Bu, öğeleri yalnızca toplu kuyruktan işler.
Temel olarak, bir müşterinin bilgileri güncellenirse; birçok ürünü etkiler, böylece daha yavaş işleme için toplu kuyruğa gönderilir. Ancak, bir ürün güncellenirse, düşük gecikme kuyruğuna gönderilir.
Remus Rusanu'nun http://rusanu.com/2007/04/25/reusing-conversations/ bloguna benzer sohbetleri , birincil anahtarın modülüne dayanarak yapmamız dışında tekrar kullanıyoruz. Bu, birincil anahtarların çoğaltılmasına yardımcı olma avantajına sahiptir.
Dolayısıyla, konuşmaları yeniden kullanıyoruz ve yönergelerimize uyuyoruz. İki iş parçacığıyla, üretime ayak uydurabilen (tahmini 15 mesaj / sn) 125 saniyede saniyede (birkaç bin mesajlık yapay düşüş) yanabildim.
Bununla birlikte, karşılaştığımız sorun, bir süre sonra ~ 4 saat veya 120K mesajdan sonra, sysdesend ve kuyruk tablosunda bloklar ve yüksek çekişme görmeye başladık. Kilitler LCK_M_U ve ANAHTAR kilitlerdir. Bazen hobt sysdesend ve diğer zamanları belirli kuyruk tablosuna (queue_) giderir.
Halihazırda 24 saat veya 30 dakika boyunca herhangi bir işlem yapılmadığında konuşmaları sona erdirecek bir sürecimiz var, bu yüzden konuşmaları tekrarlamadan önceki süreyi artırabiliriz.
SQL 2016 Enterprise kullanıyoruz (13.0.4001.0)
- Yangınları Tetikle (düşük gecikme veya toplu sürüme gönder)
- Arama tutamacını arayın veya oluşturun.
- mesaj gönder
- Kuyruk etkin yordamı
- Sonuçlar tablosunu güncelleme
Temizleme işlemi, boşta konuşmaların olup olmadığını görmek için her 10 dakikada bir çalışır. onları arka arkaya üç kereden fazla bulursa, etkin değil olarak işaretler ve konuşmaları sonlandırır.
Yararlı olabilecek herhangi bir ek ayrıntı varsa lütfen bize bildirin. Service Broker ile fazla deneyimim yok, bu yüzden mesajlarımızın / sn'nin düşük, yüksek veya kayıtsız olup olmadığını bilmiyorum.
GÜNCELLEME
Bu yüzden bugün tekrar denedik ve aynı problemle karşılaştık. Konuşma ömrünü 2 saat olarak değiştirdik ve bunun bir etkisi olmadı. Sonra 150 numarayı uyguladık; aynı sorunu vardı.
DÖNÜŞÜM GÖNDER, ton beklemede bekleyen tonlarca. Başka fikri olan var mı?
GÜNCELLEME 2
Testi bugün daha uzun süre gerçekleştirdik ve 17 dakikalık örnek dönemlerden biri için 4 konuşma tutamacında 41K mesaj işledik. Sysdesend üzerindeki kilitler ve kuyruk tablosu çok fazla olduğunda ve durmadan önce arkaya doğru sürüklenmeye başladığımızda sonuna kadar devam edebildik. İletileri işlemede herhangi bir sorunumuz yok gibi görünüyor, sıraya girmeden, onları çıkarabilir ve bu hızın en az 5 katı işleyebiliriz. Hızımız, mesaj eklemeye bağlı olarak sınırlı görünmektedir.
Daha sonraki bir testte, iletilerin% 80'ini oluşturan tetikleyicilerden birini kaldırdık. Bu çok azaltılmış yükte bile, aynı beklemeleri görmeye başladık.
GÜNCELLEME 3
Teşekkürler, tavsiyeleriniz için Remus (ve bu konuda mükemmel blog makaleleri yayınladığınız için teşekkür ederiz, bu noktaya gelmede etkili oldular).
Biz bugün tekrar koştu ve daha iyi yaptım (gibi biz beklemeleri görmeden önce daha uzun ve daha önce bizi sakat önce gitti). Yani, detaylar.
Değiştirdik: * İleti dizisi başına yapılan ileti dizisi sayısını 1: 1'den 2: 1'e yükselttik. Temel olarak, 4 konu için 8 konuşma kolu vardı.
- toplu kuyruğu birleştirdi (çünkü gelen bir mesaj yüzlerce giden mesaj anlamına gelebilir)
Bu girişim hakkında notlar:
hedef sıra etkinleştirme yordamını devre dışı bırakma. engellemede değişiklik yok (5 dakika bekledik) ve mesajlar sys.transmission_queues adresine gönderildi.
sys.conversation_endpoints izleme. Bu sayı 0 13K'dan çok hızlı bir şekilde gitti ve daha sonra gün boyunca daha yavaş yükseldi ve ~ 5 saat sonra 25K civarında kaldı. 16K +/- değerine ulaşana kadar engelleme gerçekleşmedi
DAC'ye girdim ve sıralar için DBREINDEX komutlarını çalıştırdım, ancak bir sorgudan, temizlik gelmeden ve sayıyı 0'a düşürmeden önce hayalet kayıtları asla 200'ün üzerine çıkmadı.
Sysdesend ve sysdercv, testi sonlandırdığımda 24.932'lik özdeş sayılara sahipti.
5 saat içinde ~ 310 bin ileti işledik.
İşler dağılmadan o kadar uzun gittik ki, bu sefer gerçekten yapacağımızı düşündüm. Yarın mesajları telden geçmeye zorlayacağız.
sys.conversation_endpoints
test sırasında satır sayısının ne olduğunu (sabit veya artmakta olduğunu ve engelleme gerçekleştiğinde ne kadar büyük olduğunu ) söyle . 2) Engelleme gerçekleştiğinde, hedef kuyruğun devre dışı bırakılması SEND engellemesinde bir fark yaratır mı (kuyruğun devre dışı bırakılması SEND öğesini sys.transmission_queue ile yönlendirmelidir). ve 3) Mesajları yerel olarak bile (kabloyu SSB uç noktasını ayarlama, rota ekleme) uzun vadede davranışı değiştirmeye
ALTER QUEUE ... REBUILD
Engelleme başladıktan sonra çalıştırmak fark yaratır mı?
we started seeing blocks and high contention on sysdesend and the queue table.
-> Bekleme türü nedir -PAGELATCH_EX/SH and WRITELOG
? 150 numarayı kullandın mı ? Sistem tabloları tartışma noktanızsa, 150 numara son derece yararlı olacaktır.