Iggy

Website | Getting started | Documentation | Crates


iggy


Iggy is the persistent message streaming platform written in Rust, supporting QUIC, TCP (custom binary specification) and HTTP (regular REST API) transport protocols. Currently, running as a single server, it allows creating streams, topics, partitions and segments, and send/receive messages to/from them. The messages are stored on disk as an append-only log, and are persisted between restarts.

The goal of the project is to make a distributed streaming platform (running as a cluster), which will be able to scale horizontally and handle millions of messages per second (actually, it's already very fast, see the benchmarks below).

It is a pet project of mine to learn more about distributed systems and Rust. The name is an abbreviation for the Italian Greyhound - small yet extremely fast dogs, the best in their class. Just like mine lovely Fabio & Cookie ❤️


Features


Supported languages SDK


Quick start

Build the project (the longer compilation time is due to LTO enabled in release profile):

cargo build -r

Run the tests:

cargo test

Start the server:

cargo r --bin server -r

Start the client (transports: quic, tcp, http):

cargo r --bin client -r --transport tcp

Create a stream named dev with ID 1:

stream.create|1|dev

List available streams:

stream.list

Get stream details (ID 1):

stream.get|1

Create a topic named dummy with ID 1 and 2 partitions (IDs 1 and 2) for stream dev (ID 1):

topic.create|1|1|2|dummy

List available topics for stream dev (ID 1):

topic.list|1

Get topic details (ID 1) for stream dev (ID 1):

topic.get|1|1

Send a message 'hello world' (ID 1) to the stream dev (ID 1) to topic dummy (ID 1) and partition 1:

message.send|1|1|p|1|1|hello world

Send another message 'lorem ipsum' (ID 2) to the same stream, topic and partition:

message.send|1|1|p|1|2|lorem ipsum

Poll messages by a regular consumer c (g for consumer group) with ID 0 from the stream dev (ID 1) for topic dummy (ID 1) and partition with ID 1, starting with offset (o) 0, messages count 2, without auto commit (n) (storing consumer offset on server) and using string format s to render messages payload:

message.poll|c|0|1|1|1|o|0|2|n|s

Finally, restart the server to see it is able to load the persisted data.

The HTTP API endpoints can be found in server.http file, which can be used with REST Client extension for VS Code.

To see the detailed logs from the client/server, run it with RUST_LOG=trace environment variable.

See the images below

Files structure

files structure

Server start

server start

Client start

client start

Server restart

server restart


Samples

You can find the sample consumer & producer applications under samples directory. The purpose of these apps is to showcase the usage of the client SDK. To find out more about building the applications, please refer to the getting started guide.

To run the sample, first start the server with cargo r --bin server and then run the producer and consumer apps with cargo r --bin advanced-producer-sample and cargo r --bin advanced-consumer-sample respectively.

You might start multiple producers and consumers at the same time to see how the messages are being handled across multiple clients. Check the Args struct to see the available options, such as the transport protocol, stream, topic, partition, consumer ID, message size etc.

By default, the consumer will poll the messages using the next available offset with auto commit enabled, to store its offset on the server. With this approach, you can easily achieve at-most-once delivery.

sample


Benchmarks

To benchmark the project, first start the server and then run the benchmarking app:

cargo r --bin bench -r -- --tcp --test-send-messages --streams 10 --producers 10 --parallel-producer-streams --messages-per-batch 1000 --message-batches 1000 --message-size 1000

cargo r --bin bench -r -- --tcp --test-poll-messages --streams 10 --consumers 10 --parallel-consumer-streams --messages-per-batch 1000 --message-batches 1000

Depending on the hardware, settings in server.json, transport protocol (quic, tcp or http) and payload size (messages-per-batch * message-size) you might expect over 4000 MB/s (e.g. 4M of 1 KB msg/sec) throughput for writes and 6000 MB/s for reads. The current results have been achieved on Apple M1 Max with 64 GB RAM.

Write benchmark

write benchmark

Read benchmark

read benchmark


TODO

Project

Server

Client

SDK

Streaming

Distribution

API

UI