Leveraging modern application architectures for IoT applications.
Mike Blackstock, Sense Tecnic Systems
Introduction
In the Internet of things, devices communicate with gateways and cloud computing systems, providing information from the physical world to services that provide domain-specific information to end users. This could include for example, the location and status of products in a supply chain, the current soil moisture level in a field or what lights are on in the home. In some cases, connected actuators can affect the environment, for example controlling irrigation systems or turning the music on in a room as you enter.
Typically data from things is sent to servers as streams of events, which are aggregated and processed to provide up to date information to end users. Users and application logic are often interested in the recent state of entities, e.g. the current temperature, location of taxi cabs, moisture and humidity readings in a certain area of a field, or whether the lights are on in the garage. Applications need this information to react to changes. For example, if the temperature is too cold, turn on the furnace. If the fields need watering, turn on a irrigation system. When the taxi is nearby, send me an SMS message.
Traditional Application Architectures
Like other services, IoT systems often leverage traditional web frameworks and languages. In many traditional web applications, the Create, Read, Update and Delete pattern is used (CRUD), where user interaction is typically translated by business logic into updates to entities stored in a single relational database. Both the updates and queries are made on the same entities, typically stored as columns in rows in a relational database such as a SQL server. The same data representations are used for both reading and writing to the data store. While this is often suitable for simple business logic, one problem with CRUD is that in large scale systems, an update operation often requires interaction with many entities and services to perform a function. For example, in an order-processing application sending in an order for processing will cause changes to the customer information, require pricing information for example to apply discounts, and inventory information to see if there is enough products in stock. In an IoT application, data from a device may need to be stored in a time series database for offline analysis, checked in real time to determine whether an alert needs to be triggered, displayed in a real time dashboard, and counted as part of a customer’s data subscription.
CRUD architectural pattern
CQRS and Event Sourcing
The CQRS pattern effectively separates the write data model from the read model in an application or service. When the user makes a change, the write model is updated. The system then processes the write data model creating a read or query model. The read model can be a replica of the write model, or a completely separate data model in a separate data store containing denormalized data. This has the advantage of improved security, and allowing the read and write stores to be provisioned and optimised for performance and scalability separately.
CQRS architectural pattern
To support eventual consistency another pattern called Event Sourcing is often used with CQRS. In this pattern, the write model in the CQRS architecture is a log of events representing domain specific actions that the user takes on the system. All changes are recorded so that the write model can be used to derive the state of the system at any time by generalizing a view of the data to populate the read store for queries. Systems based on this pattern are eventually consistent; there will be a delay between when events are written and the read store is updated. Building a system using this pattern can be more complex since it must have the capability of creating a read view from (re)playing a series of events in the write store.
CQRS+Event Sourcing Pattern
The event store is the authoritative data source for the system. Systems can replay events to regenerate the application state if necessary. Applications using this pattern must be able to deal with inconsistencies and the lack of transaction support. For example, if an event arrives generated by a warehouse RFID reader indicating stock for an item has been reduced, when at the same time, an order arrives for that item, the user could be informed or a back order for the item would be created.
Applying Event Sourcing to the IoT
At Sense Tecnic, we’ve been exploring the Event Sourcing architecture pattern for building highly scalable IoT applications. In IoT applications, things will often send streams of data to a service that reacts to theses updates and save them for historical analysis. At the same time, the application will receive commands from users, execute logic based on these commands, respond to user queries and send notifications.
The IoT application builds and maintains the state of the domain-specific entities of interest (things, users, etc.) in a database. In an agriculture application this may include geographical areas in a field. In a factory this may include the level of a tank, or the RPM of a motor. In a home automation system this may include the state of lights or the temperature of rooms.
In an IoT application, the ‘write model’ often consists of time series data collected from the real world. There is also a derived ‘read model’ that the application maintains to satisfy queries by end users. This leads to an architectural pattern extending CQRS and Event Sourcing where not just users, but physical things are interacting with the system. While users will interact with a presentation layer such as a UI or REST API, sending commands and making queries, things will interact with a ‘thing presentation’ layer over a protocol such as MQTT. Like users, things will generate commands that generate events in the system. Unlike users, they will also receive commands to affect the environment as shown.
An IoT Application Architecture using Event Sourcing.
A key difference from non-IoT applications is that there are two sources of commands – users and things. Based on application logic, commands from users and from other things can cause other commands to be sent to things in the environment, for example to turn lights on and off, or turn on irrigation systems when the moisture level is low.
There are several benefits to formalizing this architectural pattern for IoT applications:
- IoT applications often need to capture the state of things over time such as sensor data values for historical data analysis. The event store does this automatically.
- Thing data is collected independently of user command and the application logic allowing the thing presentation components to be scaled out independently of the user presentation. This can be important when there are many more sensors than users.
- Commands sent to things, and updates to the UI can be based on real time data from both users and things.
- New features can be added easily that use events from things, or send events to things. For example, it is straightforward to add additional functionality such as alerting or forward sensor data to an enterprise system without changing how data is collected or sent to things by simply subscribing to different events.
- If we want to change the thing model and query API, just change the components that update and maintain the read model without affecting other subsystems. The state of these new models can be regenerated from the event store.
- We can easily add different events to the system, for example sourced from a factory or enterprise systems, generated by things, services or users without affecting current events.
STS FRED for IoT Applications
The CQRS and Event Sourcing patterns are a natural fit for IoT applications. The Sense Tecnic FRED Platform manages instances of Node-RED – a visual dataflow programming environment for the IoT. Because Node-RED uses a data flow programming paradigm, where components are loosely coupled it is ideally suited for building out applications using these patterns.
In Node-RED, components called nodes are wired together into flows and communicate with each other using messages. For example, to add a simple alerting system to an IoT system, one can create a flow as shown:
Simple Node-RED flow to send alerts
This flow listens for events published by the event store, generates alert events, and then sends them to an alerting service such as Pushbullet. Assuming the system makes thing events available on a message broker, it is straightforward to add new alerting functionality and integration to your IoT applications in this way.
Conclusion
The CQRS and Event Sourcing patterns are a natural fit for IoT applications. In this blog we described the CQRS and Event Sourcing patterns and how they can be applied in an IoT application architecture. In a future blog post, we will demonstrate how the Sense Tecnic FRED system can be used to effectively prototype such applications.
If you are interested in developing an IoT application using FRED, Node-RED or other technologies, contact Sense Tecnic. We’d be glad to help you get up and running from a quick PoC using FRED to a production system that leverages these scalable architecture patterns when needed. For more information on the CQRS and Event Sourcing pattern, Node-RED and the FRED hosted Node-RED system, see the links below.
For more information
- CQRS Pattern: https://docs.microsoft.com/en-us/azure/architecture/patterns/cqrs, https://martinfowler.com/bliki/CQRS.html
- Event Sourcing pattern: https://docs.microsoft.com/en-us/azure/architecture/patterns/event-sourcing, https://martinfowler.com/eaaDev/EventSourcing.html
- Adaptech Solutions. https://adaptechsolutions.net/
- Node-RED – https://nodered.org
- FRED – Cloud Hosted Node-RED: https://fred.sensetecnic.com