2013-02-04 25 views
7

Szukam informacji na temat skalowania usługi systemu Windows, która jest obecnie uruchomiona w mojej firmie. Jesteśmy przy użyciu .NET 4.0 (może i zostanie uaktualniony do 4,5 w pewnym momencie w przyszłości) i działa to w systemie Windows Server 2012.Skalowanie usług systemu Windows

O służbie
praca usługa jest do kwerendy dla nowych wierszy tabelę rejestrowania (pracujemy z bazą danych Oracle), przetwarzamy informacje, tworzymy i/lub aktualizujemy kilka rzędów w 5 innych tabelach (nazwijmy je tabelami śledzenia), aktualizuj tabelę rejestrowania i powtarzaj.

Tabela rejestrowania zawiera duże ilości danych XML (może wzrosnąć do 20 MB na wiersz), które należy wybrać i zapisać w pozostałych 5 tabelach śledzenia. Nowe wiersze dodawane są przez cały czas z maksymalną szybkością 500 000 wierszy na godzinę.
Ruch w tabelach śledzenia jest znacznie wyższy, od 90 000 nowych wierszy od najmniejszego do potencjalnie milionów wierszy w największym stole, co godzinę. Nie wspominając już o tym, że są również operacje aktualizacji na tych tabelach.

O przetwarzanych danych
czuję ten bit jest ważne dla znalezienia rozwiązania w oparciu o jak te obiekty są grupowane i przetwarzane. Struktura danych wygląda następująco:

public class Report 
{ 
    public long Id { get; set; } 
    public DateTime CreateTime { get; set; } 
    public Guid MessageId { get; set; } 
    public string XmlData { get; set; } 
} 

public class Message 
{ 
    public Guid Id { get; set; } 
} 
  • Raport jest rejestrowanie danych muszę wybrać i proces
  • Do każdej wiadomości nie są średnio 5 Reports. W niektórych przypadkach może to wynosić od 1 do setek.
  • Wiadomość zawiera kilka innych kolekcji i innych relacji, ale nie mają one znaczenia dla pytania.

Dziś usługa Windows mamy ledwo udaje obciążenie na serwerze 16-rdzeniowego (nie pamiętam pełne specyfikacje, ale to na pewno powiedzieć, maszyna ta jest bestia). Mam za zadanie znaleźć sposób na skalowanie i dodać więcej maszyn, które będą przetwarzać wszystkie te dane i nie przeszkadzać innym instancjom.

Obecnie każda wiadomość otrzymuje własny wątek i obsługuje odpowiednie raporty. Obsługujemy raporty w partiach pogrupowane według ich ID wiadomości, aby zmniejszyć liczbę zapytań DB do minimum podczas przetwarzania danych.

Ograniczenia

  • Na tym etapie jestem pozwoliło ponownie napisać ten serwis od podstaw przy użyciu dowolnego architekturę I regulaminem.
  • Jeśli wystąpi awaria instancji, inne instancje muszą być w stanie wykryć miejsce, w którym nastąpiło uszkodzenie. Żadne dane nie mogą zostać utracone.
  • To przetwarzanie musi być jak najbardziej zbliżone do czasu rzeczywistego z raportów wstawianych do bazy danych.

szukam dowolnego wejścia radę lub o tym, jak zbudować taki projekt. Zakładam, że usługi będą musiały być bezpaństwowcami, czy też istnieje sposób synchronizacji pamięci podręcznych dla wszystkich wystąpień? Jak powinienem koordynować wszystkie wystąpienia i upewnić się, że nie przetwarzają tych samych danych?Jak mogę równomiernie rozłożyć obciążenie między nimi? I oczywiście, jak radzić sobie z zawieszaniem się instancji i nie kończeniem jej pracy?

EDIT
Usunięto informacje nieistotne

+0

To * brzmi * jak proces ETL. Czy zastanawiałeś się nad patrzeniem na coś takiego jak SQL Server Integration Services (SSIS) i pisaniem pakietów, które można zaplanować tak, aby regularnie przeprowadzały ten proces? –

+0

Używamy Oracle, a wyżsi nie chcą słyszeć słowa o SQL Server, niestety. – Artless

+0

