Dlaczego strumienie w systemie Orleans?
Istnieje już wiele technologii, które umożliwiają tworzenie systemów przetwarzania strumieniowego. Obejmują one systemy do trwałego przechowywania danych strumienia (np . event hubs i Kafka) oraz systemów do wyrażania operacji obliczeniowych za pośrednictwem danych strumienia (np . Azure Stream Analytics, Apache Storm i Apache Spark Streaming). Są to doskonałe systemy, które umożliwiają tworzenie wydajnych potoków przetwarzania strumienia danych.
Ograniczenia istniejących systemów
Jednak te systemy nie są odpowiednie do precyzyjnego przetwarzania danych strumieniowych. Systemy obliczeniowe przesyłania strumieniowego wymienione powyżej umożliwiają określenie ujednoliconego grafu przepływu danych operacji, które są stosowane w taki sam sposób, jak we wszystkich elementach strumienia. Jest to zaawansowany model, gdy dane są jednolite i chcesz wyrazić ten sam zestaw operacji przekształcania, filtrowania lub agregacji na tych danych. Istnieją jednak inne przypadki użycia, w których należy wyrazić zasadniczo różne operacje na różnych elementach danych. W niektórych z nich w ramach tego przetwarzania czasami trzeba wykonać wywołanie zewnętrzne, takie jak wywołanie dowolnego interfejsu API REST. Ujednolicone aparaty przetwarzania strumienia danych nie obsługują tych scenariuszy, obsługują je w ograniczony i ograniczony sposób lub są nieefektywne w ich obsłudze. Jest to spowodowane tym, że są one z natury zoptymalizowane pod kątem dużej ilości podobnych elementów i zwykle ograniczone pod względem ekspresywności, przetwarzania. OrleansStrumienie dotyczyć tych innych scenariuszy.
Motywacja
Wszystko zaczęło się od żądań od Orleans użytkowników w celu obsługi zwracania sekwencji elementów z wywołania metody ziarna. Jak można sobie wyobrazić, to był tylko wierzchołek góry lodowej. Potrzebowali znacznie więcej.
Typowy scenariusz dla Strumienie polega na Orleans tym, że masz strumienie dla poszczególnych użytkowników i chcesz wykonać różne przetwarzanie dla każdego użytkownika w kontekście pojedynczego użytkownika. Możemy mieć miliony użytkowników, ale niektórzy są zainteresowani pogodą i mogą subskrybować alerty pogodowe dla określonej lokalizacji, podczas gdy niektórzy są zainteresowani wydarzeniami sportowymi; ktoś inny śledzi stan określonego lotu. Przetwarzanie tych zdarzeń wymaga innej logiki, ale nie chcesz uruchamiać dwóch niezależnych wystąpień przetwarzania strumienia. Niektórzy użytkownicy są zainteresowani tylko określonymi akcjami i tylko wtedy, gdy ma zastosowanie określony warunek zewnętrzny, warunek, który nie musi być częścią danych strumienia (a tym samym musi być sprawdzany dynamicznie w czasie wykonywania w ramach przetwarzania).
Użytkownicy zmieniają swoje zainteresowania przez cały czas, dlatego ich subskrypcje na określone strumienie zdarzeń przychodzą i idą dynamicznie, w związku z czym topologia przesyłania strumieniowego zmienia się dynamicznie i szybko. Ponadto logika przetwarzania na użytkownika ewoluuje i zmienia się dynamicznie na podstawie stanu użytkownika i zdarzeń zewnętrznych. Zdarzenia zewnętrzne mogą modyfikować logikę przetwarzania dla określonego użytkownika. Na przykład w systemie wykrywania oszustw w grze, gdy zostanie wykryty nowy sposób oszukiwania, logika przetwarzania musi zostać zaktualizowana przy użyciu nowej reguły w celu wykrycia tego nowego naruszenia. Należy to zrobić oczywiście bez zakłócania trwającego potoku przetwarzania. Aparaty przetwarzania strumieniowego przepływu danych zbiorczych nie zostały opracowane w celu obsługi takich scenariuszy.
Dzieje się to prawie bez stwierdzenia, że taki system musi działać na kilku maszynach połączonych z siecią, a nie na jednym węźle. W związku z tym logika przetwarzania musi być dystrybuowana w sposób skalowalny i elastyczny w klastrze serwerów.
Nowe wymagania
Zidentyfikowaliśmy 4 podstawowe wymagania dla naszego systemu przetwarzania strumieniowego, które umożliwią mu kierowanie powyższych scenariuszy.
- Elastyczna logika przetwarzania strumieniowego
- Obsługa topologii wysoce dynamicznych
- Szczegółowość strumienia szczegółowego
- Dystrybucja
Elastyczna logika przetwarzania strumieniowego
Chcemy, aby system obsługiwał różne sposoby wyrażania logiki przetwarzania strumieniowego. Istniejące systemy, o których wspomniano powyżej, wymagają od dewelopera napisania deklaratywnego grafu obliczeniowego przepływu danych, zwykle zgodnie ze stylem programowania funkcjonalnego. Ogranicza to ekspresywność i elastyczność logiki przetwarzania. Orleans strumienie są obojętne na sposób wyrażenia logiki przetwarzania. Można je wyrazić jako przepływ danych (na przykład przy użyciu reaktywnych rozszerzeń (Rx) na platformie .NET); jako programu funkcjonalnego, jako zapytania deklaratywnego lub ogólnej logiki imperatywnej. Logika może być stanowa lub bezstanowa, może lub nie ma skutków ubocznych i może wyzwalać akcje zewnętrzne. Cała moc trafia do dewelopera.
Obsługa topologii dynamicznych
Chcemy, aby system umożliwiał dynamiczne rozwijanie topologii. Istniejące systemy, o których wspomniano powyżej, są zwykle ograniczone tylko do statycznych topologii, które są stałe w czasie wdrażania i nie mogą ewoluować w czasie wykonywania. W poniższym przykładzie wyrażenia przepływu danych wszystko jest miłe i proste, dopóki nie trzeba go zmieniać.
Stream.GroupBy(x=> x.key).Extract(x=>x.field).Select(x=>x+2).AverageWindow(x, 5sec).Where(x=>x > 0.8) *
Zmień warunek progu w filtrze Where , dodaj Select instrukcję lub dodaj inną gałąź na grafie przepływu danych i utwórz nowy strumień wyjściowy. W istniejących systemach nie jest to możliwe bez usuwania całej topologii i ponownego uruchamiania przepływu danych od podstaw. Praktycznie te systemy będą sprawdzać istniejące obliczenia i będą mogły zostać uruchomione ponownie z najnowszego punktu kontrolnego. Mimo to takie ponowne uruchomienie jest destrukcyjne i kosztowne dla usługi online, która generuje wyniki w czasie rzeczywistym. Takie ponowne uruchomienie staje się szczególnie niepraktyczne, gdy mówimy o dużej liczbie takich wyrażeń wykonywanych z podobnymi, ale różnymi parametrami (na użytkownika, na urządzenie itp.), które stale się zmieniają.
Chcemy, aby system umożliwiał rozwój grafu przetwarzania strumieniowego w czasie wykonywania, dodając nowe łącza lub węzły do grafu obliczeniowego lub zmieniając logikę przetwarzania w węzłach obliczeniowych.
Stopień szczegółowości strumienia szczegółowego
W istniejących systemach najmniejszą jednostką abstrakcji jest zwykle cały przepływ (topologia). Jednak wiele z naszych scenariuszy docelowych wymaga pojedynczego węzła/łącza w topologii, aby sama jednostka logiczna. Dzięki temu każda jednostka może być potencjalnie zarządzana niezależnie. Na przykład w topologii strumienia dużego składającego się z wielu łączy różne linki mogą mieć różne cechy i mogą być implementowane w różnych transportach fizycznych. Niektóre linki mogą przechodzić przez gniazda TCP, a inne za pośrednictwem niezawodnych kolejek. Różne linki mogą mieć różne gwarancje dostarczania. Różne węzły mogą mieć różne strategie tworzenia punktów kontrolnych, a ich logika przetwarzania może być wyrażona w różnych modelach, a nawet w różnych językach. Taka elastyczność zwykle nie jest możliwa w istniejących systemach.
Jednostka abstrakcji i argument elastyczności jest podobna do porównania architektur SoA (architektur zorientowanych na usługi) a aktorów. Systemy aktorów umożliwiają większą elastyczność, ponieważ każdy aktor jest zasadniczo niezależnym zarządzanym "małą usługą". Podobnie chcemy, aby system strumieniowy zezwalał na taką precyzyjną kontrolę.
Dystrybucja
I oczywiście nasz system powinien mieć wszystkie właściwości "dobrego systemu rozproszonego". Obejmuje to:
- Skalowalność — obsługuje dużą liczbę strumieni i elementów obliczeniowych.
- Elastyczność — umożliwia dodawanie/usuwanie zasobów w celu zwiększania/zmniejszania na podstawie obciążenia.
- Niezawodność — odporność na błędy
- Wydajność — wydajne korzystanie z zasobów bazowych
- Czas odpowiedzi — umożliwia korzystanie ze scenariuszy niemal w czasie rzeczywistym.
Były to wymagania, które mieliśmy na uwadze podczas tworzenia Orleans przesyłania strumieniowego.
Wyjaśnienie: Orleans obecnie nie obsługuje bezpośredniego zapisywania wyrażeń deklaratywnych przepływu danych, takich jak w powyższym przykładzie. Bieżące Orleans interfejsy API przesyłania strumieniowego są bardziej niskimi blokami konstrukcyjnymi, jak opisano tutaj. Zapewnienie deklaratywnych wyrażeń przepływu danych jest naszym przyszłym celem.