Zum Inhalt springen
Codedock
LeistungenWie wir arbeitenInsightsFallstudienKarriereKontakt
Zurück zu allen Artikeln
Enterprise-Integration

·

7 Min Lesezeit

·

Geschrieben von Tomáš Mikeš

Millionen Fotos von IoT-Geräten auf Azure ingestieren: von der Kamera zur Cloud

Für Fotopast.cloud verarbeiten wir Fotos aus Tausenden Wildkameras. Die Pipeline, die skaliert: Event-Grid-Trigger, Blob-Storage-Tiering, Deduplikation und Kostenoptimierung für Bulk-Uploads.

IoTAzureBlob StoragePipeline

Ein IoT-Gerät sendet alle Stunde ein Foto. Klingt nach wenig. Mal 5 000 Geräten im Betrieb ergibt das 120 000 Fotos pro Tag. Ein wesentlicher Teil kommt als Batch-Upload einmal täglich (schlafende Tiere fotografiert die Wildkamera nicht, aber bei Abenddämmerungsaktivität sendet sie 40-60 Fotos auf einmal). Dieses Volumen ohne Drops und zu vernünftigen Kosten zu ingestieren, braucht mehr als „einen API-Endpoint, der in S3 schreibt“.

Das ist die Architektur, die wir für Fotopast.cloud gebaut haben und die seit ~18 Monaten ohne Eingriffe außer Scaling läuft.

Phase 1: Ingestion — ein HTTP-Endpoint, der nichts verliert

Das Gerät sendet einen POST mit Multipart — Foto plus JSON-Metadaten (GPS, Zeit, Device-ID, Akku). Der Endpoint muss:

  • Innerhalb von 5 Sekunden antworten, sonst retry des Geräts — was Daten verdoppelt
  • Auch leicht falsch formatiertes JSON akzeptieren (ältere Firmware) und aufholen
  • Auth-Token prüfen — aber Ingestion nicht auf langsame Auth-Checks warten lassen (Pre-Validierung am Edge)

Unsere Lösung: Azure Functions auf Consumption-Plan, HTTP-Trigger. Die Funktion schreibt nur den Blob in einen Landing-Container und gibt 202 Accepted zurück. Keine Business-Validierung, kein DB-Write. Durchschnittliche Latenz 120 ms, P99 800 ms.

Business-Logic läuft später gegen den Landing-Bucket. Wenn Ingestion schlechte Daten toleriert, ist Drop-Rate = 0.

Phase 2: Deduplikation — das gleiche Foto nicht zweimal

Firmware-Edge-Cases senden das gleiche Foto mehrfach. Unsere Lösung: Landing-Blob mit Namen {deviceId}/{photoHash}.jpg. SHA-256 des Binärinhalts. Existiert ein Blob mit diesem Namen, ist Overwrite ein No-op.

Der Hash wird in der Processing-Phase berechnet (nicht im Ingestion — dort zählt Geschwindigkeit), aber jedes Foto wird in der DB nach Hash indiziert. Zwei Einträge desselben Fotos landen nach Hashing auf derselben DB-Zeile und Duplikate verschwinden.

Phase 3: Event Grid — Processing ohne Polling

Event Grid feuert bei jedem Blob-Upload ein Event. Eine zweite Azure Function wird vom Event ausgelöst, nicht durch Polling — „alle 10 s neue Dateien prüfen“ wäre langsam und teuer.

Die Processing-Function:

  • Berechnet den Hash, legt DB-Eintrag an (idempotent)
  • Erzeugt 3 Thumbnail-Größen (400 px, 1200 px, full) und speichert sie in den Hot-Container
  • Extrahiert EXIF-Metadaten (GPS, Zeit)
  • Sendet Push-Notification an den Nutzer (falls aktiv)
  • Verschiebt den Original-Blob in den Cold-Container (Archiv, günstigerer Tier)

