A fault-tolerant, real-time weather data streaming pipeline built with Kafka, gRPC, and Docker. Processes 10 messages/sec across 4 partitions using Protobuf serialization and offset checkpointing to achieve exactly-once processing with crash recovery.
- High-throughput ingestion — 10 messages/sec across 4 Kafka partitions
- Protobuf serialization — compact binary encoding via Protocol Buffers
- Exactly-once processing — offset checkpointing ensures no duplicates on crash recovery
- gRPC API — typed, low-latency service interface for weather data queries
- Dockerized — fully containerized with Docker Compose for local dev and deployment
- Fault tolerance — consumer groups with automatic partition rebalancing
Weather Sources (simulated)
│
▼
┌───────────────────┐
│ Kafka Producer │ Protobuf serialization
│ 4 partitions │ offset tracking
└────────┬──────────┘
│
┌────▼────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
│ Part. 0 │ │ Part. 1 │ │ Part. 2 │ │ Part. 3 │
└────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘
└────────────┴────────────┴─────────────┘
│
┌────────▼────────┐
│ Kafka Consumer │ exactly-once
│ (consumer grp) │ crash recovery
└────────┬────────┘
│
┌────────▼────────┐
│ gRPC Server │ typed API
│ WeatherService │
└─────────────────┘
| Component | Technology |
|---|---|
| Message broker | Apache Kafka |
| Serialization | Protocol Buffers (Protobuf) |
| API layer | gRPC |
| Containerization | Docker, Docker Compose |
| Language | Python 3.11 |
| Consumer | confluent-kafka |
- Docker & Docker Compose
- Python 3.11+
docker-compose upThis starts Zookeeper, Kafka (4 partitions), the producer, consumer, and gRPC server.
pip install -r requirements.txt
python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. weather.proto
# Terminal 1 — Producer
python producer.py
# Terminal 2 — Consumer
python consumer.py
# Terminal 3 — gRPC server
python server.pypython client.py --city "Madison" --limit 10KAFKA_TOPIC = 'weather-events'
NUM_PARTITIONS = 4
REPLICATION_FACTOR = 1
MESSAGES_PER_SEC = 10message WeatherEvent {
string city = 1;
float temperature = 2;
float humidity = 3;
float wind_speed = 4;
string condition = 5;
string timestamp = 6;
int32 partition = 7;
int64 offset = 8;
}Offset checkpointing is implemented by committing offsets only after successful processing:
consumer.commit(asynchronous=False) # synchronous commit after processingOn crash recovery, the consumer resumes from the last committed offset — ensuring no message is processed twice.
Rakshith Sriraman Krishnaraj · LinkedIn · Google Scholar