Potok danych IoT na Azure: urządzenia — IoT Hub — Event Hubs — Functions — Time Series — panel React
Podłączenie 10 000 urządzeń bezpośrednio do bazy danych to nie potok — to wąskie gardło. Produkcyjny potok danych IoT musi obsługiwać miliony wiadomości dziennie, przetrwać awarie bez utraty danych oraz jednocześnie serwować zapytania w czasie rzeczywistym i historyczne.
Architektura potoku
Etap 1: Ingest -> Azure IoT Hub (MQTT/HTTPS) Etap 2: Routing -> Routing wiadomości do punktów końcowych wg typu Etap 3: Przetwarzanie -> Azure Functions (wyzwalacz Event Hubs) Etap 4: Serwowanie -> Time Series Insights + Cosmos DB
Azure Functions — wyzwalacz Event Hub
app.eventHub("processTelemetry", {
connection: "EventHubsConn",
eventHubName: "telemetry",
cardinality: "many",
handler: async (events, context) => {
for (const e of events) {
await tsi.write(e.deviceId, e.timestamp, e.readings);
await cosmos.upsert({id: e.deviceId, lastSeen: e.timestamp});
}
}
});
Strategia partycjonowania dla Event Hubs
Event Hubs wykorzystuje partycje do osiągania przepustowości — każda partycja to niezależny, uporządkowany strumień. Grupy konsumentów odczytują partycje równolegle, więc więcej partycji oznacza więcej równoległego przetwarzania. Częstym błędem jest niedostateczne partycjonowanie: rozpoczęcie od 4 partycji i odkrycie, że Azure Functions nie są w stanie skalować się do przetwarzania 100 000 wiadomości na sekundę, gdy błąd firmware powoduje, że wszystkie urządzenia jednocześnie wysyłają zdarzenia błędów.
Liczby partycji nie można zmienić po utworzeniu. Zaplanuj 2–5-krotność oczekiwanej szczytowej przepustowości. Użyj identyfikatora urządzenia jako klucza partycji — zapewnia to uporządkowanie wszystkich wiadomości z jednego urządzenia w obrębie partycji, co upraszcza rekonstrukcję szeregów czasowych i zarządzanie stanem w twoich Functions.
Obsługa burz ponownych połączeń urządzeń
Gdy awaria chmury się kończy, każde urządzenie próbuje połączyć się ponownie jednocześnie. Przy 10 000 urządzeń tworzy to efekt tłumu (thundering herd): miliony zbuforowanych wiadomości uderzają w Event Hubs w ciągu sekund. Twoje Functions przetwarzające muszą obsłużyć to płynnie — zaimplementuj wykładniczy backoff z jitterem w firmware urządzenia i skonfiguruj Event Hubs z wystarczającą liczbą jednostek przepustowości i retencją, aby wchłonąć skok.
int backoff_ms = BASE_BACKOFF_MS;
while (!connected) {
int jitter = random(0, backoff_ms / 2);
vTaskDelay(pdMS_TO_TICKS(backoff_ms + jitter));
backoff_ms = MIN(backoff_ms * 2, MAX_BACKOFF_MS);
connected = mqtt_connect();
}
Architektura ścieżki zimnej i gorącej
Potoki danych IoT mają zwykle dwie ścieżki: ścieżkę gorącą do przetwarzania w czasie rzeczywistym (panele, alerty, wykrywanie anomalii) oraz ścieżkę zimną do magazynowania historycznego i analityki wsadowej. Ścieżka gorąca priorytetyzuje opóźnienie — Azure Functions przetwarzające zdarzenia Event Hub i wypychające je do SignalR na potrzeby paneli na żywo. Ścieżka zimna priorytetyzuje kompletność — wszystkie surowe wiadomości zapisywane do Azure Blob Storage w formacie Parquet do późniejszej analizy z Azure Synapse lub Databricks.
Zaprojektowanie obu ścieżek od pierwszego dnia pozwala uniknąć częstego problemu odrzucania surowych danych, które później okazują się cenne. Magazyn jest tani; rekonstrukcja historycznych danych z czujników, których nigdy nie zapisano, jest niemożliwa. Nasz standardowy potok zapisuje wszystkie surowe wiadomości urządzeń do zimnego magazynu, a przetworzony podzbiór do warstwy ciepłej — surowe dane zawsze można przetworzyć ponownie, ale nie da się ich „odzyskać z niebytu".
Tworzysz produkt IoT?
FSS to pełnozakresowy zespół inżynierii IoT — sprzęt, firmware, chmura i aplikacje mobilne w jednym miejscu.