Un graphique local, une file de lectures en attente d’une plateforme cloud et une archive conservée sept ans correspondent à trois stockages différents. Chacun répond à des questions distinctes, a un coût par lecture différent et présente ses propres modes de défaillance. Dimensionnez, conservez et testez chacun séparément.
Pour les mesures horodatées, commencez par une base de données de séries temporelles. Choisissez une base relationnelle si les lectures doivent être rapprochées de données métier, une base documentaire si la forme des messages varie et un stockage objet pour les fichiers et les jeux de données analytiques. Chacun peut être exploité sur site ou de manière centralisée.
Historique, transmission et reprise
Commencez par un contrat pour les données de capteurs : identité de la source, valeur, unité, heure de mesure, heure de réception, qualité et provenance des traitements. Le stockage doit en conserver assez pour interpréter une lecture même après un changement d’appareil ou de configuration.
| Stockage | Rôle | Mise en œuvre courante | Suppression d’un enregistrement |
|---|---|---|---|
| Historique interrogeable | Requêtes par période, graphiques et investigations | Base de séries temporelles ou table SQL partitionnée | Durée de conservation |
| File d’attente de transmission | Garder et réessayer les lectures non confirmées par un destinataire | Table SQLite ou file de courtier, avec des lignes propres à chaque destinataire | Confirmation par ce destinataire |
| Registre des équipements et configurations | Identité des appareils, association des canaux, échelles et unités | Base relationnelle ou fichiers de configuration versionnés | Modification volontaire conservée dans l’historique des versions |
| Archive | Conserver certains enregistrements pendant des années | Fichiers Parquet ou CSV en stockage objet | Règle de cycle de vie ou durée légale de conservation |
| Sauvegarde | Restaurer un système après perte ou dommage | Instantanés copiés hors de l’hôte | Calendrier de conservation des sauvegardes |
La dernière colonne explique la plupart des surprises. L’historique peut effacer des lectures que le destinataire n’a jamais reçues. Une file peut être vide parce que la transmission est terminée, parce qu’aucune donnée n’est arrivée ou parce qu’un filtre a écarté le point. Un graphique peut afficher des valeurs actuelles alors qu’il manque une semaine sur la plateforme cloud. Vérifiez ces résultats séparément.
Comparer les bases de données et les stockages IoT
Bases de séries temporelles
Utilisez une base de séries temporelles si la plupart des données sont des mesures numériques horodatées et si les requêtes portent sur les tendances et les agrégats par fenêtre temporelle. Avant de choisir, testez les arrivées tardives, les doublons, la cardinalité des étiquettes, les limites des requêtes et les paramètres de conservation dans l’édition que vous utiliserez.
VictoriaMetrics à nœud unique règle la conservation selon l’âge avec -retentionPeriod, fixé par défaut à un mois. Son guide de dimensionnement indique qu’un échantillon occupe environ un octet ou moins sur disque après compression et qu’un renouvellement fréquent des séries réduit cette compression. Calculez votre propre ratio avec vm_data_size_bytes et le nombre de lignes stockées. Gardez au moins 20 % du répertoire de données libres : VictoriaMetrics en a besoin pour fusionner les segments, et les requêtes ralentissent si cette fusion est impossible.
La cardinalité correspond au nombre de séries distinctes. Dans un système IoT, elle augmente lorsqu’une étiquette change souvent, par exemple si une version de micrologiciel ou une puissance de signal est enregistrée comme étiquette. Le débit de points reste identique, mais l’index grossit à chaque nouvelle combinaison. Placez les attributs changeants dans le registre des équipements, et non dans les étiquettes des séries.
Bases relationnelles
Utilisez une base relationnelle si les requêtes rapprochent les lectures des équipements, lots de production, périodes tarifaires ou dossiers de maintenance, et si l’équipe exploite déjà SQL en production.
Le partitionnement PostgreSQL répartit une grande table par plages temporelles. Supprimer ou détacher une ancienne partition est beaucoup plus rapide qu’un DELETE massif et évite le travail de VACUUM qui en résulte. L’extension TimescaleDB automatise ce principe : une hypertable est divisée en blocs temporels et une politique de conservation supprime les blocs dépassant l’âge fixé. Cette politique ne s’applique pas aux agrégats continus issus de l’hypertable : les agrégats horaires peuvent donc survivre aux lectures brutes. Testez la taille des index et les plans de requête avec au moins un mois de données représentatives.
Bases documentaires
Les bases documentaires conviennent aux fiches d’appareils et aux messages d’événement dont la structure varie. Les collections de séries temporelles MongoDB stockent les mesures dans l’ordre chronologique sous forme colonnaire et les regroupent par metaField, qui identifie la série. Les mises à jour sont limitées : la documentation restreint leurs critères de correspondance au metaField. Définissez comment conserver les valeurs corrigées avant de dépendre d’une modification sur place. La souplesse du document ne dispense pas de définir les unités, l’identité et le sens des horodatages.
Stockage objet et archives analytiques
Le stockage objet accueille les fichiers de mesures exportées, les preuves d’audit et les jeux de données analytiques. Le moteur de requêtes en est un composant distinct. Athena lit les formats colonnaires comme Parquet et ORC et ne lit que les colonnes nécessaires à la requête.
Deux règles du guide d’optimisation Athena comptent particulièrement pour les archives de capteurs. Premièrement, partitionnez selon les requêtes courantes : si les analystes consultent des journées, ne partitionnez pas par heure. Triez plutôt les enregistrements par horodatage dans chaque fichier. Deuxièmement, évitez les nombreux petits fichiers. La taille par défaut d’un groupe de lignes Parquet est de 128 Mo ; dans un petit fichier, le surcoût du format colonnaire peut dépasser son intérêt. Un site produisant 1 440 000 lectures par jour crée un fichier Parquet quotidien bien plus petit. Partitionnez par site et par mois ou regroupez plusieurs sites dans un fichier quotidien.
Placez une version de schéma et un contrat de données à côté des fichiers. Un répertoire de CSV sans ces éléments coûte peu à écrire, mais devient difficile à interpréter des années plus tard.
Vérifiez la classe de stockage. S3 Glacier Flexible Retrieval et Glacier Deep Archive exigent une demande de restauration avant lecture ; Glacier Instant Retrieval n’en exige pas. Dans le coût, ajoutez les frais de récupération, de requêtes, d’analyse et de transfert au prix du gigaoctet stocké.
Stockage sur site et centralisé
Un site autonome peut fonctionner avec le seul historique local. Ajoutez un stockage central si les équipes ont besoin de comparer plusieurs sites, de partager des rapports ou de conserver les données plus longtemps que le site ne le permet. Une architecture hybride offre les deux, mais ajoute une seconde copie à rapprocher, une file à surveiller et une autre politique de conservation.
| Besoin | Stockage | Essai |
|---|---|---|
| Examiner les événements récents d’un site pendant une coupure WAN | Historique local interrogeable | Débranchez le WAN. En tant qu’utilisateur local autorisé, retrouvez l’intervalle requis. |
| Comparer plusieurs sites | Stockage analytique central avec identité de site | Comparez unités, décalages d’horloge, intervalles et associations des équipements pour deux sites. |
| Traverser une coupure de liaison | File de transmission avec suffisamment de disque local | Bloquez le destinataire. Mesurez la croissance de la file, puis le temps de vidage après déblocage. |
| Conserver des preuves pendant des années | Archive brute ou agrégée avec moyen d’export | Confiez un fichier vieux d’un an à une personne extérieure au projet et demandez-lui de l’interpréter. |
| Rétablir un Gateway ou un serveur défaillant | Sauvegardes hors de l’hôte et procédure de restauration | Restaurez sur un matériel de rechange. Mesurez la durée et la lacune de données. |
Les niveaux chaud, tiède et froid décrivent la fréquence de consultation des données et la vitesse de récupération nécessaire. Une seule base avec deux politiques de conservation peut constituer deux niveaux. Chaque niveau supplémentaire exige un responsable, un contrôle du transfert et une action définie en cas d’échec.
Comment Edge conserve l’historique et retransmet les données
EpiSensor Edge conserve un historique local interrogeable dans VictoriaMetrics et les transmissions en attente dans une file SQLite distincte. Le mode d’historique local enregistre toutes les lectures valides, uniquement celles activées pour l’export, ou aucune. La durée de conservation se règle en jours et vaut 30 jours par défaut. VictoriaMetrics lit ce paramètre au démarrage : une modification prend effet après redémarrage d’Edge. Activer l’historique commence à enregistrer les lectures à cet instant ; les lectures jamais stockées ne peuvent pas être reconstituées.
Une transmission en état normal commence en mémoire. Edge garde chaque lecture en RAM jusqu’à ce que le destinataire confirme le succès, puis l’écarte sans l’écrire sur disque. Il ne l’écrit dans la file de reprise que si la transmission échoue ou si le destinataire est déjà connu comme hors ligne. L’historique local suit le même principe : Edge rassemble les lectures en mémoire pendant 250 ms au maximum, écrit le lot dans VictoriaMetrics et n’utilise la file de reprise que si cette écriture échoue. Cela limite les écritures sur l’eMMC du Gateway. Une coupure de courant ou un arrêt du processus avant la persistance peut faire perdre des lectures encore en mémoire.
Un producteur qui envoie des lectures à Edge par HTTP peut distinguer ces cas. La réponse 202 signifie qu’Edge a écrit le travail sur disque pour reprise. La réponse 200 indique une acceptation en mémoire. Une réponse 503 ou 507 indique qu’Edge a refusé un travail nécessitant le disque parce que le stockage est indisponible ou que la protection contre le manque d’espace s’est déclenchée. Le producteur doit garder les données et les renvoyer.
Edge considère une transmission directe comme achevée à une étape qui dépend du transport :
- MQTT : achèvement de la publication QoS 1.
- Export HTTP : réception du statut de succès configuré et du corps complet de la réponse.
- Export de fichier : écriture dans la file des fichiers en attente de cet export.
- Serveur Modbus : achèvement de toutes les écritures de registres du message.
La retransmission gérée par Edge ne concerne que les destinataires qui la déclarent, comme EpiSensor Core. Les autres flux d’intégration disposent de leurs propres tentatives ou transmettent au mieux. Vérifiez le cas de chaque intégration à la mise en service.
La file de reprise suit d’autres règles que l’historique. Dans la version actuelle, ses transmissions en attente n’expirent pas avec l’âge, car les supprimer ferait perdre des données non livrées. Une longue panne fait grossir la file jusqu’au rétablissement de la transmission ou jusqu’au refus de nouveaux travaux par la protection disque. Par défaut, celle-ci se déclenche lorsque l’espace libre descend à 10 % du système de fichiers, avec un plafond de 1 Gio, ou à 256 Mio. Chaque destinataire a ses propres lignes : un destinataire lent ne peut ni bloquer ni confirmer les données d’un autre. Les lectures retransmises conservent leur horodatage initial et ne sont envoyées qu’au destinataire qui les a manquées. Elles ne relancent ni les appareils calculés ni l’automatisation, qui ont déjà traité la lecture d’origine. Les écritures de la file utilisent SQLite synchronous=FULL : une ligne validée survit à une coupure de courant.
Dimensionner l’historique et la capacité de traverser une panne
Comptez les canaux qui transmettent, pas les appareils. Un compteur peut fournir plusieurs mesures à des intervalles différents. Pour un intervalle fixe :
Points par jour = canaux transmetteurs × 86 400 ÷ intervalle de transmission en secondes
Par exemple, 1 000 canaux transmis chaque minute produisent 1 440 000 points par jour, soit 43 200 000 points en 30 jours, avant filtrage. À une transmission par seconde, le débit est 60 fois plus élevé. Ajoutez séparément les rafales d’événements et les valeurs calculées.
Historique. Au ratio VictoriaMetrics d’environ un octet par point, 30 jours de cet exemple occupent environ 43 Mo d’échantillons, auxquels s’ajoutent l’index et une marge de 20 % d’espace libre. Une année représente environ 526 millions de points, soit environ 0,5 Go. Dans un essai synthétique EpiSensor, 200 000 lectures régulières occupaient 35 Ko dans VictoriaMetrics et 36 Mo dans une simple table SQLite, un rapport d’environ 1 000 à 1. Les valeurs réelles irrégulières se compressent moins bien : mesurez vos propres données.
File de reprise. Sur un Gateway de terrain, chaque lecture en attente occupait environ 550 octets de SQLite, index compris, pour chaque destinataire. Avec les mêmes 1 000 canaux, une panne de 72 heures met en file 4 320 000 lectures : environ 2,4 Go pour un destinataire ou 4,8 Go pour deux. Sur un ZGW-20 équipé de 16 Go d’eMMC en standard, c’est une part importante du disque. La file, et non l’historique, fixe alors la durée maximale de coupure que le Gateway peut traverser. L’option de calcul avec 64 Go d’eMMC ou le SSD de 128 Go en option l’étend. Pour calculer votre marge :
Heures de coupure couvertes = espace libre pour la file ÷ (octets par lecture en attente × lectures par heure × destinataires)
N’incluez pas dans cet « espace libre » la marge de protection disque, les journaux, les mises à jour ni la préparation des sauvegardes.
Pendant un pilote, mesurez ces quatre valeurs :
- La croissance de l’historique après la maintenance de la base : points conservés, nombre de séries, taille de l’index et utilisation du disque.
- La croissance de la file pour chaque destinataire pendant une panne contrôlée, y compris le journal d’écriture anticipée SQLite.
- Le débit de reprise : transmissions confirmées par seconde pendant que de nouvelles lectures continuent d’arriver.
- Tout le reste sur le disque : système d’exploitation, journaux, mises à jour et préparation des sauvegardes.
Le temps de vidage compte autant que la capacité. Supposons une file de 120 000 enregistrements, 100 nouveaux enregistrements par seconde et 300 confirmations par seconde. Le débit net de vidage est de 200 enregistrements par seconde : la file se vide donc au mieux en 600 secondes, soit 10 minutes. Les nouvelles tentatives et les limites de débit prolongent ce délai. Si le débit confirmé ne dépasse pas les arrivées, la file ne se vide jamais.
Ce que prouve un accusé de réception
Une connexion, un envoi, une confirmation et une mesure enregistrée sont quatre événements distincts. Définissez à chaque étape lequel signifie « terminé ».
| Preuve | Ce qu’elle établit | Vérification suivante |
|---|---|---|
| Requête d’entrée acceptée | Le service destinataire a accepté un travail selon son contrat API | Le contrat signifie-t-il mise en mémoire, file durable ou écriture validée dans une base ? |
| MQTT QoS 1 PUBACK avec code de succès | Le courtier a accepté la responsabilité du message | Traitement par l’abonné et présence de la mesure sur la plateforme cible |
| Réponse HTTP réussie | La condition de succès documentée par le point de terminaison | Corps de réponse, échecs partiels et résultat éventuel d’une importation asynchrone |
| Transfert de fichier achevé | Le fichier a atteint sa destination de transfert | Résultat de l’analyse et association correcte des enregistrements dans l’application |
| Requête d’historique renvoyant une lecture | Le stockage choisi contient cette mesure | Identité, horodatage, unité, valeur et exhaustivité attendue |
Dans la norme MQTT 5.0, le destinataire QoS 1 envoie PUBACK lorsqu’il a accepté la responsabilité du message (section 4.3.2). Cela ne prouve rien concernant les abonnés ou les bases en aval. Lisez le code de motif PUBACK (section 3.4.2.1) : 0x00 signifie Success. 0x10, No matching subscribers, est aussi un code de succès : le courtier a accepté un message qu’aucun abonné ne recevra. Les codes à partir de 0x80 signalent des échecs, notamment 0x87 Not authorized et 0x97 Quota exceeded. Consultez le guide de mise en service MQTTS pour les vérifications de transport et d’identité.
Les nouvelles tentatives créent des doublons si le destinataire valide un lot sans que l’émetteur enregistre la réussite. Donnez à chaque mesure une identité stable et rendez l’ingestion idempotente. Edge identifie les lignes de sa file par destinataire, identifiant d’export, identifiant de capteur, horodatage et valeur. Un même signal d’échec répété ne crée pas de seconde ligne, mais une valeur corrigée au même horodatage devient un nouvel enregistrement. Le destinataire doit appliquer sa propre règle. Une mise à jour ou insertion sur source, canal et horodatage garde la dernière correction ; une insertion qui ignore les conflits sur cette clé garde la première valeur. Choisissez explicitement et traitez de la même manière les arrivées tardives et les échantillons reçus dans le désordre.
La retransmission vaut seulement ce que vaut l’horodatage de chaque lecture. Si l’horloge est fausse au moment de marquer une lecture, par exemple après une coupure de courant avant la fin de la synchronisation, la retransmission livre fidèlement cette heure erronée et le destinataire range la lecture dans le mauvais intervalle. Conservez l’heure de réception à côté de l’heure de mesure pour rendre le décalage visible. Ne changez jamais l’heure de mesure d’origine pour donner l’impression qu’une ancienne lecture retransmise est actuelle.
Conservation, durabilité et sauvegarde
La conservation définit la durée de stockage de chaque classe d’enregistrements. Spécifiez séparément les lectures brutes, agrégats, événements, configurations, transmissions en attente et sauvegardes. Réduire la durée peut effacer des preuves nécessaires ; l’augmenter ne récupère pas des données déjà expirées.
Choisissez les agrégats selon la décision qu’ils doivent étayer. Une moyenne par intervalle peut masquer un pic bref. Un compteur d’énergie cumulatif exige de traiter remises à zéro et débordements ; additionner ses lectures ne donne pas la consommation. Conservez avec chaque résumé les unités, bornes des intervalles, couverture des échantillons et version de la transformation.
La durabilité définit quelles écritures confirmées survivent à une panne donnée. Elle dépend de tout le chemin d’écriture. La documentation SQLite sur la synchronisation l’illustre : en mode WAL avec synchronous=FULL, SQLite synchronise le journal après chaque validation et une transaction validée survit à une coupure de courant. Avec synchronous=NORMAL, la base reste cohérente, mais une transaction validée juste avant la coupure peut être annulée au redémarrage.
La sauvegarde et la restauration couvrent les dommages, les suppressions et les pertes. Une deuxième copie sur le même disque ne survit pas à la défaillance de ce disque ; la réplication propage aussi vite les changements indésirables que les bons. Convenez d’un objectif de point de reprise, c’est-à-dire la plus grande lacune acceptable dans les données restaurées, et d’un objectif de délai de reprise, soit la durée maximale acceptable avant le retour du service.
Sauvegardez une base active avec son propre mécanisme de cohérence. vmbackup copie des instantanés immédiats sans arrêter VictoriaMetrics. Une sauvegarde de VictoriaMetrics à nœud unique ne peut pas être restaurée dans un cluster, ni l’inverse. Gardez des copies dans un autre domaine de défaillance, protégez les identifiants et testez la restauration sur une cible isolée.
Sur Edge, vérifiez ce que couvre la sauvegarde choisie pour la version installée : l’historique de télémétrie, les services associés, l’état radio et la configuration de l’hôte ne figurent pas dans toutes les portées. Prouvez-le par un essai de restauration. Un envoi réussi prouve seulement l’existence du fichier de sauvegarde.
Mise en service du stockage
Avant de dépasser le stade pilote, désignez un responsable de l’architecture de stockage et effectuez ces vérifications :
- Prouvez la collecte et l’historique. Suivez une source, une valeur, une unité et un horodatage connus jusqu’aux requêtes locales et centrales requises.
- Interrompez la transmission. Bloquez un destinataire. Relevez la croissance de sa file, la plus ancienne lecture en attente, l’utilisation du disque et l’indication de panne présentée aux opérateurs.
- Rétablissez la liaison. Vérifiez que la file se vide pendant que les nouvelles données arrivent. Comparez ensuite les enregistrements de la plateforme destinataire pour la période de panne avec ceux de la source.
- Testez les doublons et les arrivées tardives. Vérifiez que la retransmission ne compte pas deux fois les lectures et ne remplace pas l’heure de mesure par l’heure d’arrivée.
- Exercez la reprise. Sur un système de test, arrêtez le service, puis coupez l’alimentation pendant l’arrivée de lectures. Restaurez une sauvegarde. Relevez toute lacune perdue et le temps nécessaire.
- Attribuez le suivi. Désignez les responsables des lectures manquantes, de l’âge de la file, de la capacité disque, des échecs de sauvegarde, des accès, de la conservation et des suppressions.
Pour un déploiement EpiSensor, commencez par les capacités locales d’Edge, puis ses intégrations aux plateformes. Si le destinataire ou la durée de conservation ne sont pas encore définis, parlez-nous de votre projet en précisant le nombre de canaux, les intervalles de transmission, la période de consultation requise, la durée de coupure à couvrir et les objectifs de reprise.
Questions fréquentes
Quelle base de données choisir pour stocker des données IoT ?
Il n’existe pas de meilleure base universelle. Les bases de séries temporelles conviennent aux mesures horodatées et aux requêtes par période. Les bases relationnelles rapprochent les lectures des données métier ; TimescaleDB ajoute le partitionnement temporel à PostgreSQL. MongoDB propose aussi des collections de séries temporelles. Choisissez après avoir testé des requêtes représentatives, l’utilisation réelle du disque, la conservation, la durée de restauration et la capacité de votre équipe à exploiter la solution.
Faut-il stocker les données IoT dans le cloud ou en périphérie ?
Conservez l’historique et les traitements sur site s’ils doivent fonctionner sans liaison WAN. Ajoutez un stockage central pour comparer plusieurs sites ou partager un historique plus long. Une architecture hybride exige une file de transmission, la gestion des doublons et une procédure de reprise pour chaque copie. Un système de suivi local peut fonctionner sans transmission vers le cloud.
De combien d’espace les données de capteurs IoT ont-elles besoin ?
Le nombre de points par jour correspond au nombre de canaux multiplié par 86 400, puis divisé par l’intervalle en secondes. Avec 1 000 canaux et un intervalle d’une minute, cela donne 1 440 000 points par jour. Après compression, VictoriaMetrics utilise environ un octet par point ou moins : 30 jours représentent donc environ 43 Mo, plus l’index. Une file SQLite peut demander environ 550 octets par point et par destinataire : une panne de 72 heures au même débit nécessite environ 2,4 Go par destinataire. Mesurez les deux avec vos propres données.
Une file de retransmission équivaut-elle à une base historique ?
Non. Une base historique répond aux requêtes sur les mesures enregistrées et les supprime selon leur âge. Une file de retransmission garde les lectures qu’un destinataire n’a pas confirmées et les efface après confirmation. Une file vide ne prouve pas que l’application destinataire a enregistré toutes les lectures attendues.
EpiSensor Edge évite-t-il toute perte de données pendant une panne ?
Non. Edge écrit une lecture dans sa file persistante lorsqu’un destinataire échoue ou est déjà connu comme hors ligne, puis la retransmet après le rétablissement. Les lectures encore en mémoire sont perdues si le courant ou le processus Edge s’arrête avant que l’issue de la transmission soit connue. La file cesse également d’accepter de nouveaux travaux lorsque la protection contre le manque d’espace disque se déclenche.