La arquitectura sin servidor de SQLite no sirve bien al IoT
Corporación Actian
17 de junio de 2020

Tercera parte: SQLite, el "archivo plano"de las bases de datos
En los últimos artículos, nuestra serie de blogs sobre SQLite ha analizado la arquitectura sin servidor de SQLite y su inadecuación para entornos IoT. Aquellos de ustedes que han estado siguiendo puede saltar a la siguiente sección, pero si eres nuevo en esta discusión, es posible que desee revisar las partes predecesoras.
- En la primera parte, mobile may be IoT, but IoT is not mobile when it comes to data, examinamos el hecho de que, aunque SQLite es la base de datos más popular del planeta -en gran parte debido a su ubicuo déploiement en smartphones y tabletas móviles, donde soporta aplicaciones Embarqué para un solo usuario-, no puede soportar los requisitos multiconexión, multiusuario y multiaplicación de los casos de uso de IoT que proliferan con ferocidad viral en todos los sectores. En un mundo que exige el rendimiento de guepardos y halcones peregrinos, SQLite es una babosa bananera.
- En la segunda parte, Replanteamiento de lo que significa cliente-servidor para Edge gestion des données gestion des données, analizamos las funciones y características clave de la arquitectura sin servidor SQLite (portabilidad, poca o ninguna configuración, tamaño reducido, API SQL y alguna versión inicialmente gratuita para sembrar la adopción) a la luz de las necesidades de la moderna Edge gestion des données y debatimos las deficiencias de la arquitectura SQLite en cuanto a su capacidad para integrarse con las funciones críticas que se encuentran en las bases de datos cliente-servidor tradicionales (principalmente los calificativos multipunto mencionados anteriormente).
En nuestro análisis final de esta arquitectura sin servidor, me gustaría mucho explorar (léase: aclarar) lo que sucederá si un desarrollador ignora estos puntos de advertencia y dobla hacia abajo en SQLite como una forma de manejar los casos de uso de la IO.
No confunda multiconexión y multihilo con cliente-servidor
A finales de los 90, a medida que las aplicaciones se volvían más sofisticadas, generaban e ingerían más datos y realizaban internamente operaciones más complejas con esos datos. En consecuencia, los desarrolladores de aplicaciones tuvieron que desarrollar un montón de soluciones para hacer frente a las limitaciones de los servicios rutinarios de gestión de archivos basados en el sistema operativo. En lugar de dedicar tiempo a todos estos esfuerzos de bricolaje, los desarrolladores de aplicaciones clamaban por una base de datos dedicada que pudieran Embarquer en una aplicación para dar soporte a sus necesidades específicas de gestion des données .
A principios delsiglo XXI apareció SQLite, que parecía hecho a medida para satisfacer estas necesidades. SQLite permitía indexar, consultar y otras funciones gestion des données mediante una serie de llamadas SQL estándar que podían insertarse en el código de la aplicación, con toda la base de datos incluida como un conjunto de bibliotecas que formaban parte del ejecutable final desplegado. Hay que tener en cuenta que la mayoría de estas aplicaciones solían ser monolíticas, de un solo propósito y para un solo usuario, diseñadas para las arquitecturas de processeur más sencillas que se utilizaban en aquella época. No estaban diseñadas para ejecutar múltiples procesos, y mucho menos múltiples hilos. El usuario final y la seguridad de los datos aún no eran tan prioritarios como lo son hoy. ¿Y en cuanto al rendimiento en un entorno de red? Las redes inalámbricas eran reactivas e irregulares en el mejor de los casos. Las conexiones de datos múltiples, externas y de gran ancho de banda eran poco comunes.
Así que no es de extrañar que SQLite no fuera capaz de dar servicio a peticiones simultáneas de lectura y escritura para una única conexión (y mucho menos para múltiples conexiones) cuando se diseñó. Los diseñadores estaban encantados de tener una base de datos integrable que permitiera a múltiples procesos tener acceso secuencial de lectura y escritura a una tabla de datos dentro de una aplicación. No buscaban capacidades cliente-servidor de nivel empresarial. No estaban diseñando sistemas de bases de datos independientes que soportaran múltiples aplicaciones simultáneamente. Simplemente necesitaban algo más que el acceso a archivos planos mediado por un sistema operativo.
Y ahí radica el meollo del problema con SQLite. Nunca fue concebido para manejar múltiples aplicaciones externas o sus conexiones de forma asíncrona, como lo haría una base de datos cliente-servidor tradicional. Las aplicaciones modernas en red suelen tener múltiples procesos y/o múltiples hilos. Cuando se lanza SQLite a una situación con múltiples conexiones y la posibilidad de múltiples peticiones simultáneas de lectura y escritura, rápidamente se encuentra la posibilidad de condiciones de carrera y corrupción de datos.
Para ser justos, SQLite ha intentado acomodarse a estas demandas cambiantes. La versión actual de SQLite maneja múltiples conexiones a través de sus opciones de modo de hilo: hilo único, multihilo y serializado. Single-thread es el modo de procesamiento original de SQLite, que maneja una transacción a la vez, ya sea una lectura o una escritura desde una y sólo una conexión. Multi-thread soportará múltiples conexiones pero siempre una a la vez para lectura o escritura. Serializado -el modo por defecto de las versiones más actuales de SQLite- puede soportar múltiples conexiones concurrentes (y, por tanto, puede soportar una aplicación multihilo o multiproceso), pero no puede manejarlas todas simultáneamente. SQLite puede manejar conexiones de lectura simultánea en los modos multihilo y serializado, pero bloquea las tablas de datos para evitar intentos de escritura simultánea. SQLite tampoco puede gestionar la orquestación de escrituras desde varias conexiones.
Compárelo con la arquitectura de una verdadera base de datos cliente-servidor, construida para gestionar escrituras simultáneas. La base de datos cliente-servidor evalúa cada solicitud de servicio de escritura y, si se intenta escribir en los mismos datos dentro de una tabla, bloquea la solicitud hasta que finalice la operación actual en esos datos. Si los intentos se realizan en diferentes partes de la tabla de datos, el servidor permite que sigan adelante. Eso es verdadera orquestación. Bloquear toda la tabla y retener las escrituras (o fingir que se producen escrituras secuenciales junto a múltiples lecturas con WAL) no es lo mismo.
¿Por qué es esto un obstáculo para SQLite en un entorno IoT? Una de las operaciones más básicas con dispositivos y puertas de enlace IoT consiste en escribir datos desde una variedad de dispositivos en su repositorio de datos, y los bloqueos de escritura impuestos durante las operaciones multihilo/multiconexión lo hacen inviable en un entorno de producción. Además, una segunda operación básica que tiene lugar en un entorno IoT implica la realización de procesamiento y análisis de datos en conjuntos de datos recopilados previamente. Aunque estas pueden ser operaciones de lectura intensiva que se ejecutan de forma independiente (ya sea como procesos separados o como hilos separados) de las operaciones de escritura intensiva que se acaban de describir, todavía no pueden ocurrir de forma concurrente en un entorno SQLite y mantener el cumplimiento de ACID.
A medida que se amplían los despliegues o aumenta la complejidad del sistema (por ejemplo, si se desea instrumentar más y más dentro de un entorno, ya sea un coche autónomo o un edificio inteligente), se añadirán invariablemente más puntos de conexión de datos aguas abajo o dentro del entorno local. Cada una de estas entidades tendrá una o más conexiones de base de datos adicionales, si no su propia base de datos que necesita una conexión. Puede intentar establecer estas conexiones, pero tendrán que gestionarse a través de lógica de aplicación adicional que probablemente dará lugar a tiempos de respuesta que están fuera de las restricciones de diseño para su sistema IoT.
Soluciones diseñadas para negar (o desafiar) la realidad
Los partidarios de SQLite agitarán sus manos con despreocupación y te dirán que SQLite es lo suficientemente rápido (no lo es; ya hemos discutido lo lento que es SQLite) y que puedes construir tu propia funcionalidad para manejar lecturas y escrituras simultáneas a través de múltiples conexiones-en efecto, sincronizándolas manualmente de forma específica para el caso de uso que se está manejando. Un método por el cual manejan este escenario implica el uso del modo serializado mencionado anteriormente y la construcción de funcionalidad para manejar la sincronización y la orquestación dentro de los hilos de la aplicación. Este enfoque trata de evitar la transmisión de peticiones de lectura y escritura en múltiples canales (evitando así condiciones de carrera y el potencial de corrupción de datos). Sin embargo, este enfoque también requiere un alto grado de habilidad, la asunción de la responsabilidad a largo plazo para el código, y la necesidad de una amplia prueba y validación para garantizar que las operaciones se están desarrollando correctamente.
Un enfoque alternativo sería construir el equivalente a un front-end de orquestación cliente-servidor y utilizar la opción de un solo hilo dentro de SQLite, lo que evitaría condiciones de carrera o corrupción de datos. Pero volver a la opción de un solo hilo sería como ver a esta babosa de plátano moverse a cámara aún más lenta. No es un enfoque viable, dadas las operaciones de escritura paralelas y de alta velocidad necesarias para acomodar múltiples fuentes de datos de alta resolución o redes de sensores a gran escala. Además, todo lo que se ha hecho es acomodar las debilidades de la arquitectura de la base de datos forzando a la aplicación a hacer algo que la base de datos debería estar haciendo. Y tendría que hacerlo una y otra vez, para cada aplicación de su cartera IoT.
Existen varios conjuntos de código y un par de pequeñas tiendas que han intentado producir este último enfoque, pero con un éxito limitado. Sólo funcionan con determinadas plataformas de desarrollo en algunas de las plataformas compatibles con SQLite. Incluso si esas plataformas se adaptan a tu caso de uso, los problemas de rendimiento pueden aumentar el riesgo y la dificultad de codificar esta solución en tu aplicación.
Ya hemos visto este iceberg antes
Este cuento con moraleja no se refiere únicamente a la cantidad de bricolaje en que se incurrirá con la incuestionable dependencia de SQLite para una aplicación determinada. Como el propio IoT, es mucho más que eso. Por ejemplo, si te comprometes a manejar esto en tu propio código, ¿cómo manejarás el movimiento de datos desde un dispositivo hasta el sur site edge sur site? ¿Cómo se gestionará el movimiento de datos hacia o desde la nube? Los requisitos para interactuar con los servidores en ambos niveles pueden ser diferentes, lo que le obligará a escribir más código para realizar transformaciones de datos (¿recuerda el blog sobre SQLite y ETL?). Podrías intentar evitar el cuello de botella de ETL utilizando SQLite en ambos extremos, pero eso sólo sería una patada a la lata virtual. Todavía tendrías que escribir código para manejar SQLite enmascarado como una base de datos basada en servidor en la pasarela y en la nube.
En última instancia, no puedes escapar a la necesidad de escribir más código para hacer que SQLite funcione en cualquiera de estos escenarios. Y eso es sólo la punta del iceberg. Tendrías que hacer comparaciones entre DIY y partial-DIY más módulos/bibliotecas de código para otras funcionalidades-desde encriptación de datos y gestión de clave pública hasta edición de consultas SQL, y más. La lista de funciones que aporta una verdadera infraestructura cliente-servidor, de las que carece SQLite, es interminable.
En su día, SQLite permitió a los desarrolladores evitar gran parte del bricolaje que había requerido la gestión de archivos planos. Para los casos de uso que estaban surgiendo entonces, era una solución ideal. Sin embargo, para los casos de uso actuales, se necesitaría aún más bricolaje para que SQLite funcionara, e incluso así no funcionaría del todo bien. La gran mayoría de los casos de uso del IoT requieren un nivel de funcionalidad cliente-servidor que SQLite no puede proporcionar sin incurrir en costes significativos en rendimiento, tiempo de desarrollo y riesgo. En pocas palabras, es un déjà vu, pero ahora SQLite es el archivo plano cuyas deficiencias debemos dejar en el pasado.
Ah, y si crees que todo esto es sólo un problema para los desarrolladores, piénsalo otra vez. En el próximo y último blog de esta serie, ampliaremos un poco la perspectiva y analizaremos lo que esto significa para la empresa y el balance final.
Si está listo para reconsiderar SQLite y aprender más sobre Actian Zen, puede probarlo gratuitamente con Zen Core, que está libre de derechos de autor para el desarrollo y la distribución.
Suscríbase al blog de Actian
Suscríbase al blog de Actian para recibir información sobre datos directamente en su correo electrónico.
- Manténgase informado: reciba lo último en análisis de datos directamente en su bandeja de entrada.
- No se pierda ni una publicación: recibirá actualizaciones automáticas por correo electrónico que le avisarán cuando se publiquen nuevas publicaciones.
- Todo depende de usted: cambie sus preferencias de entrega para adaptarlas a sus necesidades.