InfluxDB, une base de donnée orientée « séries temporelles » pour vos capteurs

A la différence des base de données classique comme MySQL, MariaDB, PostgreSQL, SQLite… que vous avez déjà pu rencontrer dans vos projets précédents, InfluxDB est une base de donnée axée sur le stockage de données temporelles. Un exemple concret : tous les minutes, nous voulons stocker la valeur d’un capteur de température et d’humidité, soit au bout d’une année, plus d’un million de données.

Une base de donnée classique peut tout à fait être capable de stocker autant de données, mais nous allons très vite voir que InfluxDB est clairement plus adapté pour un usage de type « date – valeur(s) » et également plus réactif malgré un grand nombre de données.

Cela dit en passant, gain de performance = optimisation des ressources = plus petite empreinte écologique (si si).

Installation de notre base de donnée

Nous allons partir sur un système vierge, debian Buster (10). Installons InfluxDB :

apt update
apt upgrade
apt install -y gnupg2 curl wget
wget -qO- https://repos.influxdata.com/influxdb.key | apt-key add -
echo "deb https://repos.influxdata.com/debian buster stable" | tee /etc/apt/sources.list.d/influxdb.list
apt update
apt install -y influxdb
systemctl enable --now influxdb

Voici, InfluxDB est installé dans notre système vierge, et il se lancera au démarrage de notre système.

On peut vérifier si tout est bien lancé, la commande systemctl status influxdb doit nous renvoyer Active: active (running)

Pour ceux qui utilisent une firewall, ne pas oublier d’ouvrir le port 8086 en TCP, en effet il s’agit du port sur lequel écoute l’API d’InfluxDB et par lequel nous allons lui envoyer nos données.

Configuration

Nous pouvons maintenant créerune base de données. Pour faire, entrons dans InfluxDB en tapant influx, nous arrivons dans le shell d’InfluxDB !

root@InfluxDB:~# influx
Connected to http://localhost:8086 version 1.7.8
InfluxDB shell version: 1.7.8
> 

Nous créons donc notre base de donnée thématique :

CREATE DATABASE meteo
exit

Voila ! Nous avons notre base de donnée, nous pouvons maintenant commencé à la remplir !

Note : Nous avons créer pour le moment une base de donnée simple, sans utilisateur ni droits spécifiques. N’importe qui peut accéder à la base de donnée, voir les valeurs et poster des valeurs. Ne pas utiliser ce type de configuration en dehors de votre réseau local. C’est seulement pour des tests et la découverte d’InfluxDB. Nous verrons plus bas comment sécuriser les accès à la base de données.

Petit point sur le fonctionnement

Juste un petit point avant de continuer, sur le fonctionnement et la sémantique d’InfluxDB.

Il faut garder à l’esprit 3 termes :

  • Le measurement, c’est l’équivalent d’une table d’une base de donnée classique, une base de donnée peut contenir plusieurs measurements. Par exemple : maison
  • Le couple tag keys et tag values, littéralement une clé et une valeur d’étiquette. Ça va permette de « trier, catégoriser » nos valeurs en ajoutant à notre donnée des métadonnées. Par exemple : capteur=dht22, notre clé est capteur, elle ne changera pas, mais on peut lui associer n’importe quelle valeur, comme dht22 si la donnée envoyée est celle du capteur DHT22. On peut en enchaîner plusieurs étiquettes pour une même donnée : capteur=dht22 et lieu=cuisine.
  • Le couple field key et field value, littéralement une clé et une valeur de champ. Il s’agit du « nom de la colonne ». Par exemple : temp. On peut bien évidement en enchaîner plusieurs si l’on veut stocker différentes valeur en même temps.
  • Pour finir, on peut renseigner un paramètre timestamp sous format Unix (nombre de nanosecondes depuis le 1er janvier 1970, UTC), exemple : 1434055562000000000.
    Si ce paramètre n’est pas renseigné, InfluxDB prendra le timestamp UTC lors de la réception de la requête. Le fait d’utiliser l’UTC nous prémuni de tout décalage à cause d’un OS mal configuré.

Note : On pourrait se demander à quoi bon créer des étiquettes alors qu’on peut créer des colonnes différentes pour stocker les infos (on pourrait créer un champ de valeur capteur-maison). En fait, l’astuce réside dans l’indexation. Les étiquettes sont indexées, c’est à dire que la base de données va être plus rapide si l’on fait une requête sur une étiquette (par exemple, je veux toutes les données de la dernière heure du capteur de la terrasse) que si on fait une requête sur la colonne capteur-maison.

A savoir, InfluxDB est assez souple par rapport aux bases de données SQL classique, c’est à dire que l’on peut créer des nouvelles colonnes de valeurs à la volée, lors de l’envoie des données. Si la clé du champ n’existe pas, alors une nouvelle colonne sera créée.
A savoir également, c’est la première donnée insérée dans un champs qui va définir le type du champ. Par exemple si je pousse une première donnée du type float (une température de 17.3), alors ce champs ne pourra à l’avenir accepter uniquement les valeurs de type float et une erreur apparaîtra si vous essayez d’insérer dans ce même champs une valeur de type boolean ou string.

Voila on a un peu posé les bases.

Bon on rempli la base ?

Il est maintenant possible de remplir la base de donnée directement avec l’URL du serveur via une requête de type POST (on POST des valeurs vers une URL).

Nous allons faire un petit test depuis un ordinateur du même réseau, grâce à curl, (si curl n’est pas installé -> apt install curl)

curl s’exécute côté OS, directement en ligne de commande, ce sui rend très facile l’automatisation d’envoi des données via des petits script et un cron.

