Zappa, Chalice и друзья: запускаем код без серверов с помощью AWS Lambda

Zappa, Chalice и друзья: запускаем код без серверов с помощью AWS Lambda

Михаил Новиков (fstrk.io) @ MoscowPython Meetup 69

"Технологии Serverless несколько лет, и с каждым годом её популярность растет. Для высоконагруженных систем это простой способ бесконечного масштабирования, а для простых сайд-проектов - это отличная возможность бесплатного хостинга. Принцип в том, что вы деплоите не вебсервер, а функции, и платите только за время выполнения этих функций (обычно это миллисекунды).
В докладе мы рассмотрим, как устроены эти функции, какие есть инструменты для их создания - и зачем это обычному питонисту. Также мы увидим, как деплоить уже готовые приложения на Django и Flask в serverless-режиме."

Видео: http://www.moscowpython.ru/meetup/69/zappa-chalice-and-friends/

53b0434aded1fb944ec3037c382158c1?s=128

Moscow Python Meetup

October 30, 2019
Tweet

Transcript

  1. Zappa, Chalice и друзья Запускаем код без серверов с помощью

    AWS Lambda Михаил Новиков Founder & Dev Lead, fstrk.io "Пишу чатботов на джанго" (c) @nooovikov 1
  2. План @nooovikov 2

  3. План 1. Что такое Serverless / FaaS ? @nooovikov 2

  4. План 1. Что такое Serverless / FaaS ? 2. Где

    это может пригодиться? @nooovikov 2
  5. План 1. Что такое Serverless / FaaS ? 2. Где

    это может пригодиться? 3. Как деплоить Serverless @nooovikov 2
  6. План 1. Что такое Serverless / FaaS ? 2. Где

    это может пригодиться? 3. Как деплоить Serverless 4. Ограничения и хаки @nooovikov 2
  7. План 1. Что такое Serverless / FaaS ? 2. Где

    это может пригодиться? 3. Как деплоить Serverless 4. Ограничения и хаки 5. Цены @nooovikov 2
  8. План 1. Что такое Serverless / FaaS ? 2. Где

    это может пригодиться? 3. Как деплоить Serverless 4. Ограничения и хаки 5. Цены 6. Отечественный Serverless @nooovikov 2
  9. 1. Что такое Serverless / FaaS ? @nooovikov 3

  10. 1. Что такое Serverless / FaaS ? • Деплоим код,

    не разворачивая сервера @nooovikov 3
  11. 1. Что такое Serverless / FaaS ? • Деплоим код,

    не разворачивая сервера • Платим только за время обработки запросов @nooovikov 3
  12. 1. Что такое Serverless / FaaS ? • Деплоим код,

    не разворачивая сервера • Платим только за время обработки запросов • Не храним стейт в функции (внешняя БД, внешний кэш, авторизация и пр.) @nooovikov 3
  13. 1. Что такое Serverless / FaaS ? • Деплоим код,

    не разворачивая сервера • Платим только за время обработки запросов • Не храним стейт в функции (внешняя БД, внешний кэш, авторизация и пр.) • Не занимаемся (кое-чем) с инфраструктурой @nooovikov 3
  14. @nooovikov 4

  15. Простое объяснение @nooovikov 5

  16. Философское объяснение Код - "клей" для инфраструктуры @nooovikov 6

  17. 2. Где это может пригодится? @nooovikov 7

  18. 2. Где это может пригодится? • ⚡ Вебхуки, интеграции @nooovikov

    7
  19. 2. Где это может пригодится? • ⚡ Вебхуки, интеграции •

    " API & микросервисы @nooovikov 7
  20. 2. Где это может пригодится? • ⚡ Вебхуки, интеграции •

    " API & микросервисы • # ETL-пайплайны @nooovikov 7
  21. 2. Где это может пригодится? • ⚡ Вебхуки, интеграции •

    " API & микросервисы • # ETL-пайплайны • $ Бэкенды для ботов, SPA @nooovikov 7
  22. 2. Где это может пригодится? • ⚡ Вебхуки, интеграции •

    " API & микросервисы • # ETL-пайплайны • $ Бэкенды для ботов, SPA • % IoT @nooovikov 7
  23. Где это нельзя использовать @nooovikov 8

  24. Где это нельзя использовать • ⏳ Длинные задачи (напр. получасовой

    парсинг сайта) @nooovikov 8
  25. Где это нельзя использовать • ⏳ Длинные задачи (напр. получасовой

    парсинг сайта) • " Приложения с большим кол-вом зависимостей @nooovikov 8
  26. Где это нельзя использовать • ⏳ Длинные задачи (напр. получасовой

    парсинг сайта) • " Приложения с большим кол-вом зависимостей • # Приложения, хранящие в себе стейт @nooovikov 8
  27. 3. Как деплоить @nooovikov 9

  28. 3.1. Деплой в интерфейсе AWS @nooovikov 10

  29. Шаг 1. Пишем функцию @nooovikov 11

  30. Шаг 2. Добавляем API к функции @nooovikov 12

  31. Это удобно? @nooovikov 13

  32. Это удобно? • Нет! @nooovikov 13

  33. Это удобно? • Нет! • Нет контроля версий @nooovikov 13

  34. Это удобно? • Нет! • Нет контроля версий • Сложности

    с зависимостями (в Lambda нельзя сделать pip install) @nooovikov 13
  35. Это удобно? • Нет! • Нет контроля версий • Сложности

    с зависимостями (в Lambda нельзя сделать pip install) • Код либо пишешь в редакторе, либо загружаешь в ZIP-архиве @nooovikov 14
  36. Нам нужен фреймворк: @nooovikov 15

  37. Нам нужен фреймворк: • Чтобы работать в своем уютном IDE

    @nooovikov 15
  38. Нам нужен фреймворк: • Чтобы работать в своем уютном IDE

    • Чтобы zip-архивы сами загружались в облако @nooovikov 15
  39. Нам нужен фреймворк: • Чтобы работать в своем уютном IDE

    • Чтобы zip-архивы сами загружались в облако • Чтобы решались проблемы с зависимостями @nooovikov 15
  40. 3.2. Деплой с Serverless Framework https://serverless.com/ @nooovikov 16

  41. Serverless Framework • YML конфиг позволяет не касаться админки AWS

    • Деплой одной командой • Можно настроить ВСЁ • Много доков и примеров • Есть энтерпрайз версия! ! @nooovikov 17
  42. Но... Он написан на Node.js. ! npm install serverless npm

    install serverless-python-requirements @nooovikov 18
  43. 3.3. Деплой с Chalice • Написан на питоне • Поддерживается

    амазоном: https://github.com/aws/chalice • Еще проще деплоить • Очень амбициозное название @nooovikov 19
  44. @nooovikov 20

  45. Странности Chalice API похож на Flask, но не совсем: @app.route('/')

    def view(): # request нужно доставать из аппы request = app.current_request # получение JSON-пейлоада body = request.json_body # получение GET-параметров params = requst.query_params @nooovikov 21
  46. Странности Chalice Заявляет, что поддерживает вебсокеты, но это не заводится:

    app = Chalice(app_name="echo-server") app.websocket_api.session = Session() app.experimental_feature_flags.update(['WEBSOCKETS']) @app.on_ws_message() def message(event): app.websocket_api.send( connection_id=event.connection_id, message=event.body ) @nooovikov 22
  47. Странности Chalice • Требует все файлы класть в папку chalicelib

    • Некоторые зависимости пакует автоматически, а некоторые - нет • chalice logs выдает ВСЕ логи за всю историю проекта (осторожно) @nooovikov 23
  48. 3.4. Деплой с Zappa github.com/Miserlou/Zappa @nooovikov 24

  49. Zappa • Пишем просто Flask-приложение • Все настройки в zappa_settings.json

    • Можно мигрировать текущие проекты без доработок (ну почти) @nooovikov 25
  50. @nooovikov 26

  51. Сравнение фреймворков • SLS Framework: • Меньше всего магии, больше

    всего гибкости • Сложно для начинающих • Chalice: • Питоничные обертки над амазоновскими командами. АПИ со странностями • Подходит для простых проектов • Zappa: • Максимум магии, но проще всего использовать • Просто Flask @nooovikov 27
  52. 4. Ограничения и хаки @nooovikov 28

  53. 4.1. Время выполнения • Синхронные функции: до 30 сек •

    Асинхронные функции: до 15 мин Как быть? @nooovikov 29
  54. 4.1. Время выполнения • Синхронные функции: до 30 сек •

    Асинхронные функции: до 15 мин Как быть? Amazon SQS + 2 функции @nooovikov 30
  55. @nooovikov 31

  56. 4.2. Регулярный запуск тасков • Невозможно запустить Celery • Нет

    cron Как быть? @nooovikov 32
  57. 4.2. Регулярный запуск тасков • Невозможно запустить Celery • Нет

    cron Как быть? Cloudwatch Events! @nooovikov 33
  58. @nooovikov 34

  59. 4.3. Зависимости • На AWS Lambda нельзя сделать pip install

    • Все засимости пакуем в zip и загружаем вместе с приложением • Поэтому на Lambda сложно запускать проекты с тяжелыми зависимостями ./requests 376K ./psycopg2 564K ./PIL 11M ./numpy 23M ./pandas 65M Как быть? @nooovikov 35
  60. Lambda Layers @nooovikov 36

  61. 4.4. Хранение стейта @nooovikov 37

  62. 4.4. Хранение стейта • Можем запустить на Амазоне инстанс Postgres.

    @nooovikov 37
  63. 4.4. Хранение стейта • Можем запустить на Амазоне инстанс Postgres.

    • Но это покупка сервера (от $15/мес) @nooovikov 37
  64. 4.4. Хранение стейта • Можем запустить на Амазоне инстанс Postgres.

    • Но это покупка сервера (от $15/мес) • Можем подключиться к AWS DynamoDB (от $0/мес) @nooovikov 37
  65. 4.4. Хранение стейта • Можем запустить на Амазоне инстанс Postgres.

    • Но это покупка сервера (от $15/мес) • Можем подключиться к AWS DynamoDB (от $0/мес) • Но это проприетарная NoSQL база со своими особенностями @nooovikov 37
  66. 4.4. Хранение стейта • Можем запустить на Амазоне инстанс Postgres.

    • Но это покупка сервера (от $15/мес) • Можем подключиться к AWS DynamoDB (от $0/мес) • Но это проприетарная NoSQL база со своими особенностями • [хак] Можем хранить SQLite базу на S3 @nooovikov 37
  67. 4.4. Хранение стейта • Можем запустить на Амазоне инстанс Postgres.

    • Но это покупка сервера (от $15/мес) • Можем подключиться к AWS DynamoDB (от $0/мес) • Но это проприетарная NoSQL база со своими особенностями • [хак] Можем хранить SQLite базу на S3 • Это Serverless SQL! @nooovikov 37
  68. Serverless SQLite @nooovikov 38

  69. Serverless SQLite @nooovikov 39

  70. Serverless SQLite @nooovikov 40

  71. Serverless SQLite @nooovikov 41

  72. Serverless SQLite @nooovikov 42

  73. Serverless SQLite Ограничения @nooovikov 43

  74. Serverless SQLite Ограничения • Несколько параллельных SELECT - ок @nooovikov

    43
  75. Serverless SQLite Ограничения • Несколько параллельных SELECT - ок •

    Несколько параллельных UDPATE/DELETE - не ок. Закоммитится только последний. @nooovikov 43
  76. Serverless SQLite Ограничения • Несколько параллельных SELECT - ок •

    Несколько параллельных UDPATE/DELETE - не ок. Закоммитится только последний. • Подходит для сервисов с редкой записью, частым чтением @nooovikov 43
  77. Пример Serverless SQL https://clc.to/board Serverless мессаджборд Zappa + Flask +

    S3sqlite registry.register("s3sqlite", "dialect", "S3SQLiteDialect") engine = create_engine('s3sqlite:///messageboard.sqlite') class Board(Base): id = Column(Integer, primary_key=True) name = Column(String) class Post(Base): id = Column(Integer, primary_key=True) content = Column(String) created_at = Column(DateTime) board = relationship("Board", back_populates="posts") @nooovikov 44
  78. 5. Цены @nooovikov 45

  79. 5. Цены Service Units Price per unit Free quota Lambda

    GB-second $0.00001667 ✅ 1 million requests $0.2 ✅ GB of data out $0.09 ✅ RDS Postgres Instance hour $0.021(μ)/$0.164(L) ✅ (1y) GB-month of storage $0.133 ✅ DynamoDB 1 million PUT $1.25 1 million GET $0.25 GB-month of storage $0.25 ✅ @nooovikov 46
  80. 6. Отечественный Серверлесс Mom, can we have serverless? No, we

    have serverless at home. Serverless at home: Yandex Cloud Functions @nooovikov 47
  81. Yandex Cloud Functions • Синтаксис идентичен AWS Lambda (ну почти)

    @nooovikov 48
  82. Yandex Cloud Functions • Синтаксис идентичен AWS Lambda (ну почти)

    • Можно работать как в интерфейсе, так и в консоли (установить Yandex CLI) @nooovikov 49
  83. Yandex Cloud Functions • Синтаксис идентичен AWS Lambda (ну почти)

    • Можно работать как в интерфейсе, так и в консоли (установить Yandex CLI) • Не нужно создавать HTTP-ручку - она подключается сама @nooovikov 50
  84. Yandex Cloud Functions • Синтаксис идентичен AWS Lambda (ну почти)

    • Можно работать как в интерфейсе, так и в консоли (установить Yandex CLI) • Не нужно создавать HTTP-ручку - она подключается сама • Workflow идентичен: пишем код, пакуем зависимости, загружаем zip- архив @nooovikov 51
  85. А фреймворки? @nooovikov 52

  86. ./deploy.sh mkdir ./package && cp * ./package pip install -r

    requirements.txt -t ./package zip ./package.zip ./package/* yc serverless function version create \ --function-name=hello \ --runtime python37 \ --entrypoint handler.handler \ --memory 128m \ --execution-timeout 5s \ --source-path ./package.zip rm ./package.zip && rm -rf ./package @nooovikov 53
  87. ./deploy.sh mkdir ./package && cp * ./package pip install -r

    requirements.txt -t ./package zip ./package.zip ./package/* yc serverless function version create \ --function-name=hello \ --runtime python37 \ --entrypoint handler.handler \ --memory 128m \ --execution-timeout 5s \ --source-path ./package.zip rm ./package.zip && rm -rf ./package @nooovikov 54
  88. ./deploy.sh mkdir ./package && cp * ./package pip install -r

    requirements.txt -t ./package zip ./package.zip ./package/* yc serverless function version create \ --function-name=hello \ --runtime python37 \ --entrypoint handler.handler \ --memory 128m \ --execution-timeout 5s \ --source-path ./package.zip rm ./package.zip && rm -rf ./package @nooovikov 55
  89. ./deploy.sh mkdir ./package && cp * ./package pip install -r

    requirements.txt -t ./package zip ./package.zip ./package/* yc serverless function version create \ --function-name=hello \ --runtime python37 \ --entrypoint handler.handler \ --memory 128m \ --execution-timeout 5s \ --source-path ./package.zip rm ./package.zip && rm -rf ./package @nooovikov 56
  90. ./deploy.sh mkdir ./package && cp * ./package pip install -r

    requirements.txt -t ./package zip ./package.zip ./package/* yc serverless function version create \ --function-name=hello \ --runtime python37 \ --entrypoint handler.handler \ --memory 128m \ --execution-timeout 5s \ --source-path ./package.zip rm ./package.zip && rm -rf ./package @nooovikov 57
  91. ./deploy.sh mkdir ./package && cp * ./package pip install -r

    requirements.txt -t ./package zip ./package.zip ./package/* yc serverless function version create \ --function-name=hello \ --runtime python37 \ --entrypoint handler.handler \ --memory 128m \ --execution-timeout 5s \ --source-path ./package.zip rm ./package.zip && rm -rf ./package @nooovikov 58
  92. Как сделать проще? @nooovikov 59

  93. Yandex + Zappa = ... @nooovikov 60

  94. Yandex + Zappa = Yappa @nooovikov 61

  95. Yappa pip install yappa @nooovikov 62

  96. Yappa github.com/kurtgn/yappa @nooovikov 63

  97. Yappa github.com/kurtgn/yappa • Выполняет под капотом упаковку и деплой @nooovikov

    63
  98. Yappa github.com/kurtgn/yappa • Выполняет под капотом упаковку и деплой •

    Упрощает типовые задачи (yappa logs, yappa status, ...) @nooovikov 63
  99. Yappa github.com/kurtgn/yappa • Выполняет под капотом упаковку и деплой •

    Упрощает типовые задачи (yappa logs, yappa status, ...) • Можно писать навыки для Алисы @nooovikov 63
  100. YCF vs. AWS Lambda @nooovikov 64

  101. YCF vs. AWS Lambda • Сделаем функцию, которая считает тяжелый

    цикл @nooovikov 64
  102. YCF vs. AWS Lambda • Сделаем функцию, которая считает тяжелый

    цикл • Задеплоим на 512MB AWS Lambda @nooovikov 64
  103. YCF vs. AWS Lambda • Сделаем функцию, которая считает тяжелый

    цикл • Задеплоим на 512MB AWS Lambda • Задеплоим на 512MB Yandex Cloud Functions @nooovikov 64
  104. YCF vs. AWS Lambda • Сделаем функцию, которая считает тяжелый

    цикл • Задеплоим на 512MB AWS Lambda • Задеплоим на 512MB Yandex Cloud Functions • Купим сервера в двух ДЦ, дадим нагрузку @nooovikov 64
  105. YCF vs. AWS Lambda • Сделаем функцию, которая считает тяжелый

    цикл • Задеплоим на 512MB AWS Lambda • Задеплоим на 512MB Yandex Cloud Functions • Купим сервера в двух ДЦ, дадим нагрузку • Пусть победит сильнейший! @nooovikov 64
  106. @nooovikov 65

  107. @nooovikov 66

  108. YCF vs. AWS Lambda Результаты • Amazon - тяжелый и

    прожорливый (но 250 RPS) • Yandex - легкий и экономный (но 20 RPS) @nooovikov 67
  109. 8. Итог Особенности Serverless @nooovikov 68

  110. 8. Итог Особенности Serverless • ! Код - это "клей",

    а не основа @nooovikov 68
  111. 8. Итог Особенности Serverless • ! Код - это "клей",

    а не основа • " Процессы эфемерны, в них нельзя хранить стейт @nooovikov 68
  112. 8. Итог Особенности Serverless • ! Код - это "клей",

    а не основа • " Процессы эфемерны, в них нельзя хранить стейт • # Платим только за время выполнения @nooovikov 68
  113. 8. Итог Особенности Serverless • ! Код - это "клей",

    а не основа • " Процессы эфемерны, в них нельзя хранить стейт • # Платим только за время выполнения • $ Автоматическое горизонтальное масштабирование @nooovikov 68
  114. 8. Итог Особенности Serverless • ! Код - это "клей",

    а не основа • " Процессы эфемерны, в них нельзя хранить стейт • # Платим только за время выполнения • $ Автоматическое горизонтальное масштабирование • % Странный workflow, но фреймворки упрощают жизнь @nooovikov 68
  115. 8. Итог Применение Serverless @nooovikov 69

  116. 8. Итог Применение Serverless • ✅ REST API бэкенды, боты

    @nooovikov 69
  117. 8. Итог Применение Serverless • ✅ REST API бэкенды, боты

    • ✅ ETL пайплайны @nooovikov 69
  118. 8. Итог Применение Serverless • ✅ REST API бэкенды, боты

    • ✅ ETL пайплайны • ✅ Бесплатный хостинг для пет проджектов @nooovikov 69
  119. 8. Итог Применение Serverless • ✅ REST API бэкенды, боты

    • ✅ ETL пайплайны • ✅ Бесплатный хостинг для пет проджектов • ❌ Не подходит для долгих тасков @nooovikov 69
  120. 8. Итог Применение Serverless • ✅ REST API бэкенды, боты

    • ✅ ETL пайплайны • ✅ Бесплатный хостинг для пет проджектов • ❌ Не подходит для долгих тасков • ❌ Не подходит для энтерпрайза @nooovikov 69
  121. 8. Итог Применение Serverless • ✅ REST API бэкенды, боты

    • ✅ ETL пайплайны • ✅ Бесплатный хостинг для пет проджектов • ❌ Не подходит для долгих тасков • ❌ Не подходит для энтерпрайза • ❌ Не подходит для постоянного хайлоада @nooovikov 69
  122. Спасибо! Mikhail Novikov Founder & Dev Lead, Fasttrack • github.com/kurtgn/yappa

    • clc.to/board • t.me/pyshorts @nooovikov 70