Influxdb


Influxdb est une base de données clef-valeur à la différence d'Elasticsearch qui est une base de données documentaire.

Les dernières versions ont d'excellentes performances, avec un serveur avec 16 coeurs virtuels sur un amazon EC2 avec des ssd on arrive à près de 900 000 indexations par seconde (https://www.influxdata.com/influxdb-1-1-released-with-up-to-60-performance-increase-and-new-query-functionality/)

Le fait que la version serveur ne soit plus libre risque de ralentir l'utilisation de cet outil qui est encore jeune.

3.1 Quelques commandes influxdb

• Lancement du serveur influxdb : ./influxd
• Lancement de l'interface texte de influxdb : ./influxdb
• Lister les bases de données : show databases
• Utiliser la base de données a : use a
• Afficher la liste des variables numérique : show field keys
• Afficher la liste des variables non numérique : show tag keys
• Effacer base de données a : DROP DATABASE a

• Commande pour importer base :
./influx -import -path=/home/alfard/Documents/NFA204/tt4.txt -precision=ns
L'option precision permet de préciser le format du temps de la base qui est importée.

  • rfc3339 pour YYYY-MM-DDTHH:MM:SS.nnnnnnnnnZ
  • h : par heure
  • m : par minute
  • s : par seconde
  • ms : par milliseconde
  • u : par microseconde
  • ns : par nanoseconde, précision par défaut

3.2 Format Line Protocol

Le programme suivant permet de changer le fichier csv dans le format Line Protocal qui est utilisé par influxdb. Il est à noter que les nouvelles versions de influxdb ne supportent plus que ce format, le support du format json a été arrêté.
Détail du format Line Protocal :
https://docs.influxdata.com/influxdb/v1.2/write_protocols/line_protocol_tutorial/

Programme pour changer csv dans le format Line Protocol

import scala.io.Source
import java.io._
val startTimeMillis = System.currentTimeMillis()
for (lines <-
Source.fromFile("/home/alfard/Documents/NFA204/Phones_gyroscope.csv").getLines()) {
val iter = lines.mkString.split(",")
val rt = "sensors" + ",gt=" + iter(9) + ",user=" + iter(6) + ",model=" + iter(7) + ",device=" +
iter(8) + " x=" + iter(3) + ",y=" + iter(4) + ",z=" + iter(5) + " " + iter(1)
val pw = new PrintWriter(new FileOutputStream(new
File("/home/alfard/Documents/NFA204/tt4.txt"),true))
pw.write(rt+System.lineSeparator)
pw.close
}
val endTimeMillis = System.currentTimeMillis()
val durationSeconds = (endTimeMillis - startTimeMillis) / 1000

Exemple d'un document au format Line Protocal
sensors,gt=stand,user=a,model=gear,device=gear_1 x=-0.5650316,y=-9.572019,z=-
0.61411273 1424696638740

Une fois le fichier Line Protocal créé, il faut supprimer la ligne du nom des variables et il faut rajouter en tête du fichier la partie suivante qui donne un nom à la base importée car on procède à l'intégration en utilisant l'éxécutable influxdb et non l'interface REST.

# DDL
CREATE DATABASE sensors
# DML
# CONTEXT-DATABASE: sensors

3.3 Vitesse d'indexation

On lance la commande d'indexation suivante :
./influx -import -path=/home/alfard/Documents/NFA204/tt4.txt -precision=ns
À la fin du traitement nous avons le résultat suivant :
...
2017/02/25 00:38:41 Processed 13800000 lines. Time elapsed: 5m7.624637496s. Points per
second (PPS): 44859
2017/02/25 00:38:43 Processed 13900000 lines. Time elapsed: 5m9.421517233s. Points per
second (PPS): 44922
2017/02/25 00:38:44 Processed 1 commands
2017/02/25 00:38:44 Processed 13932632 inserts
2017/02/25 00:38:44 Failed 0 inserts

Avec des vitesses allant jusqu'à 50 000 points par seconde, influxdb arrive en cinq minutes à
indexer un document de près de 14 millions de ligne ce qui est assez impressionnant.
Le traitement semble très optimisé et procède à des compressions de données durant
l'importation pour réduire l'espace disque.
Une fois la base créé on peut lancer quelques requêtes.

3.4 Requêtes supplémentaires

Le langage de requête est proche du SQL.
Avoir la liste des différents "device"
show tag values on "sensors" with key = "device"

La moyenne de la variable x
select mean("x") as toto from "sensors"

Avoir le nombre de mesures par utilisateur
select count(*) as toto from "sensors" group by "user"

Première ligne de la base de données
select * from "sensors" limit 1
name: sensors
time device gt model user x y z
--------------------------------------------------
1424686740286 gear_2 stand gear g 4.0186677 -7.15567 -3.3411086