Myślałem tylko o części SSIS, a nie o silniku bazy danych :) Alternatywą byłoby coś takiego jak Pentaho Data Integration (http://www.pentaho.com/explore/pentaho-data-integration/) lub Talend etl analytics (http://www.talend.com/solutions/etl-analytics) –

Odpowiedz

0

Rozwiązałem to przez kodowanie wszystko to skalowalność i nadmiarowość rzeczy na własną rękę. Wyjaśnię, co zrobiłem i jak to zrobiłem, gdyby ktoś kiedykolwiek tego potrzebował.

Utworzyłem kilka procesów w każdej instancji, aby śledzić pozostałe i wiedzieć, które rekordy może przetwarzać konkretna instancja. Po uruchomieniu instancja zarejestruje się w bazie danych (jeśli jeszcze jej nie ma) w tabeli o nazwie Instances. Tabela ta zawiera następujące kolumny:

Id     Number 
MachineName  Varchar2 
LastActive   Timestamp 
IsMaster   Number(1) 

Po rejestracji i tworzenia wiersza w tabeli, jeśli nie stwierdzono wystąpienie na MachineName instancja Uruchamia pingowanie tej tabeli każda sekunda w osobnym wątku, aktualizując swój LastActive kolumnę. Następnie wybiera wszystkie wiersze z tej tabeli i upewnia się, że Master Instance (więcej o tym później) jest wciąż żywa - co oznacza, że ​​jest to LastActive czas jest w ciągu ostatnich 10 sekund. Jeśli instancja główna przestanie odpowiadać, przejmie kontrolę i ustawi się jako master. W następnej iteracji upewni się, że istnieje tylko jeden wzorzec (w przypadku, gdy inna instancja zdecydowała się jednocześnie przejąć kontrolę), a jeśli nie, to ulegnie instancji z najniższym Id.

Co to jest instancja główna? Zadaniem serwisu jest skanowanie tabeli rejestrowania i przetwarzanie danych, aby ludzie mogli ją łatwo odfiltrować i odczytać. Nie podałem tego w moim pytaniu, ale może to mieć znaczenie tutaj. Mamy kilka serwerów ESB zapisujących wiele rekordów do tabeli rejestrowania na żądanie, a zadaniem mojej usługi jest śledzenie ich w czasie zbliżonym do rzeczywistego. Ponieważ zapisują swoje dzienniki asynchronicznie, potencjalnie mogę uzyskać wpis finished processing request A przed started processing request A w dzienniku. Mam więc kod, który sortuje te rekordy i zapewnia, że ​​moja usługa przetwarza dane we właściwej kolejności. Ponieważ musiałem skalować tę usługę, tylko jedna instancja może wykonać tę logikę, aby uniknąć wielu niepotrzebnych zapytań DB i prawdopodobnie obłąkanych błędów.
To jest miejsce, w którym wchodzi Master Instance. Tylko on wykonuje tę logikę sortowania i tymczasowo zapisuje identyfikator rekordu dziennika w innej tabeli o nazwie ReportAssignment. Zadaniem tego stołu jest śledzenie, które rekordy zostały przetworzone i przez kogo. Po zakończeniu przetwarzania rekord zostanie usunięty. Tabela wygląda następująco:

RecordId  Number 
InstanceId  Number Nullable 

Główna instancja sortuje wpisy dziennika i wstawia ich identyfikatory. Wszystkie moje wystąpienia usługi sprawdzają tę tabelę w odstępach 1-sekundowych dla nowych rekordów, które nie są przetwarzane przez nikogo lub które są przetwarzane przez nieaktywną instancję, oraz że [record's Id] % [number of isnstances] == [index of current instance in a sorted array of all the active instances] (które zostały uzyskane podczas procesu Pingowania). Kwerenda wygląda nieco jak poniżej:

SELECT * FROM ReportAssignment 
WHERE (InstanceId IS NULL OR InstanceId NOT IN (1, 2, 3)) // 1,2,3 are the active instances 
AND RecordId % 3 == 0 // 0 is the index of the current instance in the list of active instances 

Dlaczego muszę to zrobić?

  • Pozostałe dwa przypadki, że zapytanie o RecordId % 3 == 1 i RecordId % 3 == 2.
  • RecordId % [instanceCount] == [indexOfCurrentInstance] zapewnia równomierne rozdzielenie rekordów między wszystkimi instancjami.
  • pozwala instancjom przejąć rekordy, które były przetwarzane przez instancję, która uległa awarii, i nie przetwarza rekordów już aktywnych instancji po dodaniu nowej instancji.

Po instancję zapytań do tych zapisów, będzie wykonywał polecenia aktualizacji, ustawiając InstanceId do własnej i kwerendy tabeli rejestrowania zapisów z tych identyfikatorów. Po zakończeniu przetwarzania usuwa rekordy z ReportAssignment.

Ogólnie jestem z tego bardzo zadowolony. Ładnie się skaluje, zapewnia, że ​​żadne dane nie zostaną utracone, gdy instancja ulegnie awarii i prawie nie wystąpią żadne zmiany w istniejącym kodzie, który mamy.

6

Dla swoich elementów roboczych, Windows Workflow jest prawdopodobnie najszybszą drogą byłaby usługi.

Windows Workflow Foundation @ MSDN

Najbardziej przydatna rzecz dostaniesz z WF jest utrzymywanie przepływu pracy, gdzie właściwie zaprojektowany obieg może zostać wznowione od punktu utrzymują się, gdyby coś się stało z obiegu od ostatniego punktu, w którym to było zapisane.

Workflow Persistence @ MSDN

to możliwości dla obiegu być odzyskane z innego procesu należy dowolny inny awarii podczas procesu przetwarzania pracy. Proces wznawiania nie musi odbywać się na tym samym komputerze, jeśli korzystasz ze współużytkowanego magazynu przepływu pracy. Należy pamiętać, że wszystkie możliwe do odzyskania przepływy pracy wymagają użycia magazynu przepływu pracy.

Do dystrybucji pracy masz kilka opcji.

  1. Usługa wiadomości do produkcji połączone ze zrównoważenia obciążenia opartego na gospodarza poprzez przepływ pracy wywołaniu przy użyciu punktów końcowych WCF pośrednictwem klasy WorkflowService. Zauważ, że prawdopodobnie będziesz chciał użyć edytora trybu projektowania tutaj, aby skonstruować metody wprowadzania zamiast ręcznego konfigurowania Receive i odpowiednich procedur obsługi SendReply (te odwzorowują metody WCF). Najprawdopodobniej zadzwonisz do usługi dla każdej wiadomości, a być może również zadzwonisz do usługi dla każdego raportu. Zauważ, że tutaj ważna jest właściwość CanCreateInstance. Każde powiązane z nim wywołanie tworzy działającą instancję, która działa niezależnie.
    ~
    WorkflowService Class (System.ServiceModel.Activities) @ MSDN
    Receive Class (System.ServiceModel.Activities) @ MSDN
    Receive.CanCreateInstance Property (System.ServiceModel.Activities) @ MSDN
    SendReply Class (System.ServiceModel.Activities) @ MSDN

  2. Użyj autobus usługa, która ma wsparcie kolejce. Co najmniej chcesz coś, co potencjalnie akceptuje dane wejściowe z dowolnej liczby klientów, i których wyniki mogą być jednoznacznie zidentyfikowane i obsługiwane dokładnie raz. Kilka, które przychodzą na myśl, to NServiceBus, MSMQ, RabbitMQ i ZeroMQ. Spośród wymienionych tu pozycji, NServiceBus jest wyłącznie .NET gotowy out-of-the-box. W kontekście chmurowym opcje obejmują również oferty specyficzne dla platformy, takie jak usługa Azure Service Bus i Amazon SQS.
    ~
    NServiceBus
    MSMQ @ MSDN
    RabbitMQ
    ZeroMQ
    Azure Service Bus @ MSDN
    Amazon SQS @ Amazon AWS
    ~
    Uwaga że autobus obsługa jest po prostu klej między producentem, który zainicjuje wiadomości i konsumenta, który może występować na dowolnym liczba komputerów do odczytania z kolejki. Podobnie możesz użyć tego kierunku w celu generowania raportu. Konsument utworzy instancje przepływu pracy, które mogą następnie używać trwałości przepływu pracy.

  3. System Windows AppFabric może służyć do hostowania przepływów pracy, umożliwiając korzystanie z wielu technik dotyczących równoważenia obciążenia IIS w celu dystrybucji pracy. Osobiście nie mam z tym żadnego doświadczenia, więc niewiele mogę o nim powiedzieć poza tym, że ma dobre wsparcie w monitorowaniu zaraz po wyjęciu z pudełka.
    ~
    How to: Host a Workflow Service with Windows App Fabric @ MSDN
+0

Dzięki! Będę musiał przeczytać i przetestować, i zobaczyć, co moja firma chce zrobić. – Artless

+1

Biorąc pod uwagę twój komentarz do komentarza dotyczącego rozwiązania raportowania na twoje pytanie, powinienem Cię ostrzec, że magazyn trwałości, który jest dostarczany z WF, bazuje na MS SQL Server, co może być dla ciebie interesującym rozwiązaniem. Warto sprawdzić, czy program MSDE może działać jako magazyn utrwalania, aby uniknąć konieczności konfigurowania instancji MSSQL. – meklarian

Powiązane problemy