Desde el año pasado, comenzaron a organizarse hackatones en nuestra empresa. La primera competencia de este tipo tuvo mucho éxito, escribimos al respecto en el
artículo . El segundo hackathon se realizó en febrero de 2019 y no fue menos exitoso. El organizador
escribió recientemente sobre los objetivos de este último.
Los participantes recibieron una tarea bastante interesante con total libertad para elegir una pila de tecnología para su implementación. Era necesario implementar una plataforma de decisión para un despliegue conveniente de funciones de puntuación del cliente que pudieran funcionar en un flujo rápido de aplicaciones, soportar cargas pesadas, y el sistema en sí mismo se escalaba fácilmente.
La tarea no es trivial y puede resolverse de muchas maneras, como vimos en la demostración de las presentaciones finales de los proyectos de los participantes. Había 6 equipos de 5 personas en el hackathon, todos los participantes tenían buenos proyectos, pero nuestra plataforma resultó ser la más competitiva. Tenemos un proyecto muy interesante, del que me gustaría hablar en este artículo.
Nuestra solución es una plataforma basada en la arquitectura sin servidor dentro de Kubernetes, que reduce el tiempo necesario para llevar nuevas características a producción. Permite a los analistas escribir código en un entorno conveniente para ellos y desplegarlo en la producción sin la participación de ingenieros y desarrolladores.
¿Qué es la puntuación?
Tinkoff.ru, como muchas empresas modernas, tiene puntaje de clientes. Scoring es un sistema de evaluación de clientes basado en métodos estadísticos de análisis de datos.
Por ejemplo, un cliente nos pide que le demos un préstamo o que abramos una cuenta IP con nosotros. Si planeamos otorgarle un préstamo, debe evaluar su solvencia, y si la cuenta es de capital privado, debe asegurarse de que el cliente no realizará transacciones fraudulentas.
Estas decisiones se basan en modelos matemáticos que analizan tanto los datos de la aplicación en sí como los datos de nuestro almacenamiento. Además de la puntuación, también se pueden utilizar métodos estadísticos similares en el trabajo del servicio para generar recomendaciones individuales sobre nuevos productos para nuestros clientes.
El método de tal evaluación puede recibir una variedad de datos de entrada. Y en algún momento, podemos agregar un nuevo parámetro a la entrada que, de acuerdo con el análisis de los datos históricos, aumentará la conversión del uso del servicio.
Almacenamos muchos datos sobre las relaciones con los clientes, y el volumen de esta información está en constante crecimiento. Para que la puntuación funcione, el procesamiento de datos también requiere reglas (o modelos matemáticos) que le permitan decidir rápidamente quién aprueba la solicitud, a quién rechazar y a quién ofrecer un par de productos para evaluar su interés potencial.
Para esta tarea, ya utilizamos el sistema especializado de toma de decisiones
IBM WebSphere ILOG JRules BRMS , que, según las reglas establecidas por analistas, tecnólogos y desarrolladores, decide si aprobar un producto bancario en particular para un cliente o rechazarlo.
Existen muchas soluciones preparadas en el mercado, tanto modelos de puntuación como sistemas de toma de decisiones. Utilizamos uno de estos sistemas en nuestra empresa. Pero el negocio está creciendo, diversificándose, tanto la cantidad de clientes como la cantidad de productos ofrecidos están aumentando, y junto con esto, están surgiendo ideas sobre cómo mejorar el proceso de toma de decisiones existente. Seguramente las personas que trabajan con el sistema existente tienen muchas ideas sobre cómo hacerlo más simple, mejor y más conveniente, pero a veces las ideas del exterior son útiles. Para recolectar ideas sonoras, se organizó un Nuevo Hackathon.
Tarea
El hackathon se realizó el 23 de febrero. A los participantes se les ofreció una misión de combate: desarrollar un sistema de toma de decisiones, que debía cumplir una serie de condiciones.
Nos dijeron cómo funciona el sistema existente y qué dificultades surgen durante su funcionamiento, así como qué objetivos comerciales debe perseguir la plataforma en desarrollo. El sistema debe tener un rápido tiempo de comercialización de reglas en desarrollo para que el código de trabajo de los analistas entre en producción lo más rápido posible. Y para el flujo entrante de aplicaciones, el tiempo de toma de decisiones debe tender al mínimo. Además, el sistema desarrollado debería poder realizar ventas cruzadas para dar al cliente la oportunidad de comprar otros productos de la compañía si son aprobados por nosotros e intereses potenciales por parte del cliente.
Está claro que en una noche es imposible escribir un proyecto listo para lanzar que ciertamente entrará en producción, y todo el sistema es bastante difícil de cubrir, por lo que se nos pidió que implementemos al menos parte de él. Se establecieron una serie de requisitos que el prototipo debe cumplir. Se podría tratar de cubrir todos los requisitos en su conjunto y elaborar en detalle secciones individuales de la plataforma desarrollada.
En cuanto a la tecnología, a todos los participantes se les dio total libertad de elección. Era posible utilizar cualquier concepto y tecnología: transmisión de datos, aprendizaje automático, abastecimiento de eventos, big data y otros.
Nuestra decision
Después de una pequeña sesión de lluvia de ideas, decidimos que la solución FaaS sería ideal para la tarea.
Para esta solución, era necesario encontrar un marco sin servidor adecuado para implementar las reglas del sistema de toma de decisiones desarrollado. Dado que Kubernetes se usa activamente en la gestión de infraestructura en Tinkoff, examinamos varias soluciones preparadas basadas en él, hablaré más sobre ello más adelante.
Para encontrar la solución más efectiva, analizamos el producto desarrollado a través de los ojos de sus usuarios. Los principales usuarios de nuestro sistema son analistas involucrados en el desarrollo de reglas. Las reglas deben implementarse en el servidor o, como en nuestro caso, implementarse en la nube para la posterior toma de decisiones. Desde la perspectiva del analista, el flujo de trabajo es el siguiente:
- El analista escribe un script, una regla o un modelo de ML basado en los datos del repositorio. Como parte del hackathon, decidimos usar Mongodb, pero la elección del sistema de almacenamiento no es importante aquí.
- Después de probar las reglas desarrolladas en los datos históricos, el analista vierte su código en el panel de administración.
- Para garantizar el control de versiones, todo el código irá a los repositorios de Git.
- A través del panel de administración, será posible implementar el código en la nube como un módulo funcional sin servidor separado.
Los datos de origen de los clientes deben pasar por un servicio de enriquecimiento especializado, diseñado para enriquecer la solicitud inicial con datos del repositorio. Era importante implementar este servicio de tal manera que funcionara con un único repositorio (del cual el analista toma datos cuando desarrolla las reglas) para mantener una estructura de datos unificada.
Incluso antes del hackathon, decidimos sobre el marco sin servidor que usaremos. Existen bastantes tecnologías en el mercado que implementan este enfoque. Las soluciones de arquitectura de Kubernetes más populares son Fission, Open FaaS y Kubeless. Incluso hay un
buen artículo con su descripción y análisis comparativo .
Después de sopesar todos los pros y los contras, optamos por la
fisión . Este marco sin servidor es bastante fácil de administrar y cumple con los requisitos de la tarea.
Para trabajar con Fission, debe comprender dos conceptos básicos: función y entorno. La función (función) es un fragmento de código escrito en uno de los idiomas para los que existe un entorno de fisión (entorno).
La lista de entornos implementados en el marco de este marco incluye Python, JS, Go, JVM y muchos otros lenguajes y tecnologías populares.
Fission también puede realizar funciones, divididas en varios archivos, preempaquetadas en el archivo. La operación de fisión en el clúster de Kubernetes es proporcionada por módulos especializados, que son administrados por el propio marco. Para interactuar con los pods de clúster, a cada función se le debe asignar una ruta, y a la cual puede pasar los parámetros GET o el cuerpo de la solicitud en caso de una solicitud POST.
Como resultado, planeamos obtener una solución que permita a los analistas implementar scripts de reglas desarrollados sin la participación de ingenieros y desarrolladores. El enfoque descrito también elimina la necesidad de que los desarrolladores reescriban el código de los analistas en otro idioma. Por ejemplo, para el sistema de toma de decisiones actual que utilizamos, tenemos que escribir reglas en tecnologías e idiomas de perfil estrecho, cuyo alcance es extremadamente limitado, y también hay una fuerte dependencia del servidor de aplicaciones, ya que todas las reglas bancarias preliminares se implementan en un solo entorno. Como resultado, para el despliegue de nuevas reglas, es necesario liberar todo el sistema.
En la solución que propusimos, no es necesario liberar las reglas, el código se implementa fácilmente con solo hacer clic en un botón. Además, la gestión de la infraestructura en Kubernetes le permite no pensar en la carga y el escalado, tales problemas se resuelven de inmediato. Y el uso de un único almacén de datos elimina la necesidad de comparar datos en tiempo real con datos históricos, lo que simplifica el trabajo del analista.
Que conseguimos
Desde que llegamos al hackathon con una solución preparada (en nuestras fantasías), solo necesitamos convertir todos nuestros pensamientos en líneas de código.
La clave del éxito en cualquier hackathon es la preparación y un plan bien hecho. Por lo tanto, en primer lugar, decidimos en qué módulos consistirá nuestra arquitectura de sistema y qué tecnologías utilizaremos.
La arquitectura de nuestro proyecto fue la siguiente:
Este diagrama muestra dos puntos de entrada, un analista (el usuario principal de nuestro sistema) y un cliente.
El proceso de trabajo está estructurado así. El analista desarrolla la función de regla y la función de enriquecimiento de datos para su modelo, guarda su código en el repositorio de Git e implementa su modelo en la nube a través de la aplicación del administrador. Considere cómo se llamará a la función ampliada y tome decisiones sobre las solicitudes entrantes de los clientes:
- El cliente que completa un formulario en el sitio envía su solicitud al controlador. Una aplicación llega a la entrada del sistema, según la cual se debe tomar una decisión, y se registra en la base de datos en su forma original.
- A continuación, se envía una solicitud sin procesar para enriquecimiento, si es necesario. Puede complementar la solicitud inicial con datos tanto de servicios externos como del repositorio. La consulta enriquecida recibida también se almacena en la base de datos.
- Se inicia la función analítica, que recibe una solicitud enriquecida en la entrada y da una decisión, que también se registra en el repositorio.
Como almacenamiento en nuestro sistema, decidimos usar MongoDB en vista del almacenamiento documentado de datos en forma de documentos JSON, ya que los servicios de enriquecimiento, incluida la solicitud inicial, agregaron todos los datos a través de controladores REST.
Entonces, tuvimos un día para implementar la plataforma. Distribuimos con bastante éxito los roles, cada miembro del equipo tenía su propia área de responsabilidad en nuestro proyecto:
- El panel de administración frontend para el trabajo del analista a través del cual podría descargar las reglas del sistema de control de versiones de los scripts escritos, elegir las opciones para enriquecer los datos de entrada y editar los scripts de reglas en línea.
- Un panel de administración de backend que incluye una API REST para la integración frontal y VCS.
- Configuración de infraestructura en Google Cloud y desarrollo de un servicio de enriquecimiento de datos de origen.
- El módulo para integrar la aplicación de administración con el marco Serverless para el despliegue posterior de las reglas.
- Scripts de reglas para probar el estado de todo el sistema y la agregación de análisis para aplicaciones entrantes (decisiones tomadas) para la demostración final.
Comencemos en orden.
Nuestro frontend fue escrito en Angular 7 usando el Kit de UI bancario. La versión final del panel de administración fue la siguiente:
Como no había mucho tiempo, intentamos implementar solo la funcionalidad clave. Para implementar una función en el clúster de Kubernetes, fue necesario seleccionar un evento (un servicio para el que necesita implementar una regla en la nube) y codificar el código de la función que implementa la lógica de decisión. Para cada implementación de la regla para el servicio seleccionado, escribimos un registro de este evento. En el panel de administración, puede ver los registros de todos los eventos.
Todo el código de función se almacenó en un repositorio remoto de Git, que también tuvo que configurarse en el panel de administración. Para versionar el código, todas las funciones se almacenaron en diferentes ramas del repositorio. El panel de administración también proporciona la capacidad de realizar ajustes en los scripts escritos para que antes de implementar una función en producción, no solo pueda verificar el código escrito, sino también realizar los cambios necesarios.
Además de las funciones de las reglas, también nos dimos cuenta de la posibilidad de enriquecer paso a paso los datos de origen utilizando las funciones de Enriquecimiento, cuyo código también consistía en scripts en los que podía ir al almacén de datos, llamar a servicios de terceros y realizar cálculos preliminares. Para demostrar nuestra solución, calculamos el signo zodiacal del cliente que dejó la aplicación y determinamos su operador móvil utilizando un servicio REST de terceros.
El backend de la plataforma se escribió en Java y se implementó como una aplicación Spring Boot. Para almacenar los datos de administración, originalmente planeamos usar Postgres, pero, como parte del hackathon, decidimos limitarnos a un simple H2 para ahorrar tiempo. En el back-end, se implementó la integración con Bitbucket para versionar las funciones de enriquecimiento de consultas y los scripts de reglas. Para integrarse con repositorios Git remotos, se
utilizó la biblioteca JGit , que es una especie de envoltorio sobre los comandos de la CLI que le permite ejecutar cualquier instrucción git utilizando una interfaz de programa conveniente. Así que teníamos dos repositorios separados, para funciones y reglas de enriquecimiento, y todos los scripts están organizados en directorios. A través de la interfaz de usuario, fue posible seleccionar el último script de confirmación de una rama de repositorio arbitrario. Al realizar cambios en el código a través del panel de administración, se crearon confirmaciones del código modificado en los repositorios remotos.
Para implementar nuestra idea, necesitábamos una infraestructura adecuada. Decidimos implementar nuestro clúster de Kubernetes en la nube. Nuestra elección es Google Cloud Platform. El marco sin servidor Fless se instaló en el clúster de Kubernetes, que implementamos en Gcloud. Inicialmente, el servicio de enriquecimiento de datos de origen fue implementado por una aplicación Java separada envuelta en un Pod dentro de un clúster k8s. Pero después de una demostración preliminar de nuestro proyecto en el medio del hackathon, se nos recomendó hacer que el servicio de Enriquecimiento sea más flexible para brindar la oportunidad de elegir cómo enriquecer los datos sin procesar de las aplicaciones entrantes. Y no tuvimos más remedio que hacer que el servicio de enriquecimiento también fuera sin servidor.
Para trabajar con Fission, utilizamos la CLI de Fission, que debe instalarse encima de la CLI de Kubernetes. La implementación de funciones en el clúster k8s es bastante simple, solo necesita asignar una ruta interna e ingreso para que la función permita el tráfico entrante si se requiere acceso fuera del clúster. La implementación de una función generalmente no toma más de 10 segundos.
Show final del proyecto y resumen
Para demostrar el funcionamiento de nuestro sistema, colocamos en un servidor remoto un formulario simple en el que puede solicitar uno de los productos del banco. Para la solicitud, tenía que ingresar sus iniciales, fecha de nacimiento y número de teléfono.
Los datos del formulario del cliente fueron al controlador, que envió simultáneamente aplicaciones para todas las reglas disponibles, enriqueciendo previamente los datos de acuerdo con las condiciones dadas y almacenándolos en un almacenamiento común. En total, hemos implementado tres funciones de toma de decisiones para aplicaciones entrantes y 4 servicios de enriquecimiento de datos. Después de enviar la aplicación, el cliente recibió nuestra solución:
Además del rechazo o aprobación, el cliente también recibió una lista de otros productos para los cuales enviamos solicitudes en paralelo. Así que demostramos la posibilidad de venta cruzada en nuestra plataforma.
En total, 3 productos bancarios inventados estaban disponibles:
Durante cada demostración, implementamos funciones preparadas y scripts de enriquecimiento para cada servicio.
Cada regla necesitaba su propio conjunto de datos de entrada. Entonces, para aprobar la hipoteca, calculamos el signo zodiacal del cliente y lo asociamos con la lógica del calendario lunar. Para aprobar el juguete, verificamos que el cliente fuera mayor de edad y, para emitir un préstamo, enviamos una solicitud a un servicio abierto externo para determinar el operador móvil y tomamos una decisión al respecto.
Intentamos que nuestra demostración fuera interesante e interactiva, todos los presentes podían ingresar a nuestro formulario y verificar la disponibilidad de nuestros servicios imaginarios para él. , , , , .
BI
Metabase . Metabase , , ( , MongoDB), .
, . , , . , .