KeyDB como reemplazo [potencial] de Redis

No hubo reseñas sobre una "alternativa más rápida a Redis" en Habré - base de datos clave. Habiendo adquirido una experiencia bastante reciente en su uso, me gustaría llenar este vacío.

KeyDB como reemplazo [potencial] de Redis

El trasfondo es bastante banal: un día, con una gran afluencia de tráfico, se registró una degradación significativa en el rendimiento de la aplicación (es decir, el tiempo de respuesta). En ese momento lamentablemente no fue posible realizar un diagnóstico normal de lo que estaba sucediendo, por lo que posteriormente se planificaron una serie de pruebas de carga. Después de realizarlos, pudimos descubrir un cuello de botella, que era el caché de la base de datos en Redis. Como sucede a menudo, los desarrolladores no pudieron resolver el problema de inmediato y de la manera correcta (cambiando la lógica de trabajo). Por tanto, se encendió la curiosidad y el deseo de superar la situación de forma indirecta. Así apareció este artículo.

Problemas

Acerca de Redis en general

Como mucha gente sabe, Redis es una base de datos de un solo subproceso. Para ser más precisos, es así en el contexto de trabajar con datos de usuario. Después de todo, desde la cuarta versión, servicio, operaciones internas de Redis. transferido para ejecución paralela. Sin embargo, este cambio solo afectó a una pequeña parte de la carga de trabajo, ya que la mayor parte del trabajo se realiza con los datos del usuario.

Se han roto innumerables copias sobre este tema, pero los desarrolladores de Redis se niegan obstinadamente a implementar el paralelismo total, mencionando cuánto complicará la aplicación y aumentará los costos generales, además de agregar más errores. Su posición es la siguiente: si se enfrenta a un problema de un solo núcleo, tiene problemas con la arquitectura de la aplicación y es necesario cambiar algo en ella. Entre los usuarios, sin embargo, también hay "otro bando": aquellos que están atrapados en un núcleo y afirman que Redis se está creando un cuello de botella. En el caso de cargas realmente grandes, tarde o temprano, es inevitable encontrar este problema, que impone restricciones significativas a la arquitectura y/o complicaciones forzadas en la misma.

No evaluaré tal o cual opinión. En lugar de eso, compartiré nuestro caso específico y cómo lo resolvimos.

Nuestro caso

En uno de los proyectos nos encontramos con el hecho de que el equipo de desarrollo había configurado un almacenamiento en caché extremadamente agresivo de los datos de la base de datos (PostgreSQL) a través de Redis. Esta fue la única forma que, durante las afluencias repentinas de tráfico, salvó a PostgreSQL y, como resultado, a la aplicación de la muerte.

Después de una serie de pruebas de carga, analizamos la situación y descubrimos que Redis estaba limitado a un núcleo (lo que se llama un "estante"), seguido de una degradación bastante rápida de la aplicación. El “asfixio” fue exponencial: en cuanto se alcanzó el límite de rendimiento de Redis, todo dejó de funcionar.

Se parecía a esto:

KeyDB como reemplazo [potencial] de Redis

New Relic identificó claramente el problema:

KeyDB como reemplazo [potencial] de Redis

Aquí están las estadísticas de la operación: get en Redis:

KeyDB como reemplazo [potencial] de Redis

Después de informar detalladamente del problema al equipo de desarrollo, resultó que "el problema no se puede resolver en este momento". Así comenzó la búsqueda de una solución en el lado operativo, y el ya mencionado KeyDB fue la respuesta.

Sin embargo, antes de comenzar nuestra revisión, vale la pena mencionar que el proyecto utiliza Redis independiente, ya que la solución de clúster basada en Sentinel es muy inferior en términos de latencia. Una solución obvia era crear varias réplicas del caché: ¡y dejar que la aplicación vaya a todas partes con equilibrio! Sin embargo, después de consultar con los desarrolladores, nos vimos obligados a descartar esta opción debido al complejo y activo mecanismo de invalidación de caché de la aplicación. El mismo problema se extendió a la fragmentación de la caché.

Una mirada rápida a KeyDB

Mientras buscábamos una posible solución al problema, descubrimos aplicación llamada KeyDB. Esta es una bifurcación de Redis desarrollada por empresa canadiense y distribuido bajo la licencia BSD gratuita. El proyecto es muy joven: existe desde principios de 2019. Su historia es que los autores también encontraron una vez las limitaciones de Redis... y decidieron hacer su propia bifurcación. Además, no sólo resolvió problemas conocidos, sino que también recibió funciones adicionales que sólo están disponibles en la versión empresarial de Redis.

Para aquellos que quieran familiarizarse con KeyDB con más detalle, existe una buena artículo introductorio sobre Medium, que presenta el DBMS y breves puntos de referencia comparándolo con su "padre": Redis.

En primer lugar, KeyDB nos atrajo por la posible solución a nuestros problemas y, al mismo tiempo, nos interesaron algunas características adicionales. El uso de KeyDB prometía las siguientes ventajas:

  • obtener subprocesos múltiples completos;
  • compatibilidad total y absoluta con Redis (esto fue especialmente importante para nosotros, ya que no fue posible realizar ninguna modificación en el lado de la aplicación), lo que también prometió una migración sin problemas;
  • mecanismo de respaldo incorporado en el almacenamiento S3;
  • fácil de implementar la replicación activa;
  • agrupación y fragmentación sencillas sin Sentinel ni otro software de soporte.

Más de 3 estrellas y muchos contribuyentes en GitHub también parecían alentadores. La aplicación se desarrolla y admite de forma bastante activa, lo que se ve claramente en las confirmaciones, la comunicación en los problemas y en los RP cerrados (aceptados). La respuesta del mantenedor principal en todos los frentes es siempre amigable y rápida. En general, hubo muchas discusiones.