Warum Thumbnails vorab statt on-the-fly? Ein Foto wird ~50-200× gelesen (Listenansicht, Detail, Sharing). Thumbnails einmal erstellen und für immer cachen ist 10-50× günstiger als Server-side-Resize bei jedem Read.

Phase 4: Blob-Storage-Tiering — Kosten fallen um Faktor 3-5

Azure Blob hat drei Tiers:

  • Hot: ~$0,018/GB/Monat, Reads sofort. Wir nutzen das für Thumbnails.
  • Cool: ~$0,010/GB/Monat, Reads nach ~1 min Wakeup. Volle Fotos < 30 Tage alt.
  • Archive: ~$0,002/GB/Monat, 1-15 Stunden Rehydration. Fotos > 1 Jahr alt.

Automatische Lifecycle-Policy: jedes Foto geht nach 30 Tagen nach Cool, nach 12 Monaten ins Archive. Business-Logik: 90 % der Nutzer schauen nur auf die letzten 30 Tage, 99 % schauen nicht auf Dinge älter als ein Jahr — aber wir MÜSSEN sie speichern für Compliance / Beweise.

Für Fotopast hat das die Storage-Kosten nach dem ersten Betriebsjahr um 60 % gesenkt — von ~$1 200/Monat auf ~$480/Monat.

Phase 5: Backpressure und Rate-Limiting

Ein einzelnes Gerät mit fehlerhafter Firmware beginnt 100 Fotos pro Minute zu senden. Ohne Schutz würde das die Queue füllen und Processing für alle anderen verlangsamen. Device-Level-Rate-Limit:

  • Redis-Counter pro deviceId am Ingestion-Endpoint
  • Limit 200 Fotos / 5 min. Überschreitung = 429 Too Many Requests zurück (Gerät versucht später erneut)
  • Alert, wenn 10+ Geräte das Limit überschreiten (möglicher fleet-weiter Firmware-Bug)

Die Ergebnisse in Zahlen

Nach 18 Monaten Fotopast-Betrieb:

  • ~45 Mio. Fotos im System
  • ~120 TB gesamt (Großteil im Archive-Tier)
  • Ingestion-Durchsatz Peak 500 Fotos/Minute
  • P99-Latenz API-End-to-End: 950 ms
  • Azure-Kosten ~$600/Monat (inkl. Compute und Storage)
  • 0 verlorene Fotos in 18 Monaten

Was wir anders machen würden

Drei Lehren für das nächste IoT-Projekt:

  • Dead-Letter-Queue vom ersten Tag. Wir haben sie nach einem Monat hinzugefügt, nachdem wir erste Edge-Case-Daten sahen.
  • Lifecycle-Policy an Tag 1, nicht Tag 60. Einen Backlog bestehender Fotos in Cool-Tier zu verschieben ist teurer als upfront richtig einzustellen.
  • Per-Device-Metriken monitoren, nicht nur System-Level. Aggregat „500 Fotos/Min“ ist ein gesunder Durchschnitt. Aber 10 Geräte je 50 Fotos/Min = fehlerhafte Firmware, die Sie nur per-Device finden.

Sonst — 2 Monate Lieferung und 18 Monate Betrieb ohne Eingriff — ist das eine Architektur, die sich nicht geändert, sondern nur skaliert hat.

Arbeiten Sie an etwas Ähnlichem?

Vereinbaren Sie ein 30-minütiges technisches Gespräch. Kein Vertriebsprozess — direktes architektonisches Feedback.

Termin auswählen

Architektur, Cloud und Integration für komplexe Systeme. Ein Senior-Architekt in jedem Projekt.

Navigation

LeistungenWie wir arbeitenInsightsFallstudienKarriereKontaktAgentur vs. Freelancer vs. wir

Leistungen

EntwicklungCloudDevOpsAI & DatenBeratungDelivery

Kontakt

CodeDock s.r.o.

Zlenická 863/9, 104 00 Praha 22

Tschechische Republik

info@codedock.com

IČO: 14292769

DIČ: CZ14292769


© 2026 Codedock

KontaktDatenschutzerklärung
Termin buchen