Przetwarzamy wiadomości za pośrednictwem różnych usług (jedna wiadomość dotyka prawdopodobnie 9 usług przed ich wykonaniem, każda pełni określoną funkcję związaną z We / Wy). W tej chwili mamy kombinację najgorszego przypadku (serializacja kontraktu danych XML) i najlepszego przypadku (MSMQ w pamięci) pod względem wydajności.
Charakter wiadomości oznacza, że nasze serializowane dane kończą się około 12-15 kilobajtami, a my przetwarzamy około 4 milionów wiadomości tygodniowo. Trwałe wiadomości w MSMQ były dla nas zbyt wolne, a gdy dane rosną, odczuwamy presję ze strony plików mapowanych w pamięci MSMQ. Serwer korzysta z 16 GB pamięci i rośnie, tylko do kolejkowania. Wydajność spada również, gdy użycie pamięci jest wysokie, ponieważ urządzenie zaczyna wymieniać. Już przeprowadzamy samoczyszczące działanie MSMQ.
Czuję, że jest coś, co robimy źle. Próbowałem użyć RavenDB do utrwalenia wiadomości i umieszczenia w kolejce identyfikatora, ale wydajność była bardzo niska (najlepiej 1000 wiadomości na minutę). Nie jestem pewien, czy to wynik użycia wersji programistycznej, czy co, ale zdecydowanie potrzebujemy wyższej przepustowości [1]. Koncepcja działała bardzo dobrze w teorii, ale wydajność nie była wystarczająca.
Wzorzec użycia ma jedną usługę działającą jak router, która wykonuje wszystkie odczyty. Inne usługi dołączą informacje na podstawie haka innej firmy i przekażą je z powrotem do routera. Większość obiektów jest dotykana 9-12 razy, chociaż około 10% jest zmuszonych do zapętlania się w tym systemie przez jakiś czas, aż strony trzecie zareagują odpowiednio. Usługi właśnie to uwzględniają i mają odpowiednie zachowanie podczas snu, ponieważ z tego powodu wykorzystujemy pole priorytetu wiadomości.
Tak więc, moje pytanie, jaki jest idealny stos do przekazywania wiadomości między maszynami z dyskretną obsługą sieci LAN w środowisku C # / Windows? Normalnie zaczynałbym od BinaryFormatter zamiast serializacji XML, ale to wielka dziura, jeśli lepszym sposobem jest przeniesienie serializacji do magazynu dokumentów. Stąd moje pytanie.
[1]: Charakter naszej firmy oznacza, że im szybciej przetwarzamy wiadomości, tym więcej zarabiamy. Udowodniliśmy empirycznie, że przetwarzanie wiadomości w późniejszym tygodniu oznacza mniejsze prawdopodobieństwo zarobienia tych pieniędzy. Chociaż wydajność „1000 na minutę” brzmi dość szybko, naprawdę potrzebujemy tej liczby w górę o 10 000 na minutę. To, że podam numery w wiadomościach na tydzień, nie oznacza, że mamy cały tydzień na ich przetworzenie.
=============== edycja:
Dodatkowe informacje
W oparciu o komentarze dodam trochę wyjaśnień:
Nie jestem pewien, czy serializacja jest naszym wąskim gardłem. Przeanalizowałem aplikację i chociaż serializacja nie pojawia się na wykresie cieplnym, odpowiada ona jedynie za 2,5-3% wykorzystania procesora przez usługę.
Najbardziej martwię się o trwałość naszych wiadomości i potencjalne niewłaściwe użycie MSMQ. Używamy nietransakcyjnych, nietrwałych wiadomości, abyśmy mogli zwiększyć wydajność kolejkowania, i naprawdę chciałbym mieć przynajmniej trwałe wiadomości, aby przetrwały restart.
Dodanie większej ilości pamięci RAM jest krokiem naprzód. Maszyna ma już 4 GB -> 16 GB pamięci RAM i coraz trudniej jest ją zdjąć, aby kontynuować dodawanie kolejnych.
Ze względu na wzór trasy gwiazdy w aplikacji, połowę czasu, kiedy obiekt jest otwierany, a następnie wypychany do kolejki, nie zmienia się wcale. Pozwala to ponownie (IMO) na przechowywanie go w jakimś sklepie z kluczowymi wartościami i przekazywanie identyfikatorów wiadomości.
Wzór trasy gwiazdy jest integralną częścią aplikacji i nie ulega zmianie. Nie możemy go stonizować, ponieważ każdy element po drodze działa asynchronicznie (w trybie odpytywania) i chcemy scentralizować zachowanie ponownych prób w jednym miejscu.
Logika aplikacji jest napisana w języku C #, obiekty są niezmiennymi POCO, docelowym środowiskiem wdrażania jest system Windows Server 2012, a my możemy stanąć na dodatkowych maszynach, jeśli dane oprogramowanie jest obsługiwane tylko w systemie Linux.
Moim celem jest utrzymanie bieżącej przepustowości przy jednoczesnym zmniejszeniu zużycia pamięci i zwiększeniu odporności na uszkodzenia przy minimalnym nakładzie kapitału.