Иногда бессерверный, всегда масштабируемый

Мы здесь, в Легити, немного от того, что вы называете индивидуалистами. Когда они идут направо, мы идем налево. Когда они говорят, что мы не можем, мы говорим, что уже сделали. Когда они говорят, что все в стране, в которой вы находитесь, говорят по-португальски, мы говорим по-английски. (Хорошо, может быть, это только я.)

Поэтому, когда «они» говорят «ZOMG, БЕССЕРВНЫЙ ИЛИ БЮСТ !!!!!», мы говорим «Ну, не всегда».

В этой статье я расскажу, когда и почему это так. Но сначала давайте перейдем к делу и поместим вверху цитаты, оптимизированной для SEO:

В Legiti мы используем системы оркестровки контейнеров, такие как Kubernetes, для обслуживания наших моделей машинного обучения в производственной среде, которые предлагают такую ​​же автоматическую масштабируемость и отказоустойчивость, как вариант бессерверного хостинга, без ограничений зависимостей, налагаемых Lambdas.

Вот почему мы это делаем

Помимо того, что мы проводим время в Легити в качестве радикальных и задиристых индивидуалистов, мы также строим радикальные и задиристые модели, чтобы остановить мошенничество с кредитными картами в Интернете. Наши модели защиты от мошенничества в значительной степени полагаются на scikit-learn, который зависит от numpy и scipy, которые сами по себе требуют библиотек C и Fortran (?!?), Что заставляет загружать этих ребят в AWS Lambda (давайте не будем притворяться, что люди говоря о сопоставимых бессерверных альтернативах) немного похоже на стрижку газона ножницами: вы можете это сделать, но это заноза в заднице, а газонокосилки действительно существуют!

Послушайте, не поймите меня неправильно: я большой фанат бессерверных приложений, и мы используем их для многих наших сервисов. Серверы - это головная боль. Управление автомасштабированием, модернизация с нулевым временем простоя и расходы на инфраструктуру занимают относительно низкое место в моем списке вещей, которые я хочу сделать.

Тем не менее, у нас есть модели для развертывания, и вы читали какие-нибудь из этих статей о запуске scikit-learn на AWS Lambda? Они кажутся вырезанными из той же ткани, что и стремление Джорджа Мэллори к восхождению на Эверест:

На более практическом уровне ограничения AWS Lambda ограничивают размер пакета развертывания вашей функции до 50 МБ. Размер наших зависимостей для оценки мошенничества составляет 248 Мб, заархивирован. Есть способы обойти это, и мы могли бы быть более экономными в выборе пакетов, чтобы уменьшить размер нашего пакета, но опять же… почему?

Если отбросить легкомыслие, на то есть веские причины. Легкая масштабируемость, чрезвычайно конкурентоспособные цены и незначительное обслуживание серверов или его полное отсутствие, и это лишь некоторые из них. Но преимущества бессерверного развертывания сервисов обходятся дорого, особенно в случае с Legiti. Чтобы обеспечить максимальную согласованность результатов между записными книжками наших специалистов по данным и нашими производственными ответами, мы объединяем функции, используемые для расчета функций и оценки модели, в пакет Python, который развертывается и запускается против реальных транзакций клиентов в режиме реального времени.

Другими словами, отсутствует перевод кода вычисления признаков, используемого для обучения модели, в производственный эквивалент; мы запускаем одни и те же функции, один и тот же код.

Обеспечение паритета между сценариями разработки и производства - непростая задача в мире науки о данных, и использование библиотек и инструментов, доступных нашим специалистам по данным и инженерам машинного обучения, только усложняет задачу. Мы не хотим размещать искусственные интерфейсы, ориентированные на лямбда-выражения, такие как слои, в наши процедуры обработки данных. С другой стороны, мы небольшая команда с большим количеством микросервисов, чем инженеров, и ни у кого нет времени следить за временем безотказной работы отдельного сервера.

Короче говоря, нам нужно лучшее из обоих миров: простая масштабируемость и 100% время безотказной работы, но нулевые ограничения на набор инструментов, доступных для наших специалистов по данным. Решение? Кубернетес.

Хорошо, это немного сложнее - мы используем Kubernetes для запуска нескольких контейнеров, которые переводят наши процессы обогащения функций и оценки модели в Dockerized Flask-процесс, который обслуживается через uWSGI и, в свою очередь, NGINX, и все они размещены за балансировщиком нагрузки приложения и API Gateway, но согласитесь, звучало круче, когда я просто сказал Kubernetes.

Настройка развертывания Kubernetes, конечно же, не обходится без накладных расходов. Под капотом AWS Lambda по сути то же самое, но чрезвычайно абстрактный и упрощенный конечный интерфейс (буквально просто определение функции) в значительной степени привел к его широкому и быстрому внедрению. Как только вы погрузитесь в Kubernetes, вы быстро окажетесь в забытой богом стране бессмысленных терминов, таких как кубелец, поды и гипервизоры. Легко соскользнуть с рельсов, и трудно найти, где даже рельсы.

В большинстве случаев я бы рекомендовал по возможности придерживаться бессерверной архитектуры, но в Legiti у нас было два условия, которые подтолкнули нас к развертыванию нашей службы оценки транзакций в Kubernetes:

  • Бессерверная версия нашей службы оценки транзакций создала бы нежелательные препятствия на пути к достижению паритета разработки и производства для производительности нашей модели мошенничества.
  • Наш парень из DevOps - зверь с Kubernetes

По общему признанию, я ввел некоторую ложную дихотомию между Kubernetes и Lambda для развертывания сервисов. На самом деле вам не нужно специально использовать Kubernetes. Существует ряд сопоставимых управляемых или полууправляемых сервисов оркестровки контейнеров (например, Fargate или ECS на AWS, или GKE для тех, кто занимается GCS). Нам нравится гибкость и настраиваемость, которые дает нам наш управляемый Helm кластер Kubernetes, а журналы и метрики по-прежнему хорошо интегрируются с остальными нашими сервисами AWS, такими как CloudWatch.

Так какой в ​​этом смысл? Когда дело доходит до внедрения ваших моделей машинного обучения в производство, вам не нужно выбирать между использованием библиотек, моделей и функций, которые выполняют свою работу, и автоматическим масштабированием, обновлением без простоев и автоматическим масштабированием:

Можете съесть K8s и тоже.

(Хорошо, мне очень жаль)