Тому що ми робили хмарний FaaS всередині Kubernetes та перемагали у Тінькофф-хакатоні

Тому що ми робили хмарний FaaS всередині Kubernetes та перемагали у Тінькофф-хакатоні
Починаючи з минулого року, у нас в компанії почали організовувати хакатони. Перше таке змагання пройшло дуже успішно, про нього ми писали в статті. Другий хакатон пройшов у лютому 2019 року і був не менш успішним. Про цілі проведення останнього не так давно писав організатор.

Учасникам поставили досить цікаве завдання із повною свободою у виборі стеку технологій для її реалізації. Було необхідно реалізувати платформу прийняття рішень для зручного деплою функцій скорингу клієнтів, які могли б працювати на швидкому потоці заявок, витримували великі навантаження, а сама система легко масштабувалася.

Завдання є нетривіальним і може бути вирішене безліччю способів, у чому ми переконалися на демонстрації фінальних презентацій проектів учасників. На хакатоні було 6 команд по 5 осіб, всі учасники мали гарні проекти, але наша платформа виявилася найбільш конкурентоспроможною. У нас вийшов дуже цікавий проект, про який я хотів би розповісти у цій статті.

Наше рішення – платформа на основі Serverless архітектури всередині Kubernetes, яка скорочує час виведення нових фіч на продакшн. Вона дозволяє аналітикам писати код у зручному для них середовищі та розгортати його в прод без участі інженерів та розробників.

Що таке скоринг

У Tinkoff.ru, як і в багатьох сучасних компаніях, є скоринг клієнтів. Скоринг - це система оцінки клієнтів, в основі якої закладені статистичні методи аналізу даних.

Наприклад, клієнт звертається до нас із проханням видати йому кредит, або відкрити у нас рахунок ІП. Якщо ми плануємо видати йому кредит, потрібно оцінити його платоспроможність, і якщо рахунок ІП, потрібно бути впевненими що клієнт нічого очікувати проводити шахрайські операції.

В основі прийняття таких рішень лежать математичні моделі, що аналізують дані самої заявки, так і дані нашого сховища. Крім скорингу, схожі статистичні методи також можуть використовуватися в роботі сервісу формування індивідуальних рекомендацій щодо нових продуктів для наших клієнтів.

Метод такої оцінки може приймати різні дані на вході. А колись ми можемо додати на вхід новий параметр, який за результатами аналізу на історичних даних підвищить конверсію використання сервісу.

У нас зберігається безліч даних про взаємини з клієнтами, і обсяг цієї інформації постійно зростає. Щоб скоринг працював, для обробки даних потрібні ще й правила (або математичні моделі), що дозволяють швидко прийняти рішення кому заявку схвалити, кому відмовити, а кому ще кілька продуктів запропонувати, оцінивши його потенційну зацікавленість.

Для поставленого завдання ми вже використовуємо спеціалізовану систему прийняття рішень IBM WebSphere ILOG JRules BRMS, яка, на основі заданих аналітиками, технологами та розробниками правил вирішує, схвалити той чи інший банківський продукт клієнту або відмовити.

На ринку існує багато готових рішень як скорингових моделей, так і самих систем прийняття рішень. Одну з таких систем ми використовуємо у компанії. Але бізнес зростає, диверсифікується, збільшується як кількість клієнтів, і кількість запропонованих продуктів, а з цим з'являються ідеї як можна поліпшити існуючий процес прийняття рішень. Напевно, у людей, які працюють з існуючою системою, є безліч ідей як зробити простіше, краще, зручніше, але іноді бувають корисні ідеї з боку. З метою збирання здорових ідей був організований Новий Хакатон.

Поставлена ​​задача

Хакатон проводився 23 лютого. Учасникам було запропоновано бойове завдання: розробити систему прийняття рішень, яка мала відповідати низці умов.

Нам розповіли, як функціонує існуюча система і які складності виникають при її експлуатації, а також які бізнес-мети має переслідувати платформа, що розробляється. Система повинна мати швидкий time-to-market розроблюваних правил, щоб робочий код аналітиків потрапляв у продакшн якнайшвидше. А для вхідного потоку заявок час ухвалення рішення має прагнути до мінімуму. Також система, що розробляється, повинна мати можливості cross-sell, щоб давати клієнту можливість придбати інші продукти компанії у разі їх схвалення з нашого боку та потенційної зацікавленості з боку клієнта.

