loader

ARCHITECTURE

Astarte is a distributed, scalable, cloud-native system written in Elixir, designed to maximise consistency and performance all around the chain, while striving to keep the system always available.

Astarte’s architecture allows to reach impressive numbers in terms of message ingestion and consumption, especially when compared to competing monolith infrastructures, without having to compromise on any other aspect.

> MODERN, MICROSERVICES ARCHITECTURE

Astarte is a collection of specialised microservices. Compared to a monolith architecture, this design allows not only for easier clustering and monitoring, but most of all for having a pipeline-oriented design in which transient failures of any service don’t come at the risk of losing data.

Moreover, every API is exposed through a separate microservice, enabling complex deployment scenarios in which part of Astarte’s APIs should be exposed in a different way, or security-sensitive scenarios where some APIs should be entirely disabled.

Every microservice is entirely isolated, having access only to other components of the system it needs to interact with.

> AUTOMATED DATA MODELING

Astarte uses Apache Cassandra/ScyllaDB as its main database – however, this detail is never exposed to the end user. Astarte builds upon the concept of Interfaces, which abstract the Data Model by exposing a higher-level mechanism for defining, in a RESTful-like logic, what kind of data Devices can expose / exchange.

Internally, Astarte automates Cassandra’s management entirely and exposes data as an API, or through one of its pipeline mechanisms.

From within Astarte, Cassandra is relevant only from a System Administrator point of view, whereas is never exposed to the end user / developer, who doesn’t need any specific Cassandra knowledge to use the platform.

> PROTOCOL AGNOSTIC INGESTION

Astarte defines an internal exchange protocol built atop Protobuf, AMQP and RabbitMQ.  Any transport (e.g.: MQTT, CoAP…) can be used as long as it is capable of converting received messages into Astarte’s internal protocol.

This kind of decoupling allows to overcome some limitations of simpler protocols, and to ensure Astarte is not tied to any specific protocol for ingestion.

> PERSISTENCY, CONSISTENCY AND QUEUE

Astarte leverages RabbitMQ both as a message broker and as a replay queue mechanism for incoming data. Data Updater Plant (DUP), Astarte’s dedicated microservice for ingestion, can scale and cluster tying itself to several RabbitMQ queues.

Internally, by leveraging Erlang’s lightweight processes, DUP assigns every Device to its own process, ensuring consistency and deterministic ordering of Device messages, which are always guaranteed to be consumed in the same order they were sent.

RabbitMQ also ensures persistency in case DUP, Cassandra or any other component in the queue fails, by writing the queues to disk. DUP’s implementation and queue handling ensure messages are removed from a queue only when they’ve been successfully persisted to the Database.

And, should RabbitMQ fail, Transports can implement their own persistency layer to cope with RabbitMQ downtimes.

> PERFORMANCE AND SCALABILITY

In massive throughput situations, Astarte can make the most out of multicore systems through Data Updater Plant’s horizontal and vertical scaling and adequate setup of Cassandra/ScyllaDB, reaching impressive numbers in terms of ingested messages per second.

With RabbitMQ being Data Updater Plant’s main source of messages, bottlenecks usually happen when RabbitMQ’s single queue performance starts to degrade.

DUP provides a horizontal scaling mechanism which creates a dedicated set of queues for each Data Updater Plant instance.

By doing this, RabbitMQ’s load can be spread over different queues which in turn are consumed by several DUPs, in a scenario which is ideal for achieving high/massive throughput.

DUP’s internal design also plays really well with vertical scaling. In cases where RabbitMQ isn’t the bottleneck, assigning more cores to DUP will automatically spread the load over multiple cores, allowing for better concurrency and faster processing.

This thanks to the fact that DUP, by design, assigns every device to a lightweight Erlang process, which BEAM dynamically distributes over multiple cores.

LET’S GET GOING!

Set up your Astarte instance today,
fork the code or join the conversation!