Reference files, test fixtures, the playground demo project and one design document now use generic, fictitious examples (buildings, energy, water, grants, municipal services). The playground demo (17 fixtures plus the embedded demo state) tells one consistent story: a municipal customer chatbot that pre-screens housing-benefit applications, classified under Annex III point 5(a). The embedded demo copies were edited in place rather than regenerated, because they already carry newer AI Act dates than the fixture files. Legal text is unchanged. Test semantics are unchanged. Four dark-theme onboarding screenshots with outdated placeholder text are removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
410 lines
16 KiB
Markdown
410 lines
16 KiB
Markdown
# Real-Time Streaming for AI Applications
|
|
|
|
**Last updated:** 2026-06-24
|
|
**Status:** GA
|
|
**Category:** Data Engineering for AI
|
|
**Type:** reference
|
|
**Source:** https://learn.microsoft.com/fabric/real-time-intelligence/overview
|
|
**Verified:** 2026-07-24
|
|
**Verified by:** judge-v3.1
|
|
|
|
---
|
|
|
|
## Innhold
|
|
|
|
- [Introduksjon](#introduksjon)
|
|
- [Eventstream Connectors and Topologies](#eventstream-connectors-and-topologies)
|
|
- [Structured Streaming with Spark](#structured-streaming-with-spark)
|
|
- [KQL Database for Time-Series Analytics](#kql-database-for-time-series-analytics)
|
|
- [Event Filtering and Derived Streams](#event-filtering-and-derived-streams)
|
|
- [Streaming SLAs and Backpressure Handling](#streaming-slas-and-backpressure-handling)
|
|
- [Arkitekturmonstre for AI med sanntidsdata](#arkitekturmonstre-for-ai-med-sanntidsdata)
|
|
- [Referanser](#referanser)
|
|
- [For arkitekten](#for-arkitekten)
|
|
|
|
## Introduksjon
|
|
|
|
Sanntidsdatastrømming er en fundamental byggestein for AI-applikasjoner som krever umiddelbar respons på hendelser -- fra IoT-sensorer og transaksjoner til brukeratferd og systemmetrikker. Microsoft Fabric Real-Time Intelligence kombinert med Azure Event Hubs og Apache Kafka gir en komplett plattform for inntak, transformasjon og analyse av strømmedata som mater AI-modeller med oppdatert informasjon.
|
|
|
|
For norsk offentlig sektor er sanntidsarkitektur særlig relevant for overvåking av vannforsyning (kommunale vannverk), helseovervåking, energistyring og beredskapsrespons. Evnen til å oppdage avvik i sanntid og utløse automatiserte handlinger basert på AI-prediksjoner kan redusere responstider dramatisk og forbedre tjenestekvalitet.
|
|
|
|
Denne referansen dekker arkitekturmønstre for å integrere Event Hubs, Kafka og Fabric Eventstream med AI-applikasjoner, inkludert Spark Structured Streaming, KQL Database for tidsserieanalyse, og mønster for hendelsesfiltrering og avledede strømmer.
|
|
|
|
---
|
|
|
|
## Eventstream Connectors and Topologies
|
|
|
|
### Fabric Eventstream Overview
|
|
|
|
Microsoft Fabric Eventstream er en fullstendig administrert hendelsesinntak- og strømmetjeneste som muliggjør sanntidsdatabehandling uten kode.
|
|
|
|
| Kilde-type | Eksempler | Autentisering |
|
|
|---|---|---|
|
|
| Microsoft-kilder | Azure Event Hubs, Azure IoT Hub, Azure Service Bus | Managed identity, SAS |
|
|
| Database CDC | Azure SQL DB, PostgreSQL, MySQL, Cosmos DB, SQL MI | Connection string |
|
|
| Kafka-kilder | Confluent Cloud, Apache Kafka, Amazon MSK | SASL/PLAIN, OAuth |
|
|
| Andre skyer | Amazon Kinesis, Google Cloud Pub/Sub | IAM credentials |
|
|
| Fabric-hendelser | Workspace item events, Blob Storage events | Built-in |
|
|
|
|
### Topology Patterns
|
|
|
|
```
|
|
┌──────────────┐
|
|
IoT Hub ────────>│ │────> KQL Database (tidsserier)
|
|
│ │
|
|
Event Hubs ─────>│ Eventstream │────> Lakehouse (Delta tables)
|
|
│ │
|
|
Kafka ──────────>│ (Filter + │────> Spark Notebook (ML)
|
|
│ Transform) │
|
|
CDC (SQL) ──────>│ │────> Derived Stream (Real-Time Hub)
|
|
└──────────────┘
|
|
```
|
|
|
|
### Konfigurere Event Hubs som kilde
|
|
|
|
```python
|
|
# Eventstream configuration via Fabric UI or API
|
|
# Event Hub connection parameters
|
|
event_hub_config = {
|
|
"namespace": "my-eventhub-ns.servicebus.windows.net",
|
|
"event_hub": "ai-telemetry",
|
|
"consumer_group": "$Default",
|
|
"data_format": "Json",
|
|
"authentication": "SharedAccessKey"
|
|
}
|
|
```
|
|
|
|
### Destinasjoner
|
|
|
|
Eventstream støtter flere destinasjoner parallelt:
|
|
|
|
| Destinasjon | Bruksområde | Latens |
|
|
|---|---|---|
|
|
| **Eventhouse (KQL Database)** | Tidsserieanalyse, ad-hoc-spørringer | Sekunder |
|
|
| **Lakehouse** | Historisk analyse, Delta Lake lagring | Minutter |
|
|
| **Spark Notebook** | Sanntids ML-inferens | Sekunder |
|
|
| **Derived Stream** | Viderefordeling til andre forbrukere | Sub-sekund |
|
|
| **Fabric Activator** | Automatiserte handlinger og varsler | Sekunder |
|
|
| **Custom Endpoint** | Ekstern applikasjonsintegrasjon | Variabel |
|
|
|
|
---
|
|
|
|
## Structured Streaming with Spark
|
|
|
|
### Spark Structured Streaming i Fabric
|
|
|
|
Fabric Notebooks kan lese direkte fra Eventstream via Spark Structured Streaming uten manuell tilkoblingskonfigurasjon.
|
|
|
|
```python
|
|
# Les strømmende data fra Eventstream i Fabric Notebook
|
|
# Parameter-verdier settes automatisk via "Read with Spark" i UI
|
|
|
|
df_stream = (
|
|
spark.readStream
|
|
.format("fabricEventStream")
|
|
.option("eventstream.itemid", "<auto-populated>")
|
|
.option("eventstream.datasourceid", "<auto-populated>")
|
|
.load()
|
|
)
|
|
|
|
# Vis skjema
|
|
df_stream.printSchema()
|
|
```
|
|
|
|
### Transformasjoner på strømmende data
|
|
|
|
```python
|
|
from pyspark.sql.functions import col, window, avg, count, from_json
|
|
from pyspark.sql.types import StructType, StringType, DoubleType, TimestampType
|
|
|
|
# Definer skjema for innkommende JSON
|
|
schema = StructType() \
|
|
.add("sensorId", StringType()) \
|
|
.add("temperature", DoubleType()) \
|
|
.add("humidity", DoubleType()) \
|
|
.add("timestamp", TimestampType())
|
|
|
|
# Parse JSON og beregn vindusaggregater
|
|
parsed_stream = (
|
|
df_stream
|
|
.select(from_json(col("body").cast("string"), schema).alias("data"))
|
|
.select("data.*")
|
|
)
|
|
|
|
# 5-minutters glidende vindu med aggregater
|
|
windowed_aggregates = (
|
|
parsed_stream
|
|
.withWatermark("timestamp", "10 minutes")
|
|
.groupBy(
|
|
window(col("timestamp"), "5 minutes", "1 minute"),
|
|
col("sensorId")
|
|
)
|
|
.agg(
|
|
avg("temperature").alias("avg_temp"),
|
|
avg("humidity").alias("avg_humidity"),
|
|
count("*").alias("event_count")
|
|
)
|
|
)
|
|
```
|
|
|
|
### Skrive til Delta Lake (Lakehouse)
|
|
|
|
```python
|
|
# Skriv strømmede data til Delta-tabell med optimalisering
|
|
query = (
|
|
windowed_aggregates
|
|
.writeStream
|
|
.format("delta")
|
|
.outputMode("append")
|
|
.option("checkpointLocation", "Tables/_checkpoints/sensor_agg")
|
|
.trigger(processingTime="1 minute") # Batch hvert minutt
|
|
.toTable("sensor_aggregates")
|
|
)
|
|
|
|
query.awaitTermination()
|
|
```
|
|
|
|
### Optimalisering av strømmeskrivinger
|
|
|
|
| Teknikk | Beskrivelse | Anbefalt bruk |
|
|
|---|---|---|
|
|
| **Trigger interval** | `processingTime="1 minute"` batches hendelser | Reduserer små filer |
|
|
| **Optimized Write** | `spark.databricks.delta.optimizeWrite.enabled` | Automatisk filstørrelsesoptimalisering |
|
|
| **Partitioning** | `partitionBy("date", "sensorId")` | Når filtrering på partisjonsnøkler er vanlig |
|
|
| **Repartition** | `repartition(48)` før skriving | Parallellisering over CPU-kjerner |
|
|
| **Coalesce** | `coalesce(4)` for lav throughput | Unngår for mange små filer |
|
|
|
|
---
|
|
|
|
## KQL Database for Time-Series Analytics
|
|
|
|
### Eventhouse og KQL Database
|
|
|
|
KQL Database i Fabric er optimalisert for tidsseriedata og gir sub-sekund spørringsrespons over milliarder av rader.
|
|
|
|
```kql
|
|
// Tidsserieanalyse med KQL
|
|
// Beregn glidende gjennomsnitt for sensortemperatur
|
|
SensorData
|
|
| where Timestamp > ago(24h)
|
|
| summarize AvgTemp = avg(Temperature) by bin(Timestamp, 5m), SensorId
|
|
| render timechart
|
|
```
|
|
|
|
```kql
|
|
// Anomalideteksjon med innebygd series_decompose_anomalies
|
|
let min_t = ago(7d);
|
|
let max_t = now();
|
|
SensorData
|
|
| make-series AvgTemp = avg(Temperature)
|
|
on Timestamp from min_t to max_t step 1h
|
|
by SensorId
|
|
| extend (anomalies, score, baseline) =
|
|
series_decompose_anomalies(AvgTemp, 1.5, -1, 'linefit')
|
|
| mv-expand Timestamp to typeof(datetime),
|
|
AvgTemp to typeof(double),
|
|
anomalies to typeof(int),
|
|
score to typeof(double),
|
|
baseline to typeof(double)
|
|
| where anomalies != 0
|
|
```
|
|
|
|
### Sammenligning: KQL Database vs Lakehouse for strømmedata
|
|
|
|
| Egenskap | KQL Database | Lakehouse (Delta) |
|
|
|---|---|---|
|
|
| **Optimal for** | Tidsserier, logdata, IoT | Strukturert analyse, ML-trening |
|
|
| **Spørrespråk** | KQL | SQL, PySpark |
|
|
| **Latens** | Sub-sekund | Sekunder til minutter |
|
|
| **Retensjon** | Konfigurerbar policy | Ubegrenset (manuell VACUUM) |
|
|
| **Innebygd ML** | Anomalideteksjon, forecasting | Via notebooks |
|
|
| **Format** | Proprietært (optimalisert) | Delta Lake (åpent) |
|
|
| **One Logical Copy** | Ja, til OneLake | Native |
|
|
|
|
---
|
|
|
|
## Event Filtering and Derived Streams
|
|
|
|
### Filtrering i Eventstream
|
|
|
|
Eventstream støtter no-code transformasjoner direkte i strømmen:
|
|
|
|
- **Filter**: Fjern hendelser basert på betingelser
|
|
- **Manage Fields**: Velg, omdøp, fjern felt
|
|
- **Group By**: Aggreger over tidsvindu
|
|
- **Union**: Kombiner flere strømmer
|
|
- **Expand**: Flatten nestede strukturer
|
|
|
|
### Derived Streams (avledede strømmer)
|
|
|
|
```
|
|
Eventstream (rå data)
|
|
│
|
|
├── Filter: temperature > 50 ──> Derived Stream: "high-temp-alerts"
|
|
│ │
|
|
│ ├──> Activator (varsling)
|
|
│ └──> KQL Database
|
|
│
|
|
├── Group By: 5min avg ────────> Derived Stream: "sensor-aggregates"
|
|
│ │
|
|
│ └──> Lakehouse
|
|
│
|
|
└── All events ────────────────> KQL Database (rå logging)
|
|
```
|
|
|
|
### Content-Based Routing
|
|
|
|
```python
|
|
# Pseudo-kode for content-based routing via Spark
|
|
from pyspark.sql.functions import col
|
|
|
|
# Les fra Eventstream
|
|
raw_stream = spark.readStream.format("fabricEventStream").load()
|
|
|
|
# Route basert på hendelsestype
|
|
critical_events = raw_stream.filter(col("severity") == "CRITICAL")
|
|
info_events = raw_stream.filter(col("severity") == "INFO")
|
|
|
|
# Skriv til forskjellige destinasjoner
|
|
critical_query = (
|
|
critical_events.writeStream
|
|
.format("delta")
|
|
.toTable("critical_alerts")
|
|
)
|
|
|
|
info_query = (
|
|
info_events.writeStream
|
|
.format("delta")
|
|
.toTable("info_logs")
|
|
)
|
|
```
|
|
|
|
---
|
|
|
|
## Streaming SLAs and Backpressure Handling
|
|
|
|
### SLA-dimensjoner for strømmesystemer
|
|
|
|
| Dimensjon | Mål | Metric |
|
|
|---|---|---|
|
|
| **End-to-end latens** | < 5 sekunder for varsler | P99 latens |
|
|
| **Throughput** | Minimum events/sek som må håndteres | Events per second |
|
|
| **Data completeness** | Ingen tapte hendelser | Missing event rate |
|
|
| **Processing guarantee** | At-least-once eller exactly-once | Delivery semantics |
|
|
| **Recovery time** | Tid fra feil til normal drift | RTO |
|
|
|
|
### Backpressure-strategier
|
|
|
|
```python
|
|
# Spark Structured Streaming med rate limiting
|
|
query = (
|
|
df_stream
|
|
.writeStream
|
|
.format("delta")
|
|
.option("maxOffsetsPerTrigger", 10000) # Begrens per batch
|
|
.trigger(processingTime="30 seconds")
|
|
.toTable("processed_events")
|
|
)
|
|
```
|
|
|
|
### Event Hubs Partisjonering for skalering
|
|
|
|
```python
|
|
# Event Hubs partisjonskonfigurasjon
|
|
# Anbefalt: 4-32 partisjoner avhengig av throughput
|
|
# Hver partisjon støtter opptil 1 MB/s inntak, 2 MB/s uttak
|
|
|
|
# Fabric Eventstream håndterer automatisk partisjonskonsumering
|
|
# For manuell Kafka-tilgang:
|
|
kafka_config = {
|
|
"kafka.bootstrap.servers": "eventstream-xxx.servicebus.windows.net:9093",
|
|
"subscribe": "es_topic",
|
|
"kafka.sasl.mechanism": "PLAIN",
|
|
"kafka.security.protocol": "SASL_SSL",
|
|
"startingOffsets": "latest",
|
|
"maxOffsetsPerTrigger": 50000
|
|
}
|
|
|
|
df = spark.readStream.format("kafka").options(**kafka_config).load()
|
|
```
|
|
|
|
### Retry Policy for Spark Job Definitions
|
|
|
|
For produksjonsmiljøer anbefales Spark Job Definitions over Notebooks:
|
|
|
|
| Parameter | Anbefalt verdi | Begrunnelse |
|
|
|---|---|---|
|
|
| **Retry enabled** | Ja | Automatisk gjenstart ved feil |
|
|
| **Max retries** | Ubegrenset | For kontinuerlige strømmejobber |
|
|
| **Retry interval** | 60 sekunder | Unngå storm of retries |
|
|
| **Checkpoint** | Alltid konfigurert | Gjenoppta fra siste posisjon |
|
|
|
|
### Monitoring
|
|
|
|
Spark Structured Streaming UI gir innebygde metrikker:
|
|
- Input Rate (hendelser/sekund)
|
|
- Process Rate (hendelser/sekund)
|
|
- Batch Duration (ms)
|
|
- Input Rows per batch
|
|
- Operation Duration breakdown
|
|
|
|
---
|
|
|
|
## Arkitekturmonstre for AI med sanntidsdata
|
|
|
|
### Lambda Architecture (hybrid batch + streaming)
|
|
|
|
```
|
|
┌───────────────────┐
|
|
│ Event Hubs / │
|
|
│ Kafka Source │
|
|
└─────┬────┬────────┘
|
|
│ │
|
|
┌───────────┘ └──────────────┐
|
|
│ │
|
|
┌────────▼────────┐ ┌─────────▼──────────┐
|
|
│ Speed Layer │ │ Batch Layer │
|
|
│ (Eventstream │ │ (Data Factory + │
|
|
│ + KQL DB) │ │ Lakehouse) │
|
|
└────────┬─────────┘ └─────────┬──────────┘
|
|
│ │
|
|
┌────────▼───────────────────────────────▼──────────┐
|
|
│ Serving Layer │
|
|
│ (Power BI, AI Models, REST APIs) │
|
|
└───────────────────────────────────────────────────┘
|
|
```
|
|
|
|
### Kappa Architecture (rent strømmende)
|
|
|
|
Forenklet arkitektur der all data behandles som strømmer:
|
|
|
|
```
|
|
Event Source ──> Eventstream ──> Spark Structured Streaming
|
|
│
|
|
├──> Delta Table (append-only)
|
|
├──> ML Inference (real-time)
|
|
└──> KQL Database (analytics)
|
|
```
|
|
|
|
---
|
|
|
|
## Referanser
|
|
|
|
- [Overview of Microsoft Fabric Eventstreams](https://learn.microsoft.com/en-us/fabric/real-time-intelligence/event-streams/overview) -- Komplett oversikt over Eventstream-kapabiliteter
|
|
- [Query Eventstream from Notebook with Spark Structured Streaming](https://learn.microsoft.com/en-us/fabric/data-engineering/notebook-with-event-stream) -- Integrasjon mellom Notebook og Eventstream
|
|
- [Get streaming data into Lakehouse with Spark Structured Streaming](https://learn.microsoft.com/en-us/fabric/data-engineering/lakehouse-streaming-data) -- Optimalisering av Delta Lake-skrivinger
|
|
- [What is Real-Time Intelligence?](https://learn.microsoft.com/en-us/fabric/real-time-intelligence/overview) -- Oversikt over Real-Time Intelligence
|
|
- [Introduction to Fabric Real-Time Hub](https://learn.microsoft.com/en-us/fabric/real-time-hub/real-time-hub-overview) -- Real-Time Hub connectors og integrasjon
|
|
- [Get events from Azure Event Hubs into Real-Time hub](https://learn.microsoft.com/en-us/fabric/real-time-hub/add-source-azure-event-hubs) -- Event Hubs-kobling
|
|
- [Add and manage destinations in an Eventstream](https://learn.microsoft.com/en-us/fabric/real-time-intelligence/event-streams/add-manage-eventstream-destinations) -- Alle støttede destinasjoner
|
|
- [Get data from Azure Event Hubs](https://learn.microsoft.com/en-us/fabric/real-time-intelligence/get-data-event-hub) -- Direct ingestion til KQL Database
|
|
|
|
---
|
|
|
|
## For arkitekten
|
|
|
|
- **Bruk denne referansen** når brukeren trenger sanntidsdatabehandling for AI-modeller, IoT-integrasjon, eller hendelsesdrevet arkitektur på Microsoft Fabric.
|
|
- Anbefal **Eventstream + KQL Database** for tidsserieanalyse og anomalideteksjon med sub-sekund latens, og **Eventstream + Lakehouse** for historisk ML-trening.
|
|
- For norsk offentlig sektor: Fremhev at Fabric Eventstream kjorer som SaaS i europeisk region (Norway East/West Europe), noe som forenkler personvernhensyn sammenlignet med selvhostede Kafka-clustere.
|
|
- Bruk **Spark Job Definitions** (ikke Notebooks) i produksjon for strømmejobber, med retry-policy aktivert for høy tilgjengelighet.
|
|
- Anbefal **Derived Streams** for å dele sanntidsdata mellom team uten å duplisere infrastruktur -- en enkelt Eventstream kan mate flere destinasjoner med forskjellige transformasjoner.
|