
Dicen que en la vida vale la pena intentarlo al menos una vez. Y si está acostumbrado a trabajar con DBMS relacionales, vale la pena familiarizarse en la práctica con NoSQL, en primer lugar, al menos para el desarrollo general. Ahora, debido al rápido desarrollo de esta tecnología, hay muchas opiniones contradictorias y acalorados debates sobre este tema, lo que está alimentando especialmente el interés.
Si profundiza en la esencia de todas estas disputas, puede ver que surgen debido al enfoque equivocado. Aquellos que usan bases de datos NoSQL exactamente donde se necesitan están satisfechos y obtienen todas sus ventajas de esta solución. Pero los experimentadores que confían en esta tecnología como una panacea donde no es aplicable en absoluto, están decepcionados de perder las fortalezas de las bases de datos relacionales sin obtener beneficios significativos.
Le contaré sobre nuestra experiencia en la implementación de una solución basada en Cassandra DBMS: lo que tuvimos que enfrentar, cómo salimos de situaciones difíciles, logramos obtener un beneficio al usar NoSQL y dónde tuvimos que invertir esfuerzo / dinero extra.
La tarea inicial es construir un sistema que registre las llamadas a un determinado almacenamiento.
El principio del sistema es el siguiente. Los archivos con una determinada estructura que describe la estructura de la llamada llegan a la entrada. Luego, la aplicación asegura que esta estructura se guarde en las columnas apropiadas. En el futuro, las llamadas guardadas se utilizan para mostrar información sobre el consumo de tráfico para los suscriptores (cargos, llamadas, historial de saldos).

Por qué Kassandra fue elegida es bastante comprensible: escribe como una ametralladora, fácilmente escalable y tolerante a fallas.
Entonces, esto es lo que nos dio la experiencia
Sí, el nodo estrellado no es una tragedia. Esa es la esencia de la tolerancia a fallas de Cassandra. Pero el nodo puede estar vivo y al mismo tiempo comenzar a ceder en el rendimiento . Al final resultó que, esto afecta inmediatamente el rendimiento de todo el clúster.
Cassandra no cubre donde Oracle salvó con sus constantes . Y si el autor de la aplicación no entendió esto de antemano, entonces el vuelo de Cassandra no es peor que el original. Una vez que vino, lo insertaremos.
A Kassandra gratuita "lista para usar " no le gustó mucho la seguridad de la información: no hay registro de las acciones del usuario ni tampoco diferenciación de derechos . La información de la llamada se refiere a datos personales, lo que significa que todos los intentos de solicitarlos / cambiarlos de alguna manera deben registrarse con la posibilidad de una auditoría posterior. Además, debe ser consciente de la necesidad de separar los derechos en diferentes niveles para diferentes usuarios. Un ingeniero de operaciones simple y un súper administrador que puede eliminar libremente todo el espacio de teclas son roles diferentes, responsabilidades diferentes, competencias. Sin tal diferenciación de los derechos de acceso, el valor y la integridad de los datos se cuestionarán inmediatamente más rápido que con CUALQUIER nivel de consistencia.
No tomamos en cuenta que las llamadas requieren análisis serios, así como muestras periódicas para una variedad de condiciones. Dado que se supone que los registros seleccionados deben eliminarse y reescribirse (en el marco de la tarea, debemos apoyar el proceso de actualización de los datos cuando el bucle de datos ingresó inicialmente incorrectamente), Kassandra no es nuestra amiga aquí. Es conveniente poner Cassandra, como una alcancía, pero no podrás contar con ella.
Enfrentó el problema de transferir datos a zonas de prueba (5 nodos en la prueba versus 20 en la fiesta de graduación). En este caso, no se puede usar un volcado.
El problema de actualizar el esquema de datos de una aplicación que escribe en Kassandra. La reversión dará lugar a una gran cantidad de lápidas, que de manera impredecible pueden reducir nuestra productividad . Cassandra está optimizada para grabar, y antes de grabar, no piensa mucho. Cualquier operación con datos existentes también es un registro. Es decir, después de eliminar el exceso, simplemente generamos aún más registros, y solo una parte de ellos estará marcada con lápidas.
Tiempos de espera en la inserción. Cassandra es hermosa en la grabación, pero a veces la transmisión entrante puede ser muy desconcertante para ella . Esto sucede cuando la aplicación comienza a rodear varios registros que no se pueden insertar por ningún motivo. Y necesitaremos un DBA bastante real, que seguirá a gc.log, el sistema y los registros de depuración para consultas lentas, métricas para la compactación pendiente.
Varios centros de datos en un clúster. ¿Dónde leer y dónde escribir?
¿Quizás dividido en lectura y escritura? Y si es así, ¿debería haber un DC para escribir o leer más cerca de la aplicación? ¿Y no obtendremos un cerebro dividido real si elegimos el nivel de consistencia incorrectamente? Muchas preguntas, muchas configuraciones inexploradas, características que realmente quiero torcer.
Como decidimos
Que el nodo no desperdició, deshabilitó SWAP . Y ahora con una falta de memoria, el nodo debe acostarse y no producir grandes pausas gc.
Entonces, ya no esperamos lógica en la base de datos. Los desarrolladores de aplicaciones vuelven a aprender y comienzan a asegurarse activamente en su propio código. Perfecta separación clara del almacenamiento y procesamiento de datos.
Compramos soporte de DataStax. Kassandra en caja ya ha dejado de desarrollarse (la última confirmación en febrero de 2018). Al mismo tiempo, Datastax ofrece un excelente servicio y una gran cantidad de soluciones de CI modificadas y adaptadas a las existentes.
También quiero señalar que Kassandra no es muy conveniente para consultar muestras. Por supuesto, CQL es un gran paso hacia los usuarios (en comparación con Trift). Pero si tiene departamentos completos, acostumbrados a tales combinaciones convenientes, filtrado gratuito por cualquier campo y opciones de optimización de consultas, y estos departamentos están trabajando para cerrar reclamos y accidentes, entonces la decisión sobre Kassandra le parece ser enemiga y estúpida. Y comenzamos a abordar la cuestión de cómo nuestros colegas pueden hacer muestras.
Consideramos dos opciones: en la primera opción, escribimos llamadas no solo en C *, sino también en la base de datos de archivo de Oracle. Solo, a diferencia de C *, las llamadas se almacenan en esta base de datos solo durante el mes actual (profundidad de almacenamiento de llamadas suficiente para casos de recertificación). Aquí vimos de inmediato el siguiente problema: si escribe sincrónicamente, perdemos todas las ventajas de C * asociado con la inserción rápida, si es asíncrono, no hay garantía de que todas las llamadas necesarias generalmente lleguen a Oracle. Hubo un plus, pero uno grande: para la explotación, el mismo desarrollador PL / SQL familiar permanece, es decir, prácticamente implementamos el patrón "Fachada". Una opción alternativa. Implementamos un mecanismo que descarga las llamadas de C *, extrae algunos datos para enriquecerlos de las tablas correspondientes en Oracle, une las muestras recibidas y nos da el resultado, que luego usamos de alguna manera (retrotrae, repite, analiza, admira). Contras: el proceso es bastante de varios pasos y, además, no hay una interfaz para el personal operativo.
Como resultado, todavía nos decidimos por la segunda opción. Apache Spark se usó para muestras de diferentes latas. La esencia del mecanismo se redujo al código Java, que, utilizando las claves especificadas (suscriptor, claves de sección de tiempo de llamada), extrae datos de C *, así como los datos necesarios para el enriquecimiento de cualquier otra base de datos. Luego los une en su memoria y muestra el resultado en la tabla resultante. Se dibujó un bozal sobre la chispa y resultó ser bastante útil.

