Introduction to eXtremeDB Active Replication Fabric

As explained in the eXtremeDB Active Replication Fabric page, Active Replication Fabric is an eXtremeDB-based foundation for distributed IoT applications. And, as further explained in The IoT Challenges page, the volume of data collection points (edge devices), the constrained resources and CPU power of these devices, and the sporadic nature of connectivity between the devices and backend processors are the driving considerations for the Active Replication Fabric distributed architecture.

Active Replication Fabric applications can apply advanced analytics to IoT data enabling businesses to discover usage patterns, identify weaknesses in connected devices and, in the end, distribute available resources, technological and financial, to help create better connected products.

Theory of operation

Functionally, data in the IoT environment can be put into three broad categories: edge devices, where the data is collected, routers and servers, where the data is analyzed. Edge devices capture or generate data, may do some initial filtering, and make sure that the data is safe for some period of time before they transmit the data to servers for further processing.

IoT routers can form one or more additional layers of nodes between servers and edge devices. The IoT topology looks like a tree where the server is the root, the devices are the leaves, and the routers are the inner nodes. Each node in this tree has a level (a 2-byte integer): the server always has level = 1, the level of devices is 65535 ( = 0xFFFF ) and routers have a level between 2 and 65534. The level of the router defines its position in the tree - the smaller the level value, the "closer" the node is to the server. The level of the routers (and their relative position) can be changed at runtime, but the basic type (device, server or router) cannot be changed after the database creation.

As well as server and devices, each router must have a unique agent ID. Note that the server always has fixed agent_id = 1. UP/DOWN tables on the server have an automatically generated field agent_id. For UP tables it denotes the node that created the record. For DOWN tables it denotes the receiver of the row created by the server. Routers have two generated fields in their UP/DOWN tables : src_agent_id (the creator of the record) and dst_agent_id (the receiver of the record). Tables in the device's database have no accessible auto-generated fields.

We use the term “storage containers” for databases maintained on edge devices to differentiate them from the server-side databases. The eXtremeDB Active Replication Fabric APIs allow device-based applications to collect data, then transmit the collected data to servers when connected; likewise they allow communicating server-side data to IoT devices, usually for new device configuration and provisioning. This data flow is fully application-controlled through the Active Replication Framework push / pull interfaces. The APIs provide automatic or on-demand data exchange between collection points and servers.

Database Schema IoT Definition

Two schema definition declarations are required for Active Replication Framework (IoT) applications.

IoT Declarations

The declaration iot server | router | device is used in the database schema definition to declare that the database is intended to be used in the Active Replication Framework (IoT) applications. For example:

    iot server;

A router declaration must specify the level between 2 and 65534, and optionally an agentId. For example:

    iot router<100> 15;


    iot router<100>;

And an edge device has level 65534 and can optionally specify the agentId. For example:

    iot device 1000;


    iot device;

The declaration defines the role for the database: as a server or router database or a device storage container. Optionally, the agentId for the database can be specified. The agentId is a unique identifier for the database. If this agentId is not specified through the schema, it must be specified as a database parameter when opening the database.

When iot is declared, the database runtime creates two hidden classes (tables) @sys_iot_ts and @sys_iot_del. The first table contains information about data sent or received from other iot nodes. The second table contains information about objects that were deleted from the container, which is necessary to propagate deletes to other iot nodes.

Uptable and Downtable Class Modifiers

The class modifiers uptable and downtable are used to define the replication direction. Classes defined as uptable are synchronized from the device to the server: any data modifications made to the devices’ storage container are propagated up to the server’s database. The downtable classes are synchronized downwards, i.e. from the server to the connected devices. Note that classes (tables) that are not designated as an uptable or a downtable are not replicated.

An example of uptable classes could be sensor data collected in the devices’ storage container, which are replicated and then stored away in the server’s database. An example of a downtable class could be a device’s configuration parameters, or server-originated instructions, that are propagated to the device.

All uptable and downtable classes include the automatically generated field agent_id; generated by the schema compiler. For the uptable classes, the agent_id identifies the device from which the object (record) was received. The server’s downtable tables’ the agent_id identifies the device nodes storage containers that the object (record) must be sent to. For example, the following class might be defined for the server database:

    uptable class TempSensor 
        datetime          ts;
        unsigned<4>   sensorId;
        double             value;
        tree<ts, agent_id, sensorId> ats;

The agent_id field is not defined explicitly in the schema, but it can be used in indexes. For the downtable classes the default agent_id value is MCO_IOT_ALL_AGENTS which means that, by default, the server’s data is replicated to all device storage containers. It is possible to specify explicitly the value for agent_id which causes the server’s data to be replicated only to the specified node.

In addition to the agent_id field, the uptable and downtable classes are also generated with two hidden indexed fields that identify the object and the timestamp of its last modification. Both fields and their index are automatically updated by the database runtime during a transaction commit that has modified the object. However note that these internally managed fields (iot_object_id@ and iot_timestamp@) are not accessible to applications. The iot_object_id@ value is like an autoid_oid except that it is local to the class, so to create a global identity it is combined with the agent_id of the node that the object was created on. The iot_timestamp@ value is the logical timestamp (not the wall time) of the last modification of the object. Every transaction increments this counter and stores the new value. This is necessary to enforce IoT synchronization policies which identify objects that need to be sent to the next IoT level during synchronization. Therefore, if a timestamp value is required by the application, it is necessary to define a field, like ts in the above schema, that can be accessed and included in indexes if desired.