Зрозуміло, що за одну ніч неможливо написати ready-to-release проект, який неодмінно піде в продакшн, та й усю систему цілком охопити досить складно, тому нам було запропоновано реалізувати хоча б її частину. Було встановлено низку вимог, яким має задовольняти прототип. Можна було спробувати як охопити всі вимоги повністю, так і детально опрацювати окремі розділи платформи, що розробляється.

Що стосується технологій, то тут усім учасникам було надано цілковиту свободу вибору. Можна було використовувати будь-які концепції та технології: Data streaming, machine learning, event sourcing, big data та інші.

наше рішення

Провівши невеликий мозковий штурм ми вирішили, що для виконання поставленого завдання ідеально підійде рішення FaaS.

Для цього рішення необхідно було знайти відповідний Serverless фреймворк для реалізації правил системи прийняття рішень, що розробляється. Так як у Тінькофф для управління інфраструктурою активно використовується Kubernetes, ми розглянули кілька готових рішень на його основі, детальніше про нього я розповім далі.

Для пошуку найбільш ефективного рішення ми глянули на продукт, що розробляється очима її користувачів. Основні користувачі нашої системи – аналітики, які займаються розробкою правил. Правила необхідно деплоїти на сервер, або як у нашому випадку, розгортати в хмарі для подальшого прийняття рішень. З позиції аналітика робочий процес виглядає так:

  1. Аналітик пише скрипт, правило, або ML модель, ґрунтуючись на даних із сховища. В рамках хакатону ми вирішили використати Mongodb, але вибір системи зберігання даних тут не є важливим.
  2. Після тестування розроблених правил на історичних даних, аналітик заливає свій код до адмінки.
  3. З метою забезпечення версіонування весь код потраплятиме до Git-репозиторії.
  4. Через адмінку можна буде розгорнути код у хмарі як окремий функціональний модуль Serverless.

Вихідні дані від клієнтів повинні проходити через спеціалізований Enrichment-Сервіс, призначений для збагачення початкового запиту даними зі сховища. Важливо було реалізувати цей сервіс таким чином, щоб забезпечувалася робота з єдиним сховищем (з якого аналітик бере дані при розробці правил), для підтримки єдиної структури даних.

Ще до хакатону ми визначилися із Serverless-фреймворком, який використовуватимемо. На сьогоднішній день на ринку досить багато технологій, що реалізують даний підхід. Найбільш популярними рішеннями в рамках архітектури Kubernetes є Fission, Open FaaS і Kubeless. Є навіть непогана стаття з їх описом та порівняльним аналізом.

Зваживши всі плюси та мінуси ми зупинили свій вибір на Ділення. Цей Serverless-фреймворк досить простий в управлінні та задовольняє вимогам поставленого завдання.

Для роботи з Fission необхідно розуміти дві основні концепції: function та environment. Функцією (function) є шматок коду написаний однією з мов для якого є Fission-оточення (environment). Список реалізованих у рамках цього фреймворку оточень включає Python, JS, Go, JVM і безліч інших популярних мов і технологій.

Також Fission здатний виконувати функції, розбиті на кілька файлів, попередньо запаковані в архів. Робота Fission у кластері Kubernetes забезпечується спеціалізованими подами, керування якими бере на себе сам фреймворк. Для здійснення взаємодії з подами кластера, на кожну функцію необхідно призначити свій роут і в який можна передавати GET параметри або request body у разі запиту POST.

В результаті ми планували отримати рішення, що дозволяє аналітикам розгортати розроблені скрипти правил без участі інженерів та розробників. Описаний підхід також позбавляє розробників необхідності переписувати код аналітиків іншою мовою. Наприклад, для поточної системи прийняття рішень, що використовується нами, доводиться писати правила на вузькопрофільних технологіях і мовах, область застосування яких вкрай обмежена, а також присутня сильна залежність від сервера додатків, оскільки всі проекти правил банку деплояться на єдиному оточенні. Внаслідок чого для деплою нових правил необхідно виконувати реліз усієї системи.

У запропонованому нами рішенні відсутня необхідність релізу правил, код легко розгортається по одному натисканні кнопки. Також управління інфраструктурою в Kubernetes дозволяє не думати про навантаження і масштабування, подібні проблеми вирішуються «з коробки». А використання єдиного сховища даних позбавляє необхідності зіставлення real-time даних з історичними, що полегшує роботу аналітика.

Що в нас вийшло

