Arquitectura y capacidades de Tarantool Data Grid

Arquitectura y capacidades de Tarantool Data Grid

En 2017, ganamos un concurso para desarrollar el núcleo transaccional del negocio de inversión de Alfa-Bank y comenzamos a trabajar (en HighLoad++ 2018 con un informe sobre el núcleo del negocio de inversión realizado Vladimir Drynkin, jefe del núcleo transaccional del negocio de inversiones de Alfa Bank). Se suponía que este sistema agregaría datos de transacciones de diferentes fuentes en varios formatos, unificaría los datos, los almacenaría y proporcionaría acceso a ellos.

Durante el proceso de desarrollo, el sistema evolucionó y adquirió funcionalidad, y en algún momento nos dimos cuenta de que estábamos cristalizando algo mucho más que un simple software de aplicación creado para resolver una gama estrictamente definida de tareas: lo logramos. sistema para construir aplicaciones distribuidas con almacenamiento persistente. La experiencia adquirida formó la base de un nuevo producto: Cuadrícula de datos de Tarantool (TDG).

Quiero hablar sobre la arquitectura TDG y las soluciones a las que llegamos durante el proceso de desarrollo, presentarles la funcionalidad principal y mostrarles cómo nuestro producto puede convertirse en la base para crear soluciones completas.

Arquitectónicamente, dividimos el sistema en roles, cada uno de los cuales es responsable de resolver una determinada gama de problemas. Una única instancia de aplicación en ejecución implementa uno o más tipos de roles. Puede haber varios roles del mismo tipo en un clúster:

Arquitectura y capacidades de Tarantool Data Grid

Conector

Connector es responsable de la comunicación con el mundo exterior; su tarea es aceptar la solicitud, analizarla y, si tiene éxito, enviar los datos para su procesamiento al procesador de entrada. Admitimos formatos HTTP, SOAP, Kafka, FIX. La arquitectura le permite simplemente agregar soporte para nuevos formatos, y pronto habrá soporte para IBM MQ. Si falla el análisis de la solicitud, el conector devolverá un error; de lo contrario, responderá que la solicitud fue procesada exitosamente, incluso si ocurrió un error durante su procesamiento posterior. Esto se hizo específicamente para trabajar con sistemas que no saben cómo repetir solicitudes o, por el contrario, lo hacen con demasiada perseverancia. Para no perder datos, se utiliza una cola de reparación: el objeto primero ingresa en ella y solo después de un procesamiento exitoso se elimina de ella. El administrador puede recibir alertas sobre los objetos que quedan en la cola de reparación y, después de eliminar un error de software o una falla de hardware, volver a intentarlo.

Procesador de entrada

El procesador de entrada clasifica los datos recibidos según sus características y llama a los procesadores apropiados. Los controladores son código Lua que se ejecuta en un entorno limitado, por lo que no pueden afectar el funcionamiento del sistema. En esta etapa, los datos se pueden reducir a la forma requerida y, si es necesario, se puede iniciar una cantidad arbitraria de tareas que puedan implementar la lógica necesaria. Por ejemplo, en el producto MDM (Master Data Management) integrado en Tarantool Data Grid, al agregar un nuevo usuario, para no ralentizar el procesamiento de la solicitud, iniciamos la creación de un disco dorado como una tarea separada. El sandbox admite solicitudes de lectura, cambio y adición de datos, le permite realizar alguna función en todos los roles del tipo de almacenamiento y agregación del resultado (mapa/reducir).

Los controladores se pueden describir en archivos:

sum.lua

local x, y = unpack(...)
return x + y

Y luego, declarado en la configuración:

functions:
  sum: { __file: sum.lua }

¿Por qué Lua? Lua es un lenguaje muy simple. Según nuestra experiencia, un par de horas después de conocerlo, la gente comienza a escribir código que resuelve su problema. Y no se trata sólo de desarrolladores profesionales, sino, por ejemplo, de analistas. Además, gracias al compilador jit, Lua se ejecuta muy rápidamente.