curl -i -XPOST 'http://localhost:8086/write?db=meteo' --data-binary 'maison,capteur=dht22,lieu=cuisine value=20.3'

Ici nous exécutons curl depuis le serveur sur lequel est installé InfluxDB, donc nous postons vers localhost ou 127.0.0.1. Mais vous pouvons poster depuis n’importe quel périphérique du même réseau local en spécifiant l’adresse IP de votre serveur.

Les différentes réponses que vous pourriez avoir :

  • 2xx: Si le retour est HTTP 204 No Content, c’est un succés !
  • 4xx: La requête envoyée n’est pas comprise par influxDB, il y a une erreur syntaxe dans votre POST.
  • 5xx: Erreur côté serveur, ça sent pas bon en général…

Voir si les données arrivent bien

  • On se connecte à InfluxDB, puis à notre base de données.
  • On regarde quelques sont les measurements disponibles.
  • On fait un SELECT de base pour afficher les données, attention, utilisez LIMIT pour afficher seulement quelques lignes si la table est potentiellement bien remplie…

Faire une requête temporelle

La documentation officielle à lire ici.

Voici quelques exemples de requêtes qui font tout le charme d’InfluxDB : la manipulation facile des séries temporelles.

Les requêtes peuvent être faites directement en étant connecté à la base de donnée, soit à distance via curl. Nous allons ici exécuter les requêtes depuis InfluxDB directement.

# Exemple 1 : sélectionner la température moyenne sur les 3 dernières heures, du capteur placé dans la cuisine

SELECT mean(temp) FROM maison WHERE time > now()-6h AND lieu='cuisine' GROUP BY time(1h)

# Exemple 2 : sélectionner la température moyenne par heure sur les 6 dernières heures, du capteur placé dans la cuisine

SELECT mean(temp) FROM maison WHERE time > now()-6h AND lieu='cuisine' GROUP BY time(1h)

Mettre en place une authentification

Pour le moment, notre base de données est ouverte à tout vents. Pas top si l’on souhaite l’exposer au delà de son réseau local. Nous allons mettre en place une authentification du type utilisateur/mot de passe.

Par défaut, l’authentification est désactivé dans la configuration de InfluxDB (c’est pour cela que l’on a pu créer et insérer des données). Avant de l’activer, nous allons créer à minima un super-utilisateur (administrateur). Remplacer le mot de passe par un de votre choix.

root@INFLUX:~# influx
Connected to http://localhost:8086 version 1.7.9
InfluxDB shell version: 1.7.9
> CREATE USER admin WITH PASSWORD 'password' WITH ALL PRIVILEGES

On va maintenant créer un utilisateur (todd) avec des droits précis : lire et écrire dans une seule base de donnée qu’il faut avoir créé au préalable (NOAA_water_database). L’attribut ALL signifie lecture et écriture, mais on peut restreindre à la lecture seulement avec READ, ou l’écriture seulement avec WRITE.

CREATE USER todd WITH PASSWORD 'influxdb41yf3'
GRANT ALL ON "NOAA_water_database" TO "todd"

Nous voila avec un super-utilisateur qui peut tout faire, ainsi qu’un utilisateur qui peut lire et écrire dans une base de données. Activons maintenant l’authentification dans le fichier /etc/influxdb/influxdb.conf

[http]
  auth-enabled = true 

Puis on redémarre le service

systemctl restart influxdb

Maintenant, pour poster des données, nous devons fournir l’utilisateur et le mot de passe, sans quoi nous recevront une erreur de type HTTP/1.1 401 Unauthorized.

curl -i -XPOST 'http://localhost:8086/write?db=NOAA_water_database&u=todd&p=influxdb41yf3' --data-binary 'test,host=server01,region=us-west value=0.64'

Sécuriser les accès extérieur avec HTTPS

Pour le moment, nous somme en local, donc à priori il n’y a pas trop de risque d’interception des requêtes si votre réseau domestique n’est pas une passoire. En effet, en protocole HTTP, les information circulent en clair, c’est à dire que votre identifiant et votre mot de passe est accessible à n’importe qui capture votre traffic (Cf. ma série d’articles ici).

La gestion du SSL directement depuis InfluxDB est un peu délicate. En effet il est possible d’activer le SSL directement dans sa configuration et utiliser un certificat autosigné. Le problème des certificat autosigné réside dans le fait qu’il faut rajouter des options lors de l’émission de la requête pour explicitement donner l’autorisation de « croire » au certificat. Pas top, donc. Le mieux est d’utiliser un certificat fourni par Let’s Encrypt :

  • ouvrir les ports 80 et 443 sur son routeur
  • les mapper vers d’un serveur web dans votre réseau
  • faire la certification avec Certbot

Maintenant, il faut juste éditer la configuration du serveur web afin de rediriger le traffic pour influxDB vers la bonne machine (tout en bénificiant du HTTPS et du certificat Let’s Encrypt!)

# A ajouter sous la ligne "DocumentRoot /var/www/html"
<Location /influx> # Le chemin qui permet d'aiguiller 
ProxyPass http://192.168.1.100:8086 # IP de votre machine InfluxDB
ProxyPassReverse http://192.168.1.100:8086 # IP de votre machine InfluxDB
</Location>

Activer les modules de proxy de Apache2 et relancer le serveur web.

a2enmod proxy proxy_http
systemctl restart apache2

Dorénavant, il est possible de poster des données depuis l’internet mondial via l’url https://monnomdedomaine.fr/influx. Exemple de mise en pratique :

curl -i -XPOST 'https://monnomdedomaine.fr/influx/write?db=NOAA_water_database&u=todd&p=influxdb41yf3' --data-binary 'test,host=server01,region=us-west value=0.64'

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *