12 puntos por xguru 2024-09-26 | 7 comentarios | Compartir por WhatsApp
  • Wafris es una empresa de firewall de aplicaciones web de código abierto que ofrece un cliente middleware para Rails
  • El cliente v1 requería un almacén de datos local en Redis, pero en v2 usa SQLite
  • Explica el contexto de la decisión de migrar de Redis a SQLite, así como las consideraciones de rendimiento y los cambios de arquitectura

TL;DR

  • SQLite tiene cosas para las que es bueno y cosas para las que no
  • Redis tiene cosas para las que es bueno y cosas para las que no
  • Los RDBMS tradicionales (Postgres/MySQL) tienen cosas para las que son buenos y cosas para las que no
  • Estos almacenes de datos no se pueden sustituir directamente entre sí, y tratar de hacerlo te meterá en problemas
  • Este artículo describe las pruebas y el proceso de decisión al re-arquitectar el cliente v1 basado en Redis hacia un cliente v2 basado en SQLite

Factores que forzaron el cambio

  • El objetivo de Wafris es hacer que a los desarrolladores les resulte fácil proteger sus sitios
  • Por problemas de despliegue de Redis, v1 no logró plenamente ese objetivo
  • Eligieron Redis porque trabajaban en entornos como Heroku, donde es fácil usar Redis, pero muchos usuarios tuvieron problemas al desplegar Redis
  • Obligar a los usuarios a usar una base de datos aparte como Redis no estaba pensado para beneficiar al usuario

¿Qué significa "velocidad"?

  • Redis es “más rápido” que un RDBMS tradicional, pero aun así hay que gestionar conexiones, memoria, procesos, etc.
  • En entornos cloud, la latencia de red puede ser un problema grande
  • Como las reglas de Wafris deben evaluarse en cada solicitud HTTP entrante, la latencia de red puede ralentizar la aplicación

Suposición de monolito (Monolith-ish)

  • Existen aplicaciones totalmente distribuidas, pero la mayoría de las apps Rails son “Majestic Monoliths”
  • Las apps desplegadas en varias regiones, divididas en servidores con funciones superpuestas o que solo son parcialmente Rails presentan más problemas al usar Redis

Repensando la arquitectura

  • Wafris es un firewall de aplicaciones web que se instala como middleware de Rails
  • Simplificándolo en dos pasos: 1) comparar solicitudes HTTP contra reglas, y 2) reportar el resultado del procesamiento
  • La “lectura” de reglas (paso 1) es mucho más importante que la “escritura” (paso 2)
  • Las lecturas deben procesarse en secuencia, no pueden fallar y afectan el rendimiento percibido por el usuario
  • Las escrituras pueden ser lentas, procesarse por lotes o hacerse de forma asíncrona

Entra SQLite

  • Otras personas ya han explicado bien para qué casos de uso SQLite es adecuado
  • SQLite no compite con las bases de datos cliente/servidor, sino con fopen()
  • Esperaban que al eliminar la ida y vuelta por red fuera mucho más rápido que Redis
  • Decidieron evaluar SQLite y Redis con benchmarks

Benchmarking de SQLite y Redis

  • Hacer benchmarks es un arte oscuro para engañarte con números precisos
  • Hacer benchmarks de almacenes de datos es todavía más complicado
  • No buscaban una velocidad absoluta, sino crear benchmarks específicos para sus datos y su caso de uso
  • Ignoraron tweaks de optimización. Querían que Wafris funcionara al instante al integrarlo en una app
  • Probaron la ruta crítica principal de su app y su peor consulta, no benchmarks teóricos
  • La peor consulta era una solicitud a una estructura de datos compleja de “lexical decimal” que mapea rangos de IP (IPv4, IPv6) a categorías
  • Precalcularon las búsquedas por rango y las escribieron en tablas de SQLite y conjuntos ordenados de Redis
  • En cada solicitud HTTP entrante, deben comparar la IP de la solicitud con rangos personalizados de allow/block, rangos GeoIP y rangos de reputación IP

Protocolo de prueba

  • Probaron con Redis instalado por Homebrew en una MacBook Air M2 y una base de datos SQLite local
  • Hicieron pruebas con su conjunto de datos de rangos existente (1.2 millones de entradas)
  • Ejecutaron varios conjuntos de IP sobre SQLite y Redis en el mismo orden
  • Para cada multiplicador, ejecutaron la prueba 5 veces y sacaron el promedio