Migración y resultados

Aunque el proyecto de migración fue un poco arriesgado (debido a la novedad de KeyDB), no había mucho que perder. Después de todo, revertir los cambios es bastante rápido y sencillo; afortunadamente, toda la infraestructura está implementada en Kubernetes y los mecanismos integrados Actualización continua Resuelven muy bien estos problemas.

En general, preparamos plantillas de Helm, cambiamos la aplicación en el entorno de prueba a una nueva base de datos y lo implementamos todo, entregándolo al departamento de control de calidad del cliente.

Comenzaron las pruebas, que duraron aproximadamente una semana y en cuyos detalles no profundizamos. Solo sabemos que el cliente probó las funciones estándar de trabajar con Redis usando un controlador PHP. phpredisy también realizó pruebas de control de calidad de la interfaz de usuario. Después de eso, nos dieron luz verde: no se encontraron efectos secundarios al utilizar el nuevo software. Eso es Desde el punto de vista de la aplicación, nada ha cambiado en absoluto..

Vale la pena señalar que no cambiamos nada en la configuración: literalmente, simplemente reemplazamos la imagen utilizada. Lo mismo ocurre con el seguimiento y la exportación de métricas a Prometheus: el más común de ellos Funciona perfectamente con KeyDB y sin modificaciones. Por lo tanto, podemos decir con seguridad que desde un punto de vista operativo, este es simplemente un movimiento ideal.

Gracias a todo esto, después de cambiar la aplicación a un nuevo DBMS, no puedes cambiar nada, pero como “medida de estabilización” puedes dejarla así para que funcione en combate durante un tiempo. Sin embargo, si desea ver un aumento en el rendimiento (o cualquier cambio), no debe olvidar que por defecto Parámetro KeyDB responsable del subproceso múltiple (server-threads), es igual a uno, es decir El DBMS funciona exactamente igual que Redis.

Después de cambiar, probar y un tiempo de vida de la nueva aplicación (con KeyDB), decidimos repetir las pruebas de carga con los mismos parámetros que se usaron para Redis. ¿Cuáles fueron sus resultados?...

Según el gráfico de consumo de CPU, la eliminación de los problemas con el “techo” de un núcleo se hizo evidente de inmediato: el proceso comenzó a utilizar los recursos disponibles:

KeyDB como reemplazo [potencial] de Redis

Y luego intenté “torturar” la aplicación con bastante fuerza y ​​vi un consumo de hasta tres núcleos...

Según New Relic, la aplicación web en su conjunto, con la misma carga, empezó a comportarse notablemente mejor. Aún se observó cierta degradación del rendimiento; sin embargo, en comparación con un gráfico similar anterior, puedes evaluar el progreso significativo por ti mismo:

KeyDB como reemplazo [potencial] de Redis

La latencia de la nueva base de datos (KeyDB) también empeoró, pero se mantuvo dentro de valores aceptables:

KeyDB como reemplazo [potencial] de Redis

El siguiente gráfico muestra claramente que el número de solicitudes al propio KeyDB es similar:

KeyDB como reemplazo [potencial] de Redis

Para resumir estas pruebas sintéticas, podemos decir que tanto Redis como KeyDB muestran una degradación significativa del rendimiento en latencia (40 ms+) con un aumento significativo en el número de conexiones paralelas (1000+). En nuestro caso, la aplicación web pudo "desperdiciar" la latencia de Redis incluso con un número menor de conexiones (más de 400), aunque para KeyDB dicha carga siguió siendo aceptable.

Hallazgos

Este ejemplo muestra claramente la fortaleza de la comunidad Open Source en el desarrollo de proyectos en los que está interesada. En Internet encontré una excelente afirmación, cuyo significado general se reducía a lo siguiente: “Alguna gran empresa crea un producto interesante, abre algunas de sus funciones, pero deja la parte más importante pagada. La comunidad lo usa y lo usa, y luego alguien se da por vencido y crea una bifurcación, implementando las mismas funciones pagas y abriéndolas a todos”. Aquí KeyDB es el mismo caso.

Hablando de la migración en sí, que fue sorprendentemente sencilla, no recibimos así un aumento significativo en el rendimiento, que se puede esperar mirando los gráficos de los autores de KeyDB... Sin embargo, este es solo nuestro caso especial, en el que puede haber muchas desviaciones, incluida la notoria arquitectura de la aplicación (por ejemplo , una gran cantidad de comandos get en Redis en lugar de la opción más eficaz de consultas agregadas mget...). Sin embargo, logramos lograr resultados positivos y, junto con ellos, muchas funciones útiles que implementaremos en un futuro próximo.

En general, KeyDB parece prometedor: a medida que adquiramos experiencia práctica con este DBMS (¡y todavía tenemos que adquirirla!) y desarrollemos el proyecto en sí, consideraremos la posibilidad de usarlo en otras situaciones.

Sin embargo, este artículo no debe considerarse como una guía (y mucho menos un llamado) a la acción por el abandono generalizado de Redis en favor de KeyDB. A pesar de nuestra experiencia positiva, está claro que no se trata de una solución milagrosa. El caso era muy específico: específicamente para resolver un problema momentáneo en una situación en la que era necesario hacerlo rápidamente y con un costo mínimo, esta solución estaba justificada. ¿KeyDB será útil en su caso? Al menos ahora sabes que existe esta posibilidad potencial.

PS

Lea también en nuestro blog:

Fuente: habr.com

Añadir un comentario