Так як на хакатон ми прийшли з уже готовим рішенням (у наших фантазіях), нам залишилося тільки перетворити всі наші думки на рядки коду.

Запорука успіху на будь-якому хакатоні це підготовка та добре складений план. Тому, насамперед ми визначилися з яких модулів складатиметься архітектура нашої системи та які технології ми будемо використовувати.

Архітектура нашого проекту була такою:

Тому що ми робили хмарний FaaS всередині Kubernetes та перемагали у Тінькофф-хакатоні
На цій схемі вказані дві точки входу, аналітик (основний користувач нашої системи) та клієнт.

Процес роботи побудовано так. Аналітик розробляє функцію-правило та функцію збагачення даними для своєї моделі, зберігає свій код у Git-репозиторій, і через програму адміністратора розгортає свою модель у хмарі. Розглянемо як розгорнута функція викликатиметься і прийматиме рішення щодо вхідних заявок від клієнтів:

  1. Клієнт заповнюючи форму на сайті, надсилає свій запит на контролер. На вхід системи приходить заявка, за якою необхідно ухвалити рішення, і записується в БД у своєму первісному вигляді.
  2. Далі сирий запит відправляється на збагачення, якщо це потреба. Доповнити початковий запит можна як від зовнішніх сервісів так і зі сховища. Отриманий збагачений запит також зберігається у БД.
  3. Запускається функція аналітика, яка приймає на вхід збагачений запит і віддає рішення, яке також записується в сховище.

Як сховище в нашій системі ми вирішили використовувати MongoDB у вигляді докуменоринтованого зберігання даних у вигляді JSON документів, оскільки сервіси збагачення, включаючи вихідний запит, агрегували всі дані через REST-контролери.

Отже, на реалізацію платформи у нас була доба. Ми досить вдало розподілили ролі, кожен член команди мав свою зону відповідальності у нашому проекті:

  1. Фронтенд-адмінки для роботи аналітика, через яку він міг завантажувати правила із системи контролю версіонування написаних скриптів, вибирати варіанти збагачення вхідних даних та правити скрипти правил онлайн.
  2. Бекенд-адмінки, що включає REST API для фронту та інтеграцію з VCS.
  3. Налаштування інфраструктури в Google Cloud та розробка сервісу збагачення вихідних даних.
  4. Модуль інтеграції програми адмінки з Serverless-фреймворком для подальшого деплою правил.
  5. Скрипти правил для тестування працездатності всієї системи та агрегація аналітики за вхідними заявками (ухваленими рішеннями) для фінальної демонстрації.

Почнемо по порядку.

Фронтенд у нас був написаний на Angular 7 із використанням банківського UI Kit. Фінальний варіант адмінки виглядав так:

Тому що ми робили хмарний FaaS всередині Kubernetes та перемагали у Тінькофф-хакатоні
Оскільки часу було небагато, ми постаралися реалізувати лише ключовий функціонал. Для деплою функції в Kubernetes кластер необхідно було вибрати подію (сервіс, для якого необхідно розгорнути правило в хмарі) та код код функції, що реалізує логіку прийняття рішення. По кожному розгортанню правила для обраного сервісу ми писали лог цієї події. В адмінці можна було бачити логі всіх подій.

Весь код функцій зберігався у віддаленому Git-репозиторії, який також потрібно було задавати в адмінці. Для версіонування коду всі функції зберігалися у різних гілках репозиторію. В адмінці також передбачена можливість внесення коригувань у написані скрипти, щоб перед депломом функції в продакшн можна було не тільки перевірити написаний код, а й внести необхідні редагування.

Тому що ми робили хмарний FaaS всередині Kubernetes та перемагали у Тінькофф-хакатоні
Крім функцій правил ми також реалізували можливість поетапного збагачення вихідних даних за допомогою Enrichment-функцій, код яких також був скрипти, в яких можна було ходити в сховище даних, викликати сторонні сервіси і виконати попередні розрахунки. Для демонстрації нашого рішення ми розраховували знак зодіаку клієнта, який залишив заявку, та визначали його мобільного оператора, використовуючи сторонній REST сервіс.

