Stream concepts and algorithms
This lecture defines unbounded event streams and the systems that process them (windows, event time, watermarks, Lambda and Kappa, delivery guarantees). It also covers one-pass sketches (reservoir sampling, Bloom filters, Flajolet-Martin, DGIM, Count-Min). After this page you can count window outputs, apply a watermark, and work each sketch on small data.
Bloom Filters, Visualized (Definitely No or Probably Yes)Generalist Programmer · Bloom filters visualised
What are Bloom Filter Explained with Example (Big Data Analytics)Gyanpur · Bloom filter for big data
Reservoir Sampling AlgorithmCoding Interview Prep · Reservoir sampling
Understanding Watermark in Stream Processing In an Interactive WayTimeplus · Watermarks in stream processing
Lambda vs Kappa ArchitectureArpit Vaish · Lambda vs KappaBatch versus stream processingSearch on YouTube
Batch processing works on a bounded data set at rest. Stream processing works on unbounded events that keep arriving. Batch runs periodically (hourly, nightly) with latency of minutes to hours. Streaming runs continuously with latency of milliseconds to seconds.
| Aspect | Batch processing | Stream processing |
|---|---|---|
| Input | Bounded, finite data set at rest | Unbounded events that keep arriving |
| When it runs | Periodically: hourly, nightly | Continuously, as data arrives |
| Latency | Minutes to hours | Milliseconds to seconds |
| Answer | Exact, over the complete data | Incremental, per window, may be approximate |
| Typical tools | MapReduce, Spark, Hive, Pig | Kafka, Spark Structured Streaming, Flink |
| Example | Monthly electricity bill | Smart-meter alert when load spikes now |
Batch asks: what happened? Streaming asks: what is happening right now, and what should we do about it?
What a data stream isSearch on YouTube
A data stream is a potentially infinite, time-ordered sequence of events. Events arrive continuously, often at high and varying speed. Each event is usually seen only once.
Five properties define a stream:
- Continuous. Data keeps arriving. There is no end-of-file to wait for.
- Unbounded. Total size is unknown and unlimited. You cannot store it all.
- Time-ordered. Each event carries a timestamp. Order and recency matter.
- Fast, bursty. Arrival rate is high and changes. A sale or a match spikes it.
- Transient. Events are processed on the fly, then discarded or archived.
C-U-T, F-T: "Cut Fast Traffic"
Continuous · Unbounded · Time-ordered · Fast-bursty · Transient. A stream is traffic you cut into pieces as it passes. You cannot rewind it.
Stream sources and questionsSearch on YouTube
Streams come from sensors, users, markets, machines and phones. Each source has a typical standing question:
- IoT sensors. Temperature, vibration, smart meters. Query: alert if any machine exceeds 80°C.
- Clickstreams. Every page view, click and add-to-cart. Query: trending products in the last 10 min.
- Financial ticks. Stock trades, UPI and card transactions. Query: flag a card used in two cities within minutes.
- Logs and metrics. Web server, application and security logs. Query: 5xx error rate per minute.
- Social media. Posts, likes, hashtags, comments. Query: top hashtags in the last hour.
- Mobility and GPS. Ride-hailing, delivery fleets, buses. Query: surge pricing by area demand.
Why stream processing is hardSearch on YouTube
Six constraints shape every streaming design:
- Single pass. Each event is seen once. You cannot rewind and re-scan the stream like a file.
- Bounded memory. Data is unlimited but RAM is limited. Keep summaries, samples or sketches, not everything.
- Low latency. The answer is worth most now. A fraud alert after an hour is useless.
- Approximate answers. Systems often trade a little accuracy for big savings. Unique users ±2% is fine.
- Out-of-order data. Network delays mean an event from 10:00 may arrive after one from 10:02.
- Variable rate. Bursts can exceed capacity. The system needs buffering and backpressure.
Stream data modelSearch on YouTube
Each element is a tuple: a key, one or more values, and a timestamp. The schema may be fixed (sensor readings) or semi-structured (JSON click events). A stream is append-only: the past is never updated, and new facts are appended. Queries see the stream through a window of recent events or a compact summary (synopsis). Many streams can be processed together, e.g. join clicks with ad impressions.
Example from the slides, a temperature stream S:
| sensor | temp | t |
|---|---|---|
| s7 | 41.2 | 10:00:03 |
| s2 | 29.8 | 10:00:03 |
| s7 | 41.9 | 10:00:04 |
| s5 | 33.1 | 10:00:05 |
The stream continues forever. This page calls each element an event below.
DSMS architectureSearch on YouTube
A Data Stream Management System (DSMS) has five parts. They are input streams, the stream processor with its standing and ad-hoc queries, and output streams. The other two are limited working storage and archival storage.
Standing versus ad-hoc queriesSearch on YouTube
A standing (continuous) query is registered once and evaluated on every new event or window. Example: emit an alert whenever any sensor reads above 40°C. Example: every minute, output the average temperature per sensor over the last 5 minutes. Implementation keeps only the state the query needs, e.g. a running sum and count per sensor.
An ad-hoc (one-time) query is asked once about the current state of the stream. Example: what was the maximum temperature in the last hour? It can only be answered if the system kept enough: a window of the last hour, or a summary like max per hour. Design rule: anticipate likely ad-hoc questions and keep a sliding window or sketch for them.
WindowsSearch on YouTube
A window bounds an unbounded stream so a query can run on recent events. Three types exist:
- Tumbling. Fixed size, no overlap. Each event belongs to exactly one window.
- Sliding. Fixed size, slides by a smaller step. Windows overlap, so events repeat.
- Session. Variable length. It closes after a gap of inactivity.
The slides use the same eight events everywhere: s.
Worked example. Check the slide counts for the eight events at .
Tumbling, size 5 s. Windows are , , .
Sliding, size 6 s, slide 3 s. Windows are , , , .
Session, 3 s gap. Gaps between consecutive events are 1.5, 1.5, 2, 1.5, 3.5, 1, 2. Only the gap (3.5 s) exceeds 3 s, so the session closes there.
Event time, processing time, watermarkSearch on YouTube
Two clocks exist:
- Event time. When the event happened, stamped at the source (sensor, phone). Use it for correct results.
- Processing time. When the streaming system sees the event. It is simple, but results change with network delays and restarts.
A watermark is the system's estimate that events up to time have arrived. Here: watermark = max event time seen min.
= watermark. An event with event time is accepted. An event with event time is late: it is dropped or sent to a late-data path.
The slide example: a user scores a goal in a mobile game at 10:00:05, but the phone is in a tunnel and uploads at 10:03:40. By processing time the goal lands in the 10:03 window, which is wrong. By event time it lands in 10:00, where it belongs. With a 10-minute watermark it is accepted. An event 2 hours late would be dropped or sent to a late-data path.
Worked example. Max event time seen so far is 11:00. Watermark delay is 10 min. Two events arrive.
One-pass algorithmsSearch on YouTube
One pass and bounded memory force approximate methods. The slides name five:
| Problem | Technique | Core idea | Example question |
|---|---|---|---|
| Sampling | Reservoir sampling | Keep events; event replaces a random slot with probability | A fair sample of 1,000 posts from a day of unknown length |
| Filtering | Bloom filter | Bit array and several hash functions; no false negatives, some false positives | Is this URL on the malicious-site list? |
| Count distinct | Flajolet–Martin, HyperLogLog | Hash events; the longest run of trailing zeros estimates the count | How many unique visitors today? |
| Counting in a window | DGIM | Buckets of power-of-two sizes summarise the last bits | How many failed logins in the last attempts? |
| Frequent events | Count-Min sketch | Small 2-D counter array; take the minimum across hash rows | Which hashtags are trending now? |
Reservoir samplingSearch on YouTube
Fill the reservoir with the first events. For event , keep it with probability . If kept, it replaces a uniformly random slot. Result: every event seen so far is in the sample with probability .
= reservoir size, = position in the stream (), = events seen so far. The method never needs in advance.
Worked example (slides). Reservoir with over events a, b, c, d, e.
| Event | Keep prob. | Random outcome | Reservoir | |
|---|---|---|---|---|
| 1 | a | fill | added | [a] |
| 2 | b | fill | added | [a, b] |
| 3 | c | kept, replaces a | [c, b] | |
| 4 | d | not kept | [c, b] | |
| 5 | e | kept, replaces b | [c, e] |
After 5 events, each of a, b, c, d, e is in the reservoir with probability , though was never known in advance.
Worked example (extra). Reservoir with . Eight events arrive (a through h).
Check for the first event. Event a enters at . It survives each later event with probability . The product telescopes: . This matches .
Bloom filterSearch on YouTube
A Bloom filter tests whether an event belongs to a large set without storing the set. It keeps a bit array of bits and hash functions. To insert, set all hashed bits to 1. To query, check all bits. If any bit is 0, the event is definitely absent. If all bits are 1, it is possibly present (it may be a false positive).
The slide filter has bits and these two hash functions. Insert 25: bits 5 and 3. Insert 42: bits 2 and 7. Check: , ; , .
Worked example (slides). Bits set after the two inserts are .
| 0 | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 0 | 0 |
| Query | Bits set? | Answer | Truth | ||
|---|---|---|---|---|---|
| 30 | 0 | 3 | bit 0 is 0 | Definitely not in set | Correct |
| 42 | 2 | 7 | both 1 | Possibly in set | Correct (true positive) |
| 15 | 5 | 3 | both 1 | Possibly in set | False positive: 15 was never inserted |
A 0 bit proves absence, so false negatives are impossible. A 1 bit may come from other events, so false positives are possible.
Worked example (extra). Same filter, bits . Query 35 and 31.
Counting distinct eventsSearch on YouTube
Flajolet–Martin (FM) estimates how many different events appeared without storing them. Hash each event to a binary string. Count the trailing zeros of each hash. Let be the longest run seen. Estimate the distinct count as . Reason: about half the hashes end in 0, and a quarter end in 00. An eighth end in 000. So a run of zeros appears once the count reaches about . HyperLogLog extends this with many registers and a harmonic mean for a tighter estimate.
= estimated distinct count. = longest run of trailing zeros seen in any hash. Rare long runs push the estimate up, so real systems average over many hash functions.
Worked example. Five distinct events hash to binary strings with trailing-zero counts 0, 1, 2, 0, 1.
The truth is 5. The estimate 4 is close and used only a few bits of state.
DGIM: counting ones in a windowSearch on YouTube
DGIM answers "how many 1s were among the last bits?" using much less than bits of memory. It groups the 1s into buckets whose sizes are powers of two (1, 2, 4, …), with at most two buckets of each size. Old buckets expire as the window slides. Estimate: sum all bucket sizes except the oldest, plus half of the oldest bucket.
Worked example. Last bits, oldest first: 1, 0, 1, 1, 0, 1, 0, 1. True count of 1s is 5.
Bucket the 1s. Ages of the five 1s (0 = newest): 0, 2, 4, 5, 7. Group newest first into contiguous ranges with sizes 1, 2, 2: size 1, size 2, size 2. Sizes never decrease going back, and each bucket holds one contiguous range of time.
Estimate. Buckets newest first: sizes 1, 2, 2. The oldest bucket has size 2.
The estimate 4 is close to the truth 5, from 3 buckets instead of 8 stored bits.
Count-Min sketchSearch on YouTube
Count-Min estimates how often each event occurs, so you can find the heavy hitters. It keeps a small 2-D counter array with one hash function per row. To insert, increment one counter per row. To query, take the minimum across the rows. Collisions only add counts, so the estimate is never below the truth.
Worked example. Two rows, four counters each. Hashes: , ; , ; , . Insert a three times, b twice, c once.
Counters. Row 1: index 0 gets (a and b collide), index 3 gets 1. Row 2: index 1 gets (a and c collide), index 2 gets 2.
Every estimate is greater than or equal to the truth. The minimum across rows keeps the error small.
Fast data platformsSearch on YouTube
Fast data is value that decays with time. A fraud score matters now, not next week.
| Data at rest | Data in motion |
|---|---|
| Stored first, analysed later | Analysed as it flows, then stored |
| Optimised for volume and complex queries | Optimised for velocity and low latency |
| HDFS, data warehouses, Hive | Kafka, Spark Structured Streaming, Flink |
| Example: yearly sales trends | Example: block a fraudulent card swipe now |
Fast data platforms usually have three capabilities. First, durable high-throughput ingestion (Kafka). Second, a stream processing engine (Spark Structured Streaming, Flink). Third, fast serving storage (key-value stores, time-series databases, dashboards). Typical uses: fraud detection, live recommendations, predictive maintenance, network monitoring, live sports analytics, dynamic pricing.
Lambda architectureSearch on YouTube
Lambda runs two paths: a batch layer and a speed layer. The batch layer recomputes complete views over the immutable master data set (Hadoop, Spark); views are hours old but accurate. The speed layer builds incremental views over recent data only (Storm, Flink, Spark Streaming); views are fresh but approximate. A serving layer merges both views per query. Batch recomputation also fixes errors in the speed layer.
Strength: accurate batch results plus low-latency recent results. Weakness: the same logic is written and maintained twice, in two systems that must agree (e.g. a Hive job plus a Storm topology).
Kappa architectureSearch on YouTube
Kappa keeps one path. New events append to a durable, replayable log (a Kafka topic with long retention). A single stream processing job (Spark, Flink, Kafka Streams) reads the log and writes tables, dashboards and APIs. To reprocess, start a new job version from offset 0 and swap it in when it catches up.
| Lambda | Kappa | |
|---|---|---|
| Code paths | Two: batch and streaming | One: streaming only |
| Reprocessing | Re-run the batch layer | New job version from offset 0, swap when caught up |
| Complexity | Higher; two systems must agree | Lower; one system to operate |
| Fits best when | Heavy historical analytics, ML training | Logic is mostly event-driven and incremental |
Lambda is still useful when large historical computations, such as training ML models over years of data, run better as batch jobs. In practice many platforms are hybrids. Spark runs the same DataFrame code in batch and streaming mode. Lakehouse tables like Delta Lake or Iceberg serve as both streaming sinks and batch sources.
Streaming platform landscapeSearch on YouTube
| Platform | Category | Processing model | Typical use |
|---|---|---|---|
| Apache Kafka | Distributed event log | Partitioned, replicated, durable log | Backbone for ingesting events |
| Apache Pulsar | Messaging and streaming | Brokers plus BookKeeper storage | Multi-tenant, geo-replicated |
| Amazon Kinesis | Managed cloud streams | Shards, managed by AWS | Cloud-native ingestion |
| Spark Structured Streaming | Processing engine | Micro-batch on DataFrames | Unified batch and stream analytics |
| Apache Flink | Processing engine | Record-at-a-time, event time, state | Low-latency stateful apps |
| Apache Storm | Processing engine | Record-at-a-time spouts and bolts | Early real-time pioneer |
| Kafka Streams | Java library | Record-at-a-time inside your app | Microservices on topics |
Two layers exist. Transport and storage of events: Kafka, Pulsar, Kinesis, plus Google Pub/Sub and Azure Event Hubs. They receive events from producers, store them durably and deliver them to consumers, but do little computation. Processing engines: Spark Structured Streaming, Flink, Storm, Kafka Streams. They read from the transport layer, compute (filter, aggregate, join, window) and write results. A typical stack is Kafka plus Spark or Kafka plus Flink.
Storm was the first widely used open-source stream processor. Flink is built for true streaming with strong event-time and state support. Spark Structured Streaming wins when the team already uses Spark for batch: the same DataFrame API works for both. Kafka Streams is a library, not a cluster: you embed it in an ordinary Java application.
Record-at-a-time versus micro-batchSearch on YouTube
Four design questions shape a streaming system. How are events grouped for processing? What happens to events when something fails? Where does state live? How does the system scale and cope with bursts?
| Record-at-a-time (continuous) | Micro-batch |
|---|---|
| Each event is processed the moment it arrives | Events are collected for a short interval, then processed as a small batch job |
| Latency: milliseconds | Latency: about the batch interval, e.g. 1 s |
| Engines: Flink, Storm, Kafka Streams | Engine: Spark Streaming and Structured Streaming |
| Fault tolerance via distributed snapshots of state | Reuses the Spark batch engine and lineage-based recovery |
Delivery guaranteesSearch on YouTube
Scenario: payment event P1 is read, the worker crashes, then restarts. Is P1 counted 0, 1 or 2 times?
| At-most-once | At-least-once | Exactly-once |
|---|---|---|
| Commit the offset before processing | Process first, commit the offset after | Output and offset commit happen atomically |
| Crash after commit: P1 is lost (0 times) | Crash before commit: P1 is re-read and counted twice | P1 affects the result exactly once |
| No duplicates, possible loss | No loss, possible duplicates | Via checkpoints plus replayable sources plus idempotent or transactional sinks |
| OK for metrics where a gap is tolerable | Fix with idempotent writes keyed by payment id | Cost: more coordination, slightly more latency |
Name the mechanism in the exam. At-most-once commits the offset before processing. At-least-once commits it after. Exactly-once needs checkpoints plus a replayable source plus an idempotent or transactional sink. The commit order decides at-most-once vs at-least-once; exactly-once needs atomic output plus offset commit.
State and checkpointsSearch on YouTube
Stateless operations (map, filter, parse JSON) handle each event alone. They keep nothing to remember and restart with ease. Stateful operations (counts, windows, joins, deduplication, sessions) need memory across events, so the state must survive failures.
A checkpoint store (HDFS or S3) holds offsets plus a state snapshot. Example from the slides: the Kafka source sits at offsets 0 to 150. The operator holds running counts per user (u1: 12, u2: 7, u3: 30). The last checkpoint is at offset 120.
Restore from the checkpoint, then re-read from the checkpoint offset. Do not restart from the crash offset, or events between the checkpoint and the crash are lost. Do not restart from offset 0, or all old events are double-counted.
Scaling and backpressureSearch on YouTube
Partitioning splits the stream by key (e.g. user id), so many workers process partitions in parallel. Events of one key stay together and in order. Parallelism grows with partitions and workers: in Kafka plus Spark, one Kafka partition maps to at least one Spark task.
If the sink is slower than the source, backpressure slows the intake rather than running out of memory: Spark's maxOffsetsPerTrigger, Flink's flow control. Buffering absorbs bursts: during a flash sale, events wait safely in the Kafka log and are processed as capacity allows.
Quick self-testSearch on YouTube
1. Differentiate batch processing and stream processing on input, latency and answer.
Batch works on a bounded data set at rest, with latency of minutes to hours and an exact answer over complete data. Streaming works on unbounded arriving events, with latency of milliseconds to seconds and an incremental, per-window answer that may be approximate.
2. Events arrive at t = 0.5, 2, 4.5, 5.5, 9 s. Give the counts for 4 s tumbling windows.
Windows are , , . holds 0.5, 2, so 2. holds 4.5, 5.5, so 2. holds 9, so 1. Counts: 2, 2, 1.
3. Watermark delay is 10 min and the max event time seen is 11:00. An event stamped 10:55 and one stamped 10:40 arrive. Which is accepted?
. The 10:55 event is , so it is accepted. The 10:40 event is , so it is late and dropped (or sent to a late-data path).
4. Reservoir with k = 3 sees 8 events. With what probability is the 6th event kept, and with what probability is any given event in the final sample?
. After , every event is present with probability .
5. A 10-bit Bloom filter with h1(x) = x mod 10 and h2(x) = (2x+3) mod 10 holds bits 7. Query 35 and 31.
35 gives and . Both bits are set, so possibly present: a false positive (35 was never inserted). 31 gives . Bit 1 is 0, so definitely absent.
6. Differentiate event time and processing time. Why does the game-goal example need event time?
Event time is when the event happened (stamped at the source). Processing time is when the system sees it. The goal happened at 10:00:05 but uploaded at 10:03:40. Processing time puts it in the 10:03 window, which is wrong. Event time puts it in 10:00, where it belongs.
7. Differentiate at-most-once, at-least-once and exactly-once delivery. What decides the guarantee?
At-most-once commits the offset before processing (loss possible, no duplicates). At-least-once commits it after (duplicates possible, no loss). Exactly-once commits output and offset atomically via checkpoints, replayable sources and idempotent or transactional sinks. The commit order decides the first two.
8. Differentiate Lambda and Kappa. When would you still choose Lambda?
Lambda runs two paths (batch plus speed) and merges the views. Kappa runs one streaming path over a replayable log. Choose Lambda when heavy historical computations, such as training ML models over years of data, run better as batch jobs.
9. Why can an exact distinct count not run on an unbounded stream, and what does FM store instead?
Exact counting stores every distinct event, but the stream is unbounded and memory is bounded. FM stores only the longest run of trailing zeros in the hashes and estimates .
10. Why do Count-Min estimates never fall below the truth, and how does the query keep the error small?
Counters only increase and collisions only add counts, so no estimate falls short. The query takes the minimum across hash rows, and the least-collided row is closest to the truth.
- Batch works on bounded data at rest (minutes to hours, exact). Streaming works on unbounded arriving events (milliseconds to seconds, incremental, may be approximate).
- A stream is continuous, unbounded, time-ordered, fast and bursty, transient. It is an append-only sequence of timestamped events.
- A DSMS runs standing queries (registered once, run forever) and ad-hoc queries (asked once, need kept windows or sketches).
- Tumbling windows never overlap, sliding windows overlap, sessions close after an inactivity gap. Slide events give 3·2·3, 3·3·3·3 and 5·3.
- Event time is when the event happened; processing time is when the system sees it. Watermark : accept events , drop events .
- Reservoir: keep event with probability ; every event ends in the sample with probability .
- Bloom filter: a 0 bit proves absence (no false negatives); set bits may collide (false positives possible).
- Flajolet–Martin: with = longest trailing-zero run. DGIM buckets powers of two and halves the oldest. Count-Min takes the row minimum and never undercounts.
- Lambda runs batch plus speed layers (logic twice). Kappa replays one log through one job (logic once).
- Record-at-a-time gives millisecond latency (Flink, Storm). Micro-batch latency is about the batch interval (Spark).
- At-most-once commits before processing; at-least-once after; exactly-once needs checkpoints plus replayable sources plus idempotent or transactional sinks.
- Stateful operators checkpoint state and offsets; recovery restores the snapshot and re-reads from it. Partition by key for order and parallelism; use backpressure and buffering for bursts.