Al resolver un problema con la actualización de datos, una prueba de promoción nuevamente examinó varias soluciones. Tanto la transferencia a través de Sstloader como la opción de dividir el clúster en la zona de prueba en dos partes, cada una de las cuales ingresa alternativamente en el mismo clúster que la promoción, por lo que se alimenta de ella. Al actualizar la prueba, se planeó cambiar sus lugares: la parte que funcionó en la prueba se borra y se ingresa en el baile de graduación, y la otra comienza a trabajar con los datos por separado. Sin embargo, pensando de nuevo, evaluamos más racionalmente los datos que deberían transferirse, y nos dimos cuenta de que las llamadas en sí mismas son una entidad inconsistente para las pruebas, generadas rápidamente si es necesario, y es el conjunto de datos de promoción que no vale la pena transferir a la prueba. Hay varios objetos de almacenamiento que vale la pena mover, pero esto es literalmente un par de tablas, y no muy pesadas. Por lo tanto , Spark volvió a ayudarnos como una solución, con la ayuda de la cual escribimos y comenzamos a usar activamente la transferencia de datos entre tablas de scripts de prom-test.
Nuestra política de implementación actual nos permite trabajar sin sobornos. Antes del baile de graduación, hay una transferencia obligatoria a la prueba, donde el error no es tan costoso. En caso de falla, siempre puede soltar el espacio de casos y rodar todo el esquema desde el principio.
Para garantizar la disponibilidad continua de Cassandra, necesita dba y no solo eso. Todos los que trabajan con la aplicación deben entender dónde y cómo observar la situación actual y cómo diagnosticar los problemas de manera oportuna. Para hacer esto, utilizamos activamente DataStax OpsCenter (administración y monitoreo de cargas de trabajo), métricas del sistema Cassandra Driver (número de tiempos de espera para escribir en C *, número de tiempos de espera para leer desde C *, latencia máxima, etc.), monitoreo el trabajo de la aplicación en sí, trabajando con Kassandra.
Cuando pensamos en la pregunta anterior, nos dimos cuenta de dónde podría estar nuestro principal riesgo. Estos son formularios de visualización de datos que generan datos de varias solicitudes de almacenamiento que son independientes entre sí. De esta manera podemos obtener información bastante inconsistente. Pero este problema sería tan relevante si trabajáramos con un solo centro de datos. Entonces, lo más razonable aquí es, por supuesto, hacer la función por lotes de leer datos en una aplicación de terceros, lo que garantizará que los datos se reciban en un solo período de tiempo. En cuanto a la separación de lectura y escritura en términos de rendimiento, aquí nos detuvimos por el riesgo de que, con alguna pérdida de conexión entre los DC, podamos obtener dos grupos completamente inconsistentes.
Como resultado, en este momento nos detuvimos en el nivel de consistencia para el registro EACH_QUORUM, para leer - LOCAL_QUORUM
Breves impresiones y conclusiones
Con el fin de evaluar la solución resultante en términos de soporte operativo y las perspectivas de un mayor desarrollo, decidimos pensar en dónde más se podría aplicar dicho desarrollo.
Si está en movimiento, entonces obtenga datos para programas como "Pague cuando sea conveniente" (cargue información C *, calcule usando scripts de Spark), contabilice los reclamos con la agregación por direcciones, almacene roles y calcule los derechos de acceso de los usuarios usando la matriz de roles.
Como puede ver, el repertorio es amplio y variado. Y si elegimos el grupo de seguidores / oponentes de NoSQL, nos uniremos a los seguidores, ya que obtuvimos nuestras ventajas, y exactamente donde esperábamos.
Incluso la opción de Cassandra lista para usar permite el escalado horizontal en tiempo real, resolviendo sin problemas el problema de aumentar los datos en el sistema. Logramos poner en un circuito separado un mecanismo muy cargado para calcular los agregados para las llamadas, así como para separar el esquema y la lógica de la aplicación, eliminando la práctica viciosa de escribir trabajos y objetos personalizados en la base de datos. Tuvimos la oportunidad de elegir y configurar, para acelerar, en qué DC calcularemos y en qué registros de datos, nos aseguramos de las caídas de los nodos individuales y de todo el DC.
Aplicando nuestra arquitectura a nuevos proyectos, y ya teniendo algo de experiencia, me gustaría tener en cuenta de inmediato los matices descritos anteriormente, y evitar algunos errores, suavizar algunas esquinas afiladas que no pudieron evitarse inicialmente.
Por ejemplo, realice un seguimiento de las actualizaciones de Cassandra a tiempo , porque ya se conocían y corrigieron bastantes problemas que recibimos.
No coloque la base de datos y Spark en los mismos nodos (ni los divida estrictamente por la cantidad de uso de recursos aceptable), ya que Spark puede comer más de lo esperado OP, y rápidamente obtendremos el problema número 1 de nuestra lista.
Bombear la competencia de monitoreo y operación en la etapa de prueba del proyecto. Inicialmente, tenga en cuenta el máximo de todos los consumidores potenciales de nuestra solución , porque la estructura de la base de datos dependerá en última instancia de esto.
Gire el circuito resultante varias veces para una posible optimización. Seleccione qué campos se pueden serializar. Comprender qué tablas adicionales podemos hacer para tener en cuenta de la manera más correcta y óptima, y luego devolver la información requerida a pedido (por ejemplo, suponiendo que podamos almacenar los mismos datos en diferentes tablas, teniendo en cuenta diferentes desgloses según diferentes criterios, puede ahorrar significativamente tiempo de procesador para solicitudes de lectura).
Es una buena idea montar inmediatamente TTL y limpiar datos obsoletos.
Al descargar datos de Cassandra, la lógica de la aplicación debe funcionar de acuerdo con el principio FETCH, de modo que no todas las líneas se carguen en la memoria a la vez, sino que se seleccionen en lotes.
Antes de transferir el proyecto a la solución descrita, es aconsejable verificar la tolerancia a fallas del sistema realizando una serie de pruebas de choque , como la pérdida de datos en un centro de datos, la restauración de datos dañados durante un cierto período y la reducción de la red entre centros de datos. Dichas pruebas no solo le permitirán evaluar los pros y los contras de la arquitectura propuesta, sino que también brindarán una buena práctica de calentamiento a los ingenieros que las llevan a cabo, y la habilidad adquirida estará lejos de ser superflua si las fallas del sistema se reproducen en el baile de graduación.
Si trabajamos con información crítica (como datos de facturación, cálculo de la deuda del suscriptor), también debe prestar atención a las herramientas que reducirán los riesgos que surgen debido a las características del DBMS. Por ejemplo, use la utilidad nodeync (Datastax), después de haber desarrollado una estrategia óptima para su uso, de modo que, en aras de la coherencia, no forme una carga excesiva en Cassandra y la use solo para ciertas tablas en un período determinado.
Bueno, después de seis meses de vida, ¿con Cassandra? En general, no hay problemas sin resolver. Accidentes graves y pérdida de datos, tampoco lo permitimos. Sí, tuve que pensar en compensar algunos problemas no resueltos anteriormente, pero al final no eclipsó nuestra solución arquitectónica. Si quiere y no tiene miedo de probar algo nuevo, y al mismo tiempo no quiere decepcionarse, prepárese para el hecho de que nada sucede de forma gratuita. Hay más que entender, profundizar en la documentación y recopilar su rastrillo individual que en la antigua solución heredada y ninguna teoría le dirá de antemano exactamente qué rastrillo lo está esperando.