Бекенд платформи був написаний на Java і реалізований як Spring Boot додаток. Для зберігання даних адмінки ми спочатку планували використовувати Postgres, але, в рамках хакатона, вирішили обмежитися простим H2, з метою економії часу. На беку було реалізовано інтеграцію з Bitbucket, для версіонування функцій збагачення запитів і скриптів правил. Для інтеграції з віддаленими Git репозиторіями використовувалась бібліотека JGit, яка є свого роду обгорткою над командами CLI, що дозволяє виконувати будь-які git інструкції, використовуючи зручний програмний інтерфейс. Так у нас було два окремі репозиторії, для функцій збагачення та правил, а всі скрипти розкладені за директоріями. Через UI можна було вибрати останній коміт скрипта довільної гілки репозиторію. При внесенні правок код через адмінку у віддалених репозиторіях створювалися коммиты зміненого коду.

Для реалізації нашої ідеї нам була потрібна підходяща інфраструктура. Ми вирішили розгорнути наш кластер Kubernetes у хмарі. Наш вибір зупинився на Google Cloud Platform. Serverless-фреймворк Fission був встановлений у кластері Kubernetes, який ми розгорнули у Gcloud. Спочатку сервіс збагачення вихідних даних був реалізований окремим Java-додатком, оберненим в Pod всередині кластера k8s. Але після попередньої демонстрації нашого проекту в середині хакатону, нам порекомендували зробити Enrichment сервіс гнучкішим, щоб надати можливість вибирати, як збагачувати сирі дані заявок, що входять. І нам нічого не залишалося, крім зробити сервіс збагачення також Serverless.

Для роботи з Fission ми використовували Fission CLI, яку потрібно встановлювати поверх Kubernetes CLI. Деплой функцій в k8s кластер досить простий, необхідно лише призначити для функції внутрішній роут і ingress для вхідного трафіку, якщо необхідний доступ поза кластером. Розгортання однієї функції зазвичай займає трохи більше 10 секунд.

Фінальний показ проекту та підбиття підсумків

Для демонстрації роботи нашої системи ми розмістили на віддаленому сервері просту форму, на якій можна подати заявку на один із продуктів банку. Для запиту необхідно було ввести свої ініціали, дату народження та номер телефону.

Дані з клієнтської форми йшли на контролер, який паралельно надсилав заявки на всі доступні правила, попередньо збагативши дані згідно з заданими умовами, і зберігши їх у загальне сховище. Усього у нас було розгорнуто три функції, що приймають рішення за вхідними заявками та 4 сервіси збагачення даними. Після надсилання заявки клієнт отримував наше рішення:

Тому що ми робили хмарний FaaS всередині Kubernetes та перемагали у Тінькофф-хакатоні
Клієнт, крім відмови або схвалення, також отримував список інших продуктів, запити на які ми надсилали паралельно. Так ми продемонстрували можливість cross-sale у нашій платформі.

Усього було доступно 3 вигадані продукти банку:

  • Кредит.
  • іграшка
  • Іпотека.

На кожну послугу під час демонстрації ми розгорнули підготовлені функції та скрипти збагачення.

Для кожного правила був потрібний свій набір вхідних даних. Так для схвалення іпотеки ми обчислювали знак зодіаку клієнта і пов'язували це з логікою місячного календаря. Для схвалення іграшки ми перевіряли, що клієнт досяг повноліття, а для видачі кредиту ми надсилали запит до зовнішнього відкритого сервісу визначення стільникового оператора, і щодо нього приймали рішення.

Ми спробували зробити нашу демонстрацію цікавою та інтерактивною, кожен присутній міг зайти на нашу форму та перевірити доступність йому наших вигаданих послуг. А в самому кінці презентації ми продемонстрували аналітику заявок, що надійшли, де було показано, скільки людей скористалися нашим сервісом, кількість схвалень, відмов.

Для збору аналітики в режимі он-лайн ми додатково розгорнули BI інструмент з відкритим вихідним кодом Метабаза і прикрутили його до нашого сховища. Metabase дозволяє будувати екрани з аналітикою за даними, що цікавлять нас, необхідно лише прописати підключення до БД, вибрати таблиці (у нашому випадку колекції даних, так як ми використовували MongoDB), і вказати поля, що цікавлять нас.

В результаті у нас вийшов непоганий прототип платформи прийняття рішень, і на демонстрації кожен слухач міг перевірити власноруч її працездатність. Цікаве рішення, готовий прототип та успішна демонстрація дозволили нам перемогти, незважаючи на сильну конкуренцію в особі інших команд. Впевнений, що за проектом кожної команди також можна написати цікаву статтю.

Джерело: habr.com

Додати коментар або відгук