Resultados de la prueba

  • SQLite aplastó a Redis (en su caso de uso específico)
  • SQLite fue aproximadamente 3 veces más rápido que una instancia local de Redis
  • Esto fue antes de considerar la latencia de red
  • Incluso si SQLite solo empatara con Redis, seguiría siendo ventajoso por eliminar el tiempo de red

Lo que no aparece en la gráfica

  • Aunque el rendimiento de SQLite fuera 2 veces peor en el benchmark, en la práctica podría ser más rápido por la latencia de red
  • Por más potente que sea el servidor Redis, existen límites de ancho de banda de red, conexiones y latencia entre regiones
  • SQLite ofrece escalado horizontal casi infinito “gratis”
  • La experiencia de onboarding mejora muchísimo con SQLite. Es probable que el usuario ni note que se está usando
  • Se podía exprimir más rendimiento de Redis, pero era difícil convencer a los usuarios de cambiar su configuración de Redis

Los resultados son solo el comienzo

  • Demostraron que SQLite era más rápido que Redis, pero hay compensaciones reales
  • La prueba anterior no consideraba las escrituras
  • Para gestionar la competencia entre lecturas y escrituras se necesitan conexiones a la base de datos, pools de conexiones, transacciones, etc.
  • Igual que a un superauto eléctrico le cuesta cargar bloques de concreto, no se debe usar SQLite para un rol para el que no es adecuado

Construyendo una arquitectura de sincronización

  • En v1 (Redis), cuando el usuario actualizaba reglas en Wafris Hub, se actualizaban las reglas del almacén de datos Redis
  • Eso no funciona con SQLite, porque no se puede “empujar” hacia el servidor web
  • En v2 (SQLite): 1) el usuario actualiza reglas en Wafris Hub, 2) el cliente revisa a intervalos si hay reglas actualizadas, 3) si las reglas se actualizaron, descarga una base de datos SQLite completamente nueva
  • Esto reduce drásticamente la responsabilidad del usuario en instalación y configuración
  • La tasa de éxito de instalación del cliente v2 aumentó 3 veces

Arquitectura distribuida con SQLite

  • Pensemos en una app Rails desplegada en un proveedor cloud con autoescalado activado
  • Si las solicitudes pasan de 100 req/s a 10,000 req/s, las instancias de cómputo escalan, pero la base de datos no
  • De hecho, esa es una razón principal por la que las apps Rails se caen por sobrecarga
  • Sincronizar la base de datos SQLite en cada instancia de cómputo resuelve este problema al mantener todas las llamadas en local

¿Y qué pasa con las escrituras?

  • Dividieron la app en rutas de lectura (evaluación de reglas) y escritura (reportes), y luego ignoraron la ruta de escritura
  • Rediseñaron la ruta de escritura como 1) reportar conectándose de forma asíncrona a Wafris Hub, 2) enviar reportes por lotes y 3) eliminar por completo las escrituras a la base de datos del cliente
  • Puede que esto no funcione para otros, pero a ellos solo les importan los usuarios que quieren un cliente de Wafris rápido y fácil de desplegar

Conclusión

  • Están muy satisfechos con la arquitectura v2 basada en SQLite
  • Ya está ayudando a muchos sitios a resistir ataques y mantenerse en línea
  • Empezar ahora es mucho más fácil, lo que reduce el trabajo de soporte para ellos y las molestias para los usuarios
  • Consideran que esto es una victoria para un internet más seguro y protegido

7 comentarios

 
aer0700 2024-09-26

SQLite es suficientemente bueno, pero en este caso da la impresión de que simplemente no era un caso de uso adecuado para Redis...

 
kandk 2024-09-26

Que el benchmark se haya hecho en una M2 es como que...

 
colossus 2024-09-29

Entonces, ¿hay que medirlo en cada instancia de AWS? Me parece que están pidiendo demasiado de un proyecto de código abierto.

 
toru123 2024-09-27

¿Se hizo en el mismo entorno de servidor; eso sería un problema?
¿Y para el benchmark hay que usar un CPU específico...?

 
superwoou 2024-09-26

¿Qué aspectos de lo que se hizo en m2 podrían ser problemáticos? (aparte del hecho de que el entorno de servicio real no usa un procesador m2)

 
kandk 2024-09-26

Ese es el problema. Hacer experimentos en el laboratorio y afirmar: ¡esto es perfecto para uso comercial!

 
[Este comentario fue ocultado.]