Historia pytania.
Proliferacja Przemysłu 4.0 i infrastruktury inteligentnych miast przekształciła zarządzanie danymi szeregów czasowych z niszowej troski Ops w fundament nowoczesnych digitalnych gospodarek. Początkowe rozwiązania, takie jak Graphite czy jedno-węzłowa InfluxDB, zadowalały monolityczne aplikacje, ale nowoczesny krajobraz obejmuje miliony heterogenicznych punktów końcowych IoT emitujących dane telemetryczne o wysokiej kardiolalności na obszarach o fragmentowanych granicach geopolitycznych. Zbieżność wykładniczego wzrostu danych z rygorystycznymi mandatami suwerenności danych – takimi jak orzeczenie Schrems II w Unii Europejskiej – sprawiła, że architektury chmurowe oparte na centralizacji stały się prawnie nie do przyjęcia, co wymagało nowatorskich podejść do rozproszonego przechowywania, które szanowałyby fizyczne granice jurysdykcji, zachowując przy tym spójność analityczną.
Problem.
Wyzwanie architektoniczne koncentruje się na podstawowym niedopasowaniu między szlakami wprowadzania danych optymalizowanymi pod kątem zapisu a zapytaniami analitycznymi optymalizowanymi pod kątem odczytu w wielo-tenantowym środowisku. Wymiary o wysokiej kardynalności – takie jak unikalne identyfikatory urządzeń czy znaczniki czasu z dokładnością do milisekund – powodują eksplozję wzrostu indeksów, co degraduję wydajność tradycyjnych silników przechowywania B-drzew czy LSM-drzew. Ponadto, egzekwowanie ścisłej izolacji tenantów bez kompromisów w zakresie efektywności wykorzystania zasobów wymaga rozwiązania problemu „hałaśliwego sąsiada” w skali planetarnej, gdzie nagły przypływ danych sensorowych jednego tenanta nie może pogarszać wydajności zapytań dla innych, przy jednoczesnym utrzymaniu gwarancji ACID w regionach podlegających nieprzewidywalnym podziałom sieciowym.
Rozwiązanie.
Wzór architektury Lambda stanowi teoretyczną podstawę, oddzielając warstwę prędkości (gorące, ostatnie dane) od warstwy wsadowej (zimne, historyczne dane). Warstwa wprowadzania danych korzysta z Apache Kafka lub Apache Pulsar podzielonych według regionu geograficznego, aby spełnić wymagania dotyczące pobytu danych, z Kafka Streams wykonującymi bieżące próbkowanie, aby złagodzić presję na kardynalność. Gorące przechowywanie wykorzystuje Apache Cassandra lub ScyllaDB z złożonymi kluczami podstawowymi (time_bucket, device_hash), aby rozdzielić obciążenie zapisu, podczas gdy zimne przechowywanie opiera się na plikach Apache Parquet w obiektowych magazynach zgodnych z S3 z formatami tabel Apache Iceberg dla ewolucji schematów. Federacja zapytań za pomocą Trino lub Presto agreguje w tych heterogenicznych warstwach, z proxy Envoy egzekwującymi logikę geo-fence na krawędzi sieci, aby zapobiec wyciekowi danych przez granice.
Pod koniec 2023 roku międzynarodowa firma technologii rolniczej wdrożyła czujniki glebowe i systemy obrazowania dronów na 40 000 farmach w Stanach Zjednoczonych, Brazylii i Niemczech. Każda farma generowała 2 000 unikalnych metryk szeregów czasowych co 30 sekund – od poziomów pH po dane z obrazowania multispekralnego – co skutkowało stałym obciążeniem wynoszącym 80 000 zapisów na sekundę z niezwykle wysoką kardynalnością z powodu unikalnych UUID czujników. Ich początkowe monolityczne wdrożenie TimescaleDB w AWS us-east-1 doświadczyło katastrofalnej degradacji wydajności w okresie zbiorów, z latencją zapytań dla analizy trendu plonów trwającą ponad 60 sekund. Dodatkowo, inspektorzy ds. zgodności z GDPR odkryli, że dane z niemieckich farm były replikowane do amerykańskich stref dostępności w celu redundancji, co stwarzało natychmiastowe ryzyko regulacyjne i potencjalne kary w wysokości 4% globalnych przychodów.
Rozwiązanie A: Federowane regionalne klastry z replikami odczytów między regionami.
To podejście zaproponowało wdrożenie niezależnych klastrów InfluxDB w każdym suwerennym regionie, wykorzystując Kafka MirrorMaker do asynchronicznej replikacji tylko zagregowanych, zanonimizowanych statystyk do globalnego klastra raportowego. Główną zaletą była ścisła zgodność z przepisami dotyczącymi pobytu danych, jako że surowa telemetria nigdy nie przekroczyła granic. Jednak asynchroniczna replikacja wprowadziła znaczne opóźnienia w globalnej analityce, z zestaleń danych przekraczających 15 minut. Ponadto rozwiązanie stworzyło jeden punkt awarii w globalnym klastrze, który tracił wszystkie możliwości zapytań, jeśli podziały sieciowe izolowały go od replik regionalnych, naruszając wymagania dotyczące dostępności w czasie rzeczywistym monitorowania plonów.
Rozwiązanie B: Centralizowana chmurowa baza danych TSDB z szyfrowaniem po stronie klienta i powierzeniem kluczy.
Ta strategia sugerowała przyjęcie Amazon Timestream z AES-256 szyfrowaniem po stronie klienta, gdzie europejskie urządzenia przechowywały klucze deszyfrujące lokalnie, teoretycznie spełniając artykuł 44 GDPR dotyczący transferów danych. Korzyści obejmowały zarządzaną infrastrukturę i automatyczne skalowanie bez obciążenia operacyjnego. Kluczowa wada miała charakter prawny, a nie techniczny: sądy europejskie orzekły, że zaszyfrowane dane wciąż stanowią dane osobowe, jeśli kontroler posiada potencjalne środki do deszyfrowania, co tworzyło niejednoznaczność regulacyjną. Dodatkowo, silnik zapytań Timestream miał trudności z wysokokardynalnymi połączeniami pomiędzy milionami unikalnych identyfikatorów sensorów, często kończąc czas na skomplikowanych zapytaniach rolniczych z geospacjalnymi nakładkami.
Rozwiązanie C: Architektura z warstwowym przechowywaniem z agregacją w krawędzi i rekonsyliacją opartą na CRDT.
To rozwiązanie wdrożyło agenty Telegraf w bramach farm, aby wstępnie agregować dane telemetryczne w pięciominutowych interwałach, redukując kardynalność o 95% dzięki statystycznemu podsumowaniu (średnia, maksimum, minimum, liczba) przed wprowadzeniem. Regionalne klastry Cassandra przechowywały gorące dane (30 dni) z kompaktacją Time-To-Live, podczas gdy zadania Apache Spark kompresowały dane historyczne do formatu Parquet w regionalnych kubełkach S3 z kompresją Snappy. Zapytania federacyjne Trino rozkładały się w tych warstwach za pomocą abstrakcji tabel Iceberg, podczas gdy siatka usług Istio egzekwowała ścisłe przestrzeganie geo-fence na poziomie sieci. Wymiana polegała na zwiększonej złożoności architektonicznej i potrzebie zaawansowanej logiki CRDT do scalania danych buforowanych w krawędzi podczas podziałów sieciowych, jednak to unikalnie spełniało wszystkie techniczne i prawne wymogi.
Które rozwiązanie zostało wybrane (i dlaczego).
Zespół inżynieryjny wybrał rozwiązanie C po sześciotygodniowym dowodzie koncepcji, priorytetując pewność prawną i wydajność zapytań nad prostotą operacyjną. Rozwiązanie oparte na CRDT było kluczowe dla środowisk rolniczych, gdzie łączność sieciowa była niestabilna, umożliwiając ciągnikom i dronom buforowanie metryk lokalnie oraz bezstratne scalanie stanów po ponownym połączeniu. Oszczędności kosztów wynikające z kompresji Parquet oraz archiwizacji S3 Glacier – szacowane na 82% redukcji wydatków na przechowywanie w porównaniu z przechowywaniem tylko gorącym – zapewniły wsparcie zarządu dla zwiększonej inwestycji inżynieryjnej.
Wynik.
System produkcyjny obecnie utrzymuje 120 000 zapisów na sekundę z latencją wprowadzania P99 poniżej 30 ms i latencją zapytań analitycznych poniżej 800 ms dla analizy trendów dwunastomiesięcznych we wszystkich 40 000 farmach. Architektura skutecznie przeszła niezależne audyty zgodności GDPR i LGPD (Brazylia), potwierdzając, że surowa telemetria pozostała fizycznie w odpowiednich jurysdykcjach. W trakcie sezonu zbiorów w 2024 roku system przetrwał trzygodzinną całkowitą awarię regionu us-east-1 bez utraty danych, automatycznie kierując ruch do us-west-2 przy zachowaniu ścisłego pobytu danych dla niemieckich farm przez warstwę zapytań geo-federowanych.
Jak zapobiec eksplozjom kardynalności z unikalnymi identyfikatorami urządzeń lub znacznikami czasu o wysokiej częstotliwości, nie tracąc zdolności do analizy telemetrycznej poszczególnych urządzeń?
Wielu młodszych architektów błędnie sugeruje po prostu dodanie więcej partycji Kafka lub poziome skalowanie węzłów Cassandra, aby wchłonąć presję zapisu. Wyrafinowana odpowiedź polega na wdrożeniu hierarchicznej strategii agregacji z użyciem Apache Flink lub Kafka Streams, aby utrzymać „podwójne ścieżki”: surowe dane o wysokiej kardynalności znajdują się w gorącej warstwie (SSD-obsługiwany ScyllaDB) przez 24-48 godzin z agresywnymi politykami TTL, podczas jednoczesnego zapisu wstępnie zagregowanych, niskokardynalnych danych (wg strefy farmy lub typu sprzętu) do warstwy ciepłej. Wymaga to zaprojektowania filtrów Bloom, aby zapobiec duplikatowi przetwarzania podczas zagregowanych okien i zrozumienia, że kardynalność jest zasadniczo problemem przechowywania, a nie jedynie problemem przepustowości, wymagającym starannego wyboru strategii kompaktacji LSM-tree, takich jak kompaktacja Size-Tiered versus Leveled, w zależności od częstotliwości aktualizacji specyficznych wymiarów metrycznych.
Jakie są konkretne kompromisy między używaniem partycjonowania opartego na czasie a partycjonowaniem opartym na hashu dla klucza podstawowego w rozproszonej bazie danych szeregów czasowych, takiej jak Cassandra lub ScyllaDB?
Kandydaci często domyślnie wybierają partycjonowanie oparte na czasie (np. partycjonowanie według dnia), ponieważ jest to logicznie zgodne z zapytaniami obejmującymi zakres czasowy i upraszcza wygaszenie danych bazujące na politykach TTL. Jednakto powoduje poważne gorące punkty na najnowszym węźle partycji podczas intensywnego wprowadzania, naruszając zasadę równomiernego rozmieszczenia w rozproszonych systemach. Właściwe podejście wykorzystuje złożone klucze partycyjne, łączące koszyki czasowe (np. godzinę) z hashem identyfikatora urządzenia, aby rozproszyć zapisy, przy jednoczesnym używaniu kolumn klastrowych dla precyzyjnego znacznika czasu, aby zachować efektywność przeszukiwania zakresu czasowego w każdej partycji. Należy także wziąć pod uwagę problem „szerokiego wiersza” w Cassandra, gdzie nadmierna liczba kolumn klastrowych może powodować napięcie na stercie podczas kompaktacji, co wymaga zastosowania indeksu wtórnego lub strategii indeksu wtórnego SASI (SSTable Attached Secondary Index) dla specyficznych wzorców zapytań, co wprowadza wzmocnienie zapisu, które należy modelować zgodnie z USL (Universal Scalability Law), aby przewidzieć ograniczenia współbieżności.