Almacenamiento

El almacenamiento almacena datos persistentes. Antes de guardar, los datos se validan con el esquema de datos. Para describir el circuito utilizamos un formato extendido. apache avro. Un ejemplo:

{
    "name": "User",
    "type": "record",
    "logicalType": "Aggregate",
    "fields": [ 
        { "name": "id", "type": "string"}, 
        {"name": "first_name", "type": "string"}, 
        {"name": "last_name", "type": "string"} 
    ], 
    "indexes": ["id"] 
}

Según esta descripción, se genera automáticamente DDL (lenguaje de definición de datos) para Tarantula DBMS y GraphQL esquema de acceso a los datos.

Se admite la replicación de datos asíncrona (hay planes para agregar una síncrona).

Procesador de salida

En ocasiones es necesario avisar a los consumidores externos sobre la llegada de nuevos datos, para ello existe el rol de Procesador de salida. Después de guardar los datos, se pueden pasar al controlador apropiado (por ejemplo, para llevarlos al formulario requerido por el consumidor) y luego pasar al conector para su envío. Aquí también se utiliza una cola de reparación: si nadie aceptó el objeto, el administrador puede volver a intentarlo más tarde.

Escalado

Los roles de conector, procesador de entrada y procesador de salida no tienen estado, lo que nos permite escalar el sistema horizontalmente simplemente agregando nuevas instancias de aplicación con el tipo de rol deseado habilitado. El almacenamiento se utiliza para el escalado horizontal. enfoque para organizar un clúster utilizando depósitos virtuales. Después de agregar un nuevo servidor, algunos de los depósitos de los servidores antiguos se mueven al nuevo servidor en segundo plano; Esto sucede de forma transparente para los usuarios y no afecta el funcionamiento de todo el sistema.

Propiedades de datos

Los objetos pueden ser muy grandes y contener otros objetos. Garantizamos la atomicidad de la adición y actualización de datos almacenando un objeto con todas las dependencias en un depósito virtual. Esto evita que el objeto se "distribuya" entre varios servidores físicos.

Se admite el control de versiones: cada actualización de un objeto crea una nueva versión, y siempre podemos tomar un intervalo de tiempo y ver cómo era el mundo en ese momento. Para los datos que no necesitan un historial largo, podemos limitar el número de versiones o incluso almacenar solo una (la más reciente), es decir, esencialmente deshabilitar el control de versiones para un tipo determinado. También puedes limitar el historial por tiempo: por ejemplo, eliminar todos los objetos de un determinado tipo que tengan más de 1 año. También se admite el archivado: podemos descargar objetos anteriores al tiempo especificado, liberando espacio en el clúster.

Tareas

Entre las características interesantes, cabe destacar la posibilidad de ejecutar tareas según una programación, a petición del usuario o mediante programación desde el sandbox:

Arquitectura y capacidades de Tarantool Data Grid

Aquí vemos otro rol: el corredor. Esta función no tiene estado y se pueden agregar instancias de aplicaciones adicionales con esta función al clúster según sea necesario. La responsabilidad del corredor es completar las tareas. Como se mencionó, es posible generar nuevas tareas desde el sandbox; se guardan en una cola de almacenamiento y luego se ejecutan en el corredor. Este tipo de tarea se llama Trabajo. También tenemos un tipo de tarea llamada Tarea: son tareas definidas por el usuario que se ejecutan según una programación (usando la sintaxis cron) o bajo demanda. Para iniciar y realizar un seguimiento de dichas tareas, contamos con un práctico administrador de tareas. Para que esta funcionalidad esté disponible, debe habilitar la función del programador; este rol tiene un estado, por lo que no escala, lo cual no es necesario; al mismo tiempo, como todos los demás roles, puede tener una réplica que comienza a funcionar si el maestro se niega repentinamente.

Logger

