Szenarien für den Einsatz von IoT und BigData: Ablage und Verwaltung von Sensordaten mit Elasticsearch (Teil 4)
Nachdem in den beiden vorhergehenden Teilen dieser Blog-Post-Serie auf die Erfassung der Messwerte im Außen- und Innen-Bereich eingegangen wurde, beschäftigt sich dieser Artikel mit der Abfrage und Ablage der Sensor-Daten.
Die nachfolgende Abbildung zeigt den Aufbau, der hierfür relevanten Infrastruktur. In einem Elasticsearch-Cluster mit zwei Knoten werden die Daten für Auswertungen und zur Anzeige vorgehalten. Befüllt wird der Cluster durch eine vorgelagerte Springboot-Applikation, die wiederum die Daten von den einzelnen Raspberry’s abruft.
Zwischen-Pufferung
Für die Persistierung kommt ein zweistufiger Ansatz zum Tragen. Im ersten Schritt erfolgt auf jedem Raspberry zunächst die Speicherung der Daten. Dies übernimmt jeweils eine kleine SpringBoot-Applikation, die alle 2 Sekunden die Innen-Sensoren abfrägt. Die Daten der außenstehenden Wetterstation werden nur dreiminütlich gesendet und abgelegt. Beide Sensor-Typen speichern ihre Ergebnisse in einer H2-Datenbank in derselben Datenbank-Tabelle. Die Bereitstellung der Daten erfolgt über einen Rest-Service, der JSON-Daten ausliefert.
Es stellt sich die Frage, warum die Messwerte nicht direkt von den Sensoren an Elasticsearch geschickt werden. Im Gegensatz zu den Raspberry's werden alle Server bei exensio und damit auch der Elasticsearch-Cluster jeden Abend im Sinne von Green-IT automatisiert heruntergefahren. Ohne Zwischenspeicherung würden die Werte in der Nacht und an den Wochenenden verloren gehen.
Abfrage der Daten
Für die Abfrage der Daten von den Raspberry's wird, wie oben schon erwähnt, ebenfalls eine Springboot-Applikation eingesetzt. Diese läuft auf dem Elasticsearch-Server und frägt im 2 Sekunden-Rythmus alle Raspberry's an. Für diesen Zweck wird an jeden Raspberry ein Request mit zwei Parametern geschickt:
http://ex-raspberry-03/sensor?created=1401196929960&max=1000
Der erste Parameter gibt den Zeitstempel des letzten in Elasticsearch abgelegten Wertes für den Sensor an. Mit der zweiten Kenngröße (max) wird die Menge der maximal zu liefernden Datensätze definiert. Aus Performancegründen werden die Abfragen asynchron mit Hilfe der @Async-Annotation von Spring vollzogen.
Die Lieferung der Daten erfolgt über den oben genannten Rest-Service, wobei nach Zeitstempel aufsteigend geliefert wird.
Nutzung von Elasticsearch
Beim Einsatz von Springboot ist die Nutzung von Spring Data naheliegend, da hierfür auch ein Elasticsearch-Provider existiert. Die abgefragen JSON-Daten befüttern das nachfolgend dargestellte POJO, das außer Annotationen keine Abhängigkeiten zu Elasticsearch besitzt.
@Getter
@Setter
@Document(indexName = "sensorraspberry")
public class IndexDocRaspberry {
private String id;
private String device;
private String type;
private Float temperature;
@Field(type = FieldType.Date, format = DateFormat.date_hour_minute_second_millis)
private Date created;
private Float humidity;
private Float windspeed;
private Float rainfall;
private Float cpuTemperature;
private Boolean valid;
}
Aus dem POJO ergibt sich automatisch die Struktur des Index für Elasticsearch, die nachfolgend dargestellt ist. Die einzelnen Attribute sind selbsterklärend. Wichtig für die spätere Darstellung ist neben den eigentlichen Nutzwerten, die Ablage des Sensor-Typs ("indoor" oder "outdoor"), sowie das Gerät von dem der Meßwert kommt. Damit lässt sich auswerten, wo der Messwert aufgezeichnet wurde (in welchem Bürozimmer).
"sensorraspberry": {
"mappings": {
"indexdocraspberry": {
"properties": {
"id": {
"type": "string"},
"cpuTemperature": {
"type": "float"},
"created": {
"type": "date",
"format": "dateOptionalTime"},
"device": {
"type": "string",
"index": "not_analyzed"},
"humidity": {
"type": "float"},
"rainfall": {
"type": "float"},
"temperature": {
"type": "float"},
"type": {
"type": "string",
"index": "not_analyzed"},
"valid": {
"type": "boolean"},
"windspeed": {
"type": "float"}
}
}
}
}
Die nachfolgende Abbildung zeigt einen statistischen Ausschnitt des Index mit Marvel an einem Nachmittag. Hier ist rechts oben zu sehen, dass Elasticsearch mit ca. 2 Messwerten pro Sekunde gefüttert wird. Wird der Server morgens gestartet, so ist diese Indexierungsrate weit höher und liegt bei ca. 1000 Messwerten pro Sekunde. Dies ist darauf zurückzuführen, dass sämtliche gemessenen Werte von der Nacht nachgefahren werden müssen.
Fazit zum gewählten Ansatz
Bei dem genutzten Ansatz mit der Zwischenspeicherung von Daten, entstand für die Umsetzung etwas mehr Arbeit. Allerdings steht im Gegensatz dazu, der Vorteil, dass tagsüber die Wetter-Daten in Echtzeit zur Verfügung stehen und Nachts bzw. an den Wochenenden keine Server unnötig laufen. Das Nachfahren der Messwerte nach einem verlängerten Wochenende ist innerhalb weniger Minuten erledigt.
Die Serie gliedert sich folgendermaßen: