Una gráfica local de tendencias, una cola de lecturas pendientes para la plataforma en la nube y un archivo de siete años son almacenes distintos. Cada uno responde preguntas diferentes, cuesta una cantidad diferente por lectura y falla de forma diferente. Dimensione, conserve y pruebe cada almacén por separado.
Para medidas con marca temporal, empiece por una base de datos de series temporales. Use una base relacional cuando deba relacionar las lecturas con registros empresariales, una documental si varían las estructuras de las cargas útiles y almacenamiento de objetos para archivos y conjuntos analíticos. Cualquiera puede funcionar en la instalación o de forma centralizada.
Historial, entrega y recuperación
Empiece por un contrato de datos de sensores: identidad de origen, valor, unidad, hora de medida, hora de recepción, calidad y procedencia del procesamiento. El almacenamiento debe conservar lo suficiente para interpretar una lectura después de que cambie el dispositivo o su configuración.
| Almacén | Función | Implementación habitual | Qué elimina un registro |
|---|---|---|---|
| Historial consultable | Consultas por intervalo de tiempo, gráficas e investigación | Base de series temporales o tabla SQL particionada | Retención por antigüedad |
| Cola de salida | Retener y reintentar lecturas aún no confirmadas por un destino | Tabla SQLite o cola del bróker, con filas independientes por destino | Confirmación de ese destino |
| Activos y configuración | Identidad del dispositivo, mapeo de canales, escalado y unidades | Base relacional o archivos de configuración versionados | Cambio deliberado, conservado en el historial de versiones |
| Archivo | Conservar ciertos registros durante años | Archivos Parquet o CSV en almacenamiento de objetos | Regla de ciclo de vida o plazo legal de conservación |
| Copia de seguridad | Restaurar un sistema tras pérdida o daño | Instantáneas copiadas fuera del equipo | Política de retención de copias |
La última columna explica muchas sorpresas. El historial puede eliminar lecturas que un destino aún no recibió. Una cola puede estar vacía porque terminó la entrega, porque no llegó nada o porque un filtro eliminó el punto. Una gráfica puede mostrar valores actuales mientras a una plataforma en la nube le falta una semana. Compruebe cada resultado por separado.
Comparación de bases de datos y almacenamiento IoT
Bases de series temporales
Use una base de series temporales si la carga principal son lecturas numéricas con hora, agregaciones por ventana y consultas de tendencias. Antes de elegirla, pruebe llegadas tardías, duplicados, cardinalidad de etiquetas, límites de consulta y retención en la edición que instalará.
VictoriaMetrics de un solo nodo fija la retención por antigüedad con -retentionPeriod; el valor predeterminado es un mes. Su guía de dimensionamiento indica aproximadamente 1 byte o menos por muestra comprimida y advierte de que una gran rotación de series reduce la compresión. Calcule su cifra con vm_data_size_bytes y el número de filas almacenadas. Mantenga libre al menos el 20 % del directorio de datos: VictoriaMetrics necesita ese espacio para fusionar segmentos y las consultas se ralentizan si no puede hacerlo.
La cardinalidad es el número de series distintas. En IoT crece cuando una etiqueta cambia con frecuencia, como una versión de firmware o intensidad de señal guardada como etiqueta. La frecuencia de puntos no cambia, pero el índice crece con cada combinación nueva. Guarde atributos cambiantes en el almacén de activos, no en las etiquetas de series.
Bases relacionales
Use una base relacional cuando las consultas vinculen lecturas con equipos, lotes de producción, periodos tarifarios o registros de servicio, y el equipo ya opere SQL en producción.
El particionado de PostgreSQL divide una tabla grande por intervalos de tiempo. Eliminar o separar una partición antigua es mucho más rápido que un DELETE masivo y evita el trabajo de VACUUM que este provoca. TimescaleDB lo automatiza: divide una hypertable en fragmentos temporales y su política de retención elimina los fragmentos antiguos. Esa política no se aplica a las agregaciones continuas construidas sobre la hypertable, de modo que los agregados horarios pueden sobrevivir a sus lecturas brutas. Pruebe tamaño de índices y planes de consulta con al menos un mes de datos representativos.
Bases documentales
Los almacenes documentales sirven para fichas de dispositivos y cargas útiles de eventos con estructura variable. Las colecciones de series temporales de MongoDB agrupan medidas ordenadas por hora en formato columnar mediante un metaField que identifica la serie. Las actualizaciones están limitadas: la documentación restringe las condiciones de búsqueda de actualización al metaField. Planifique cómo guardar valores corregidos antes de depender de actualizaciones en el mismo registro. Una estructura flexible sigue necesitando definiciones de unidades, identidad y significado temporal.
Almacenamiento de objetos y archivos analíticos
El almacenamiento de objetos guarda archivos de medidas exportadas, pruebas de auditoría y conjuntos analíticos. El motor de consultas es otro componente. Athena lee formatos columnares como Parquet y ORC y solo las columnas que necesita la consulta.
Dos reglas de la guía de optimización de Athena son importantes para archivos de sensores. Primero, particione para la consulta habitual: si los analistas trabajan por día, no particione por hora. Ordene los registros por marca temporal dentro de cada archivo. Segundo, evite muchos archivos pequeños. El grupo de filas Parquet predeterminado es de 128 MB; en archivos pequeños, el coste adicional del formato columnar supera la ventaja. Una instalación con 1.440.000 lecturas diarias produce un Parquet diario mucho menor. Particione por instalación y mes, o incluya varias instalaciones en un archivo diario.
Guarde la versión del esquema y el contrato de datos junto a los archivos. Un directorio de CSV sin ellos es barato de escribir y caro de interpretar años después.
Compruebe la clase de almacenamiento. S3 Glacier Flexible Retrieval y Glacier Deep Archive requieren una solicitud de restauración antes de leer un objeto; Glacier Instant Retrieval no. Incluya los costes de recuperación, solicitudes, consultas y transferencia, además del precio por gigabyte almacenado.
Almacenamiento local y central
Una instalación independiente puede funcionar solo con historial local. Añada un almacén central cuando los equipos necesiten comparar instalaciones, elaborar informes compartidos o conservar datos más tiempo del que permite cada lugar. Una arquitectura híbrida ofrece ambas cosas, pero añade una segunda copia que conciliar, una cola que supervisar y otra política de retención.
| Requisito | Almacén | Prueba |
|---|---|---|
| Investigar eventos recientes durante un corte de WAN | Historial local consultable | Desconecte la WAN. Recupere el intervalo necesario como usuario local autorizado. |
| Comparar varias instalaciones | Almacén analítico central con identidad de instalación | Compare unidades, desfases de reloj, intervalos y mapeos de activos de dos instalaciones. |
| Superar un corte de conexión | Cola de salida con espacio local suficiente | Bloquee el destino. Mida crecimiento de la cola y tiempo de vaciado al desbloquearlo. |
| Conservar pruebas durante años | Archivo bruto o agregado con ruta de exportación | Entregue un archivo de hace un año a alguien externo al proyecto y pídale que lo interprete. |
| Recuperar una Gateway o servidor averiado | Copias externas y procedimiento de restauración | Restaure en hardware de repuesto. Registre el tiempo y el hueco de datos. |
Los niveles caliente, templado y frío describen con qué frecuencia se leen los datos y cuánto pueden tardar en recuperarse. Una base con dos políticas de retención puede ofrecer dos niveles. Cada nivel añadido necesita responsable, comprobación de transferencia y acción definida si esta falla.
Cómo almacena Edge el historial y reenvía datos
EpiSensor Edge mantiene un historial local consultable en VictoriaMetrics y entregas pendientes en una cola de salida SQLite aparte. El modo de historial guarda todas las lecturas válidas, solo las habilitadas para exportación o ninguna. La retención se fija en días y es de 30 por defecto. VictoriaMetrics lee el ajuste al iniciarse, así que un cambio se aplica tras reiniciar Edge. Activar el historial empieza a registrar en ese momento; no puede reconstruir lecturas que nunca se almacenaron.
Una entrega normal comienza en memoria. Edge retiene cada lectura en RAM hasta que el destino comunica el éxito y después la descarta sin escribirla en disco. Solo la añade a la cola si falla la entrega o el destino ya figura como desconectado. El historial local funciona de manera semejante: Edge acumula lecturas hasta 250 ms en memoria, escribe el lote en VictoriaMetrics y recurre a la cola solo si falla la escritura. Este diseño reduce escrituras en la eMMC de la Gateway. Un corte de alimentación o parada del proceso antes de persistir puede perder lecturas en tránsito.
Un productor que envía lecturas a Edge por HTTP puede distinguir los casos. Una respuesta 202 significa que Edge escribió el trabajo en disco para reenvío; 200 significa que aceptó las lecturas en memoria. 503 o 507 significan que rechazó trabajo con respaldo en disco porque no está disponible o se activó la protección por poco espacio. El productor debe conservar y reenviar esos datos.
Edge considera completa una entrega en un punto que depende del transporte:
- MQTT: finalización de la publicación QoS 1.
- Exportación HTTP: estado de éxito configurado tras recibir todo el cuerpo de respuesta.
- Exportación a archivo: escritura en la cola de archivos pendientes de exportación.
- Servidor Modbus: finalización de todas las escrituras de registros del mensaje.
El reenvío propio de Edge se aplica a destinos que lo declaran, como EpiSensor Core. Otros flujos de integración gestionan sus propios reintentos o realizan entregas sin garantía. Confirme el comportamiento de cada integración durante la puesta en servicio.
La cola de salida sigue reglas distintas del historial. En la implementación actual, las entregas pendientes no caducan por antigüedad porque eliminarlas descartaría datos no entregados. Un corte prolongado hace crecer la cola hasta que se recupera el destino o la protección por poco espacio rechaza nuevos trabajos. Por defecto, esta protección se activa cuando el espacio libre baja al 10 % del sistema de archivos, con un máximo de 1 GiB, o a 256 MiB. Cada destino tiene sus propias filas, por lo que uno lento no bloquea ni confirma los datos de otro. Las lecturas reenviadas conservan sus marcas temporales originales. El reenvío solo va al destino que perdió los datos y no vuelve a ejecutar dispositivos calculados ni automatizaciones, porque ya procesaron la lectura original. Las escrituras de la cola SQLite utilizan synchronous=FULL, de modo que una fila confirmada sobrevive a un corte eléctrico.
Dimensionar historial y capacidad ante cortes
Cuente canales que informan, no dispositivos. Un contador puede publicar varias magnitudes con intervalos distintos. Para un intervalo fijo:
Puntos diarios = canales que informan × 86.400 ÷ intervalo de informe en segundos
Por ejemplo, 1.000 canales que informan una vez al minuto producen 1.440.000 puntos diarios, o 43.200.000 en 30 días, antes de filtrar. A un segundo, la frecuencia es 60 veces mayor. Añada por separado ráfagas de eventos y valores calculados.
Historial. Con aproximadamente 1 byte por punto según VictoriaMetrics, 30 días del ejemplo representan unos 43 MB de muestras, más índice y margen del 20 % de espacio libre. Un año supone unos 526 millones de puntos o cerca de 0,5 GB. En una prueba sintética de EpiSensor, 200.000 lecturas periódicas ocuparon 35 KB en VictoriaMetrics y 36 MB en una tabla SQLite simple: una proporción cercana a 1.000 a 1. Los valores de campo con ruido comprimen peor que los sintéticos; mida con datos propios.
Cola de salida. En una Gateway de campo, cada lectura en cola ocupó unos 550 bytes de SQLite, índices incluidos, por destino. Los mismos 1.000 canales durante un corte de 72 horas generan 4.320.000 lecturas: unos 2,4 GB para un destino o 4,8 GB para dos. En una ZGW-20 con eMMC estándar de 16 GB, es gran parte del disco, y la cola, no el historial, determina el corte máximo que puede superar. La opción de eMMC de 64 GB o SSD opcional de 128 GB amplía ese periodo. Para calcular su capacidad:
Horas de corte cubiertas = espacio libre para la cola ÷ (bytes por lectura en cola × lecturas por hora × destinos)
No incluya en el «espacio libre» el umbral de protección, registros, actualizaciones ni área temporal de copias.
En un piloto, mida cuatro valores:
- Crecimiento del historial después del mantenimiento de la base: puntos retenidos, número de series, tamaño de índice y uso del disco.
- Crecimiento de la cola por destino durante un corte controlado, incluido el registro de escritura anticipada de SQLite.
- Rendimiento de recuperación: entregas confirmadas por segundo mientras siguen llegando lecturas nuevas.
- Todo lo demás en disco: sistema operativo, registros, actualizaciones y área temporal de copias.
El tiempo de vaciado importa tanto como la capacidad. Suponga una cola de 120.000 registros, 100 registros nuevos por segundo y un destino que confirma 300 por segundo. La velocidad neta es 200 registros por segundo y, en el mejor caso, la cola se vacía en 600 segundos, o 10 minutos. Reintentos y limitación de velocidad aumentan ese tiempo. Si el rendimiento confirmado no supera las llegadas, la cola nunca se vacía.
Qué demuestra una confirmación
La conexión, el envío, la confirmación y una observación almacenada son eventos distintos. Defina cuál cuenta como finalización en cada tramo.
| Prueba | Qué establece | Qué comprobar después |
|---|---|---|
| Solicitud de entrada aceptada | El servicio receptor aceptó trabajo según su contrato de API | Si el contrato significa memoria, cola persistente o escritura confirmada en la base |
| PUBACK MQTT QoS 1 con código de éxito | El bróker se hizo cargo del mensaje | Procesamiento del suscriptor y lectura almacenada en la plataforma de destino |
| Respuesta HTTP correcta | Condición de éxito documentada del extremo | Cuerpo de respuesta, fallos parciales y resultado de importación asíncrona |
| Transferencia de archivo completa | El archivo llegó al destino de transferencia | Resultado del analizador y registros correctamente mapeados en la aplicación |
| Consulta del historial devuelve la lectura | El almacén elegido contiene esa observación | Identidad, marca temporal, unidad, valor e integridad esperada |
Según el estándar MQTT 5.0, un receptor QoS 1 envía PUBACK tras aceptar la responsabilidad del mensaje (sección 4.3.2). Esto no demuestra nada sobre suscriptores o bases posteriores. Lea el código de motivo de PUBACK (sección 3.4.2.1): 0x00 es éxito; 0x10, sin suscriptores coincidentes, también es código de éxito: el bróker aceptó un mensaje que nadie recibirá. Los códigos 0x80 y superiores son fallos, como 0x87, no autorizado, y 0x97, cuota superada. Consulte la guía de puesta en servicio MQTTS para comprobar transporte e identidad.
Los reintentos crean duplicados si un receptor confirma un lote y el emisor no registra el éxito. Dé identidad estable a cada observación y haga idempotente la ingesta. Edge identifica filas de la cola por destino, ID de exportación, ID de sensor, marca temporal y valor. Repetir una señal de fallo no crea otra fila, pero un valor corregido con la misma hora sí es otro registro. El receptor necesita su propia regla. Una actualización por origen, canal y hora conserva la última corrección; una inserción que ignora conflictos con la misma clave conserva el primer valor. Elija deliberadamente y trate del mismo modo lecturas tardías y fuera de orden.
El reenvío solo es tan bueno como la marca temporal de cada lectura. Si el reloj estaba mal al asignarla, por ejemplo tras un corte antes de sincronizarse, el reenvío conserva fielmente la hora incorrecta y el receptor coloca la lectura en el intervalo equivocado. Guarde hora de recepción junto a la de medida para que se vea el desfase. Nunca cambie la marca temporal de origen de una lectura antigua para que el reenvío parezca actual.
Retención, durabilidad y copias de seguridad
La retención define cuánto tiempo se guarda cada clase de registro. Especifique por separado lecturas brutas, agregados, eventos, configuraciones, entregas pendientes y copias. Reducirla puede eliminar pruebas necesarias; aumentarla no recupera datos ya vencidos.
Elija agregados para la decisión que deben respaldar. Una media por intervalo puede ocultar un pico breve. Un acumulado de energía necesita tratar reinicios y desbordamientos: sumar sus lecturas no da el consumo. Conserve unidades, límites de intervalo, cobertura de muestras y versión de transformación en cada resumen.
La durabilidad define qué escrituras confirmadas sobreviven a un fallo especificado y depende de toda la ruta. La documentación de sincronización de SQLite lo ilustra. En modo WAL con synchronous=FULL, SQLite sincroniza el registro anticipado después de cada confirmación y una transacción confirmada sobrevive al corte eléctrico. Con synchronous=NORMAL, la base se mantiene coherente, pero una transacción confirmada justo antes del corte puede revertirse al reiniciar.
Las copias y restauraciones permiten recuperarse de daños, borrados o pérdidas. Una segunda copia en el mismo disco tampoco sobrevive a su fallo, y la replicación copia cambios no deseados tan deprisa como los deseados. Acuerde un objetivo de punto de recuperación (el máximo hueco aceptable de datos recuperados) y uno de tiempo de recuperación (el máximo plazo aceptable para restablecer el servicio).
Haga copias de un almacén activo mediante su mecanismo de consistencia. vmbackup copia desde instantáneas, así que no hace falta detener VictoriaMetrics. Una copia de VictoriaMetrics de un solo nodo no se puede restaurar en un clúster, ni al revés. Guarde copias en otro dominio de fallo, proteja credenciales y ensaye restauraciones en un destino aislado.
En Edge, compruebe qué recupera el alcance de copia elegido para la versión instalada: historial de telemetría, servicios auxiliares, estado de radio y configuración del host no están en todos los alcances. Demuéstrelo mediante un ensayo de restauración. Una carga correcta solo demuestra que existe un archivo de copia.
Puesta en servicio de la ruta de almacenamiento
Antes de ampliar el piloto, nombre al responsable de la arquitectura de almacenamiento y haga estas comprobaciones:
- Demuestre la recogida y el historial. Siga un origen, valor, unidad y marca temporal conocidos hasta las consultas locales y centrales necesarias.
- Interrumpa la entrega. Bloquee un destino. Registre crecimiento de la cola, lectura pendiente más antigua, uso del disco e indicación de fallo para operadores.
- Recupere la conectividad. Confirme que la cola se vacía mientras continúan los datos actuales. Compare después los registros del periodo de corte en la plataforma con el origen.
- Pruebe duplicados y datos tardíos. Confirme que el reenvío no cuenta dos veces ni sustituye la hora de medida por la de llegada.
- Ensaye la recuperación. Use un sistema de prueba. Detenga el servicio y después corte la alimentación mientras llegan lecturas. Restaure una copia. Registre cualquier intervalo perdido y el tiempo empleado.
- Asigne la responsabilidad continua. Nombre quién vigila lecturas ausentes, antigüedad de cola, capacidad de disco, fallos de copias, accesos, retención y eliminación.
Para un despliegue EpiSensor, empiece por las capacidades locales de Edge y después sus integraciones de plataforma. Si aún no están definidos el destino o la retención, consulte el despliegue indicando número de canales, intervalos de informe, ventana de consulta necesaria, duración prevista de los cortes y objetivos de recuperación.
Preguntas frecuentes
¿Cuál es la mejor base de datos para datos IoT?
No hay una única mejor base. Las de series temporales sirven para medidas con hora y consultas por intervalo. Las relacionales sirven cuando las lecturas deben vincularse con registros empresariales; TimescaleDB añade particionado temporal a PostgreSQL. MongoDB también ofrece colecciones temporales. Elija probando consultas representativas, uso real de disco, retención, tiempo de restauración y capacidad operativa del equipo.
¿Debo guardar datos IoT en la nube o localmente?
Conserve historial y procesamiento en la instalación cuando deban seguir disponibles sin WAN. Añada un almacén central para analizar varias instalaciones o compartir una retención más larga. Una arquitectura híbrida necesita cola de entrega, tratamiento de duplicados y procedimiento de recuperación para cada copia. Un sistema local de monitorización no necesita enviar datos a la nube para funcionar.
¿Cuánto espacio necesitan los datos de sensores IoT?
Los puntos diarios son canales que informan multiplicados por 86.400 y divididos por el intervalo en segundos. Con 1.000 canales cada minuto se obtienen 1.440.000 puntos diarios. VictoriaMetrics guarda aproximadamente 1 byte o menos por punto comprimido: 30 días son unos 43 MB más índice. Una cola SQLite puede necesitar unos 550 bytes por punto y destino: un corte de 72 horas a esa frecuencia supone unos 2,4 GB por destino. Mida ambos con sus datos.
¿Una cola de reenvío equivale a una base de historial?
No. Una base histórica consulta medidas registradas y las elimina por antigüedad. Una cola de reenvío retiene lecturas aún no confirmadas por un destino y las borra al recibir su confirmación. Una cola vacía no demuestra que la aplicación receptora guardó todas las lecturas esperadas.
¿Edge evita toda pérdida de datos durante un corte?
No. Edge escribe una lectura en la cola respaldada en disco si falla el destino o ya consta como desconectado y la reenvía al recuperarse. Las lecturas todavía en memoria se pierden si falla la alimentación o se detiene Edge antes de conocer un éxito o fracaso. La cola deja de aceptar trabajo nuevo cuando se activa la protección por poco espacio.