Otra función se llama registrador. Recopila registros de todos los miembros del clúster y proporciona una interfaz para cargarlos y verlos a través de la interfaz web.

Servicios

Cabe mencionar que el sistema facilita la creación de servicios. En el archivo de configuración, puede especificar qué solicitudes se envían a un controlador escrito por el usuario que se ejecuta en el entorno limitado. En este controlador, puede, por ejemplo, ejecutar algún tipo de consulta analítica y devolver el resultado.

El servicio se describe en el archivo de configuración:

services:
   sum:
      doc: "adds two numbers"
      function: sum
      return_type: int
      args:
         x: int
         y: int

La API GraphQL se genera automáticamente y el servicio queda disponible para llamar:

query {
   sum(x: 1, y: 2) 
}

Esto llamará al manejador. sumque devolverá el resultado:

3

Perfiles de consulta y métricas

Para comprender el funcionamiento del sistema y las solicitudes de creación de perfiles, implementamos soporte para el protocolo OpenTracing. El sistema puede enviar información bajo demanda a herramientas que soporten este protocolo, como Zipkin, lo que permitirá entender cómo se ejecutó la solicitud:

Arquitectura y capacidades de Tarantool Data Grid

Naturalmente, el sistema proporciona métricas internas que se pueden recopilar con Prometheus y visualizar con Grafana.

Desplegar

Tarantool Data Grid se puede implementar desde paquetes RPM o un archivo, utilizando una utilidad de la distribución o Ansible, también hay soporte para Kubernetes (Operador Tarantool Kubernetes).

La aplicación que implementa la lógica empresarial (configuración, controladores) se carga en el clúster Tarantool Data Grid implementado en forma de archivo a través de la interfaz de usuario o mediante un script a través de la API proporcionada por nosotros.

Aplicaciones de muestra

¿Qué aplicaciones se pueden crear usando Tarantool Data Grid? De hecho, la mayoría de las tareas empresariales están relacionadas de alguna manera con el procesamiento, almacenamiento y acceso al flujo de datos. Por lo tanto, si tiene grandes flujos de datos que deben almacenarse y acceder a ellos de forma segura, nuestro producto puede ahorrarle mucho tiempo de desarrollo y centrarse en su lógica empresarial.

Por ejemplo, queremos recopilar información sobre el mercado inmobiliario, para que en el futuro, por ejemplo, tengamos información sobre las mejores ofertas. En este caso destacaremos las siguientes tareas:

  1. Los robots que recopilan información de fuentes abiertas serán nuestras fuentes de datos. Puede resolver este problema utilizando soluciones listas para usar o escribiendo código en cualquier idioma.
  2. A continuación, Tarantool Data Grid aceptará y guardará los datos. Si el formato de datos de diferentes fuentes es diferente, entonces puede escribir código en Lua que realizará la conversión a un único formato. En la etapa de preprocesamiento también podrá, por ejemplo, filtrar ofertas duplicadas o actualizar adicionalmente en la base de datos información sobre los agentes que trabajan en el mercado.
  3. Ahora ya tiene una solución escalable en un clúster que se puede llenar con datos y realizar selecciones de datos. Luego, puede implementar una nueva funcionalidad, por ejemplo, escribir un servicio que solicitará datos y ofrecerá la oferta más ventajosa por día; esto requerirá unas pocas líneas en el archivo de configuración y un poco de código Lua.

¿Qué será lo próximo?

Nuestra prioridad es mejorar la facilidad de desarrollo utilizando Cuadrícula de datos de Tarantool. Por ejemplo, este es un IDE compatible con controladores de creación de perfiles y depuración que se ejecutan en un entorno limitado.

También prestamos gran atención a las cuestiones de seguridad. En este momento estamos en proceso de certificación por parte de FSTEC de Rusia para confirmar el alto nivel de seguridad y cumplir con los requisitos para la certificación de productos de software utilizados en sistemas de información de datos personales y sistemas de información gubernamentales.

Fuente: habr.com

Añadir un comentario