Hizmet Aracısı - Konuşma Ömrü?


9

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)

  1. Yangınları Tetikle (düşük gecikme veya toplu sürüme gönder)
  2. Arama tutamacını arayın veya oluşturun.
  3. mesaj gönder
  4. Kuyruk etkin yordamı
  5. 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.


1
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.
Kin Shah

@kin, soruyu güncelledim, ancak kilit türleri LCK_M_U veya LCK_M_X. 150 numarayı okumuştum ama 2016'da gereksiz olduğunu umuyordum (tempdb sızıntı sorununu da çözdüklerinden beri), aynı zamanda böyle bir hack gibi göründüğü için. Üretime girerken başka bir bıçak yapacağız (ne yazık ki sadece üretim iş yükleriyle karşılaşıyoruz) ve önce daha kısa ömür boyu konuşmaları deneyeceğiz. Burada sonuçları ile güncelleyeceğim. Sonra referans verdiğiniz 150 numara olacak.
Jonathan Fite

Twitter'da @RemusRusanu sordum - o hizmet komisyoncu şeyler konusunda uzmandır :-)
Kin Shah

Bu daha önce gördüğüm bir şey değil (uzun çalışma süresinden sonra SEND'in bozulması). 1) Lütfen sys.conversation_endpointstest 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
zorlar

Bazı düşünceler: 4) engelleme gerçekleştiğinde, ALICI'nın hedefte durdurulması bir fark yaratır mı (varsa aktif proc'u devre dışı bırak) ve 5) hedef sırada kaç hayalet kayıt var? ALTER QUEUE ... REBUILDEngelleme başladıktan sonra çalıştırmak fark yaratır mı?
Remus Rusanu

Yanıtlar:


3

Kendi sorunuza cevap vermenin kötü bir form olduğunu biliyorum, ama ilgilenen herkes için bunu kapatmak istedim. Sonunda sorunu çözmeyi veya en azından gereksinimlerimizi karşılayacak kadar çözmeyi başardık. Yorum yapan herkese teşekkür etmek istiyorum; Remus Rusanu ve Kin çok yardımcı oldular.

Veritabanımız oldukça yoğun ve RCSI modunda. Konum bilgilerini 45 saniyede bir güncelleyen birden çok (binlerce) mobil cihazımız var. Bu güncellemeler sayesinde, birden fazla tablo bilgilerini günceller (uçucu bilgileri tek bir tabloyla sınırlayıp daha sonra sonuçlar için katıldığım için kötü tasarım). Bu tablolar, son kullanıcıların doğrudan temel tablolara yönelmesini sağlamak yerine, zaman uyumsuz olarak raporlama bilgileri oluşturmaya çalıştığımız tablolardır.

Başlangıçta her güncelleme / ekleme deyiminde (çoğu durumda bir satır olması gerekir) değiştirilmiş kayıtlar üzerinde bir imleç yapan ve her birincil anahtarı servis aracısına bir iletiye gönderen tetikleyicilerimiz vardı. Hizmet komisyoncusu içinde, özellikle toplu kuyruk, rapor için üst prosedürü (birincil anahtar başına bir yürütme) yürüten diğer imleçlerdi.

Nihayet bizi çalıştırdı:

  • İmleçleri kaldırdık ve daha büyük mesajlar göndermeye karar verdik. Tablo başına kullanıcı işlemi başına yine bir ileti var, ancak artık birden fazla birincil anahtar içeren ileti gönderiyoruz.

  • Toplu işlemci ayrıca mesaj başına birden fazla anahtar gönderir ve bu da iletileri uygun şekilde diğer kuyruğa karıştırırken devam eden SEND CONVERSATIONS sayısını azaltır.

  • En geçici tablo (mobil cihaz veri tablomuz), tetikleyicileri kaldırmıştı. Upert prosedürünü uygun yabancı anahtarları içerecek şekilde güncelledik ve şimdi kullanıcılara sonuçları getirirken bu tabloya tekrar katılıyoruz. Bu tablo, bir gün içinde işlememiz gereken mesajların% 80'ine kolayca katkıda bulundu.

Günde ~ 1 milyon mesajı (Mobil tablo olmadan) işleriz ve mesajlarımızın büyük çoğunluğu (% 99 +) hedefimiz dahilinde işlenir. Hala ara sıra aykırı değerimiz var ama bunun nadir doğası göz önüne alındığında kabul edilebilir olduğu kabul ediliyor.

İçeren faktörler:

  • Daha önce bahsi geçen konuşma temizleme prosedüründe, konuşmaları uygun şekilde temizlemeyen ve onları erken bitiren bir hata buldum. Bu, sistem sayım sayımızın asla birkaç binden fazla olmamasına neden oldu (çoğu 150 numarayı kullanmaktan geliyor).

  • Tetikleyicilerdeki imleçler beklenenden daha fazla kilit tutuyor gibi görünüyordu (statik, ileri_yokta olsa bile). Bunları kaldırmak, DÖNÜŞÜM GÖNDER 'te gördüğümüz kilitleri doğada daha geçici hale getirdi (ya da en azından gördüğümüz zamanlar çok daha düşük).

  • Aslında iki çözümü yan yana (Service Broker çözümü arka ucu (üretim yükü altında test için)) ve mevcut çözümü (birçok tabloyu kapsayan korkunç sorgu) çalıştırıyorduk.

Bir yan fayda olarak, bu bir Hayalet Kayıt Temizleme sorununu ortaya çıkarmıştır ve Service Broker tablolarında (sistem veya kuyruk) olmasa da, sistemimizde oldukça yaygındır ve belirtiler "net nedenimiz" ile gerçekten iyi uyuşmaz. zaman zaman yaşadığımız sorunlar. Bu konuda araştırmalar devam ediyor, buna katkıda bulunan tabloları bulmaya çalışıyoruz ve muhtemelen sadece dizinlerini rutin olarak yeniden oluşturacağız.

Tekrar teşekkürler.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.