Necesito almacenar una gran cantidad de registros estructurados (potencialmente cientos de miles de millones) en una base de datos. Los datos serían escritos continuamente por muchos sensores, con una alta tasa de inserción (hasta 100k filas/segundo).
Los datos están bien estructurados, parece ser una buena combinación para una base de datos estructurada como Postgres. Sin embargo, me temo que el rendimiento no sería suficiente para la cantidad de datos que deben ingerirse.
Además, no necesito todas las características de una base de datos relacional (no necesito soporte completo de SQL). Los datos se escribirían una vez y se leerían varias veces como fragmentos grandes mediante consultas básicas como:
SELECT time, value FROM data WHERE time>1000 AND time<2500 AND sensor_location="home" ORDER BY time
Es decir, seleccione todos los registros entre dos marcas de tiempo para un sensor determinado (o conjunto de sensores). No necesito ninguna capacidad para realizar consultas complejas, como uniones o actualizaciones . La cláusula ORDER BY es importante, ya que necesito poder procesar estos mensajes en el orden en que fueron escritos (usando un script de Python). Estas consultas generalmente devuelven muchas filas y, a menudo, son demasiado grandes para caber en la RAM. Además, devolver tantas filas es muy lento con la mayoría de los RDBMS debido a su protocolo de conexión basado en texto, incluso si divido la consulta.
Este parece ser un buen caso de uso para una base de datos de series temporales como InfluxDB. Sin embargo, su versión de código abierto no se puede distribuir fácilmente (que es un requisito en mi caso, tanto para la resiliencia como para la escalabilidad), y mis pruebas mostraron que no tiene el rendimiento suficiente cuando se trata de consultas grandes (en particular, su protocolo de conexión es demasiado lento para transferir de manera eficiente tantas filas y, a veces, incluso falla cuando la consulta devuelve demasiadas filas).
Hace poco me enteré de Clickhouse, que es escalable horizontalmente y tiene un alto rendimiento. Tiene un protocolo de cable binario/comprimido y uno de los controladores de Python (clickhouse_driver) tiene una función execute_iter
que evita explotar la memoria RAM del cliente al realizar estas consultas grandes. Sin embargo, estoy bastante preocupado por su resistencia (la corrupción de datos no es tolerable en mi caso de uso) ya que es bastante reciente y tiene una base de usuarios limitada.
Soy consciente de que mi caso de uso es bastante específico. ¿Hay otras opciones gratuitas/de código abierto que deba tener en cuenta?
Parece que su caso es típico de ClickHouse, utilice el motor de tabla ReplicatedMergeTree https://clickhouse.tech/docs/en/engines/table-engines/mergetree-family/replication/
Eche un vistazo a la base de datos de series temporales de VictoriaMetrics . Maneja fácilmente un rendimiento de ingestión de 100 000 filas/s en un solo nodo con unos pocos núcleos de CPU. Está optimizado para almacenar y consultar billones ( 10^12
) de filas; consulte los estudios de casos . También escala a múltiples nodos; consulte los documentos para conocer la versión del clúster .
También proporciona el lenguaje de consulta MetricsQL , que está optimizado para consultas típicas de series temporales en producción. Por ejemplo, la siguiente consulta devolvería series de tiempo para todos los sensores de temperatura en casa: temperature{sensor_location="home"}
.
Debe tener en cuenta Warp 10 . Es escalable y se adapta bien a su caso de uso.
Dado que procesa los mensajes con Python, el hecho de que esté bien integrado con él debería ser relevante para usted. Es compatible con Pickle y Arrow para conectar datos a Python. También puede distribuir el procesamiento utilizando su integración con Spark.