Докладчик: Никита Семенов
О докладе:
Появление asyncio стало новой вехой в истории питона. По-настоящему удобный и эффективный способ запускать асинхронный код.
В своем докладе я познакомлю слушателя с базовым синтаксисом, парадигмами и примитивами, чтобы можно было начать использовать всю мощь asyncio уже сегодня.
Для этого я возьму децентрализованные базы данных с web-интерфейсом, раскиданные по нескольким серверам, и покажу как их можно эффективно запроцесить только при помощи стандартных методов питона 3.4+ и aiohttp.
Видео: https://youtu.be/rpiHVA6vRTY
Надежный обмен данными в гетерогенной среде, между разными платформами и технологиями является одним из ключевых моментов разработки сложных систем. Во время обмена данные преобразуются в некоторый промежуточный формат совместимый между платформами. Преобразование в подобный формат и из него — крайне рутинная и подверженная ошибкам работа.
Метаописание данных неким декларативным языком с последующей автогенерацией типизированных структур облегчает жизнь разработчику. Снимает с него необходимость задумываться о промежуточном формате, о правильном порядке полей, а типизированность гарантирует выявление ошибок еще на этапе компиляции кода.
В докладе будет рассмотрено несколько подобных решений, их плюсы и минусы. Также будет рассмотрен с практической стороны наш собственный формат метаданных, используемый нами на протяжении более 5 лет.
Целевая аудитория:
Ограничений нет, но в большей степени разработчики, имеющие уже определенный опыт разработки разнородных систем или приступающие к подобной задаче.
Разработка на блокчейн Голос | Ерлан ШиндаулетовCyber Fund
Данная презентация была представлена на одном из еженедельных образовательных митапов от компании cyber•Fund.
Посмотреть полное видео с митапа можно здесь:
https://www.youtube.com/watch?v=ZkF59_XwraI
Прочитать текстовую версию выступления:
https://golos.io/@cyberevents
Дополнительная информация о компании cyber•Fund
Мы инвестируем и развиваем блокчейн проекты, способные кардинально менять наш мир в лучшую сторону, создавая экономику роботов и самовыражения людей. Больше о нашей работе вы можете узнать из следующих ресурсов:
Наши проекты:
сyber•Fund - аналитика и разработка блокчейн систем
Golos.io - медийная блокчейн платформа
Satoshi•Fund - первый фонд инвестирующий в криптоактивы
Cyberstudio.io - помощь в проведении ICO
Мы ждем вас в наших сообществах:
Блог:
https://blog.cyber.fund/
Email Newsletter:
http://company.cyber.fund/#newsletter
Социальные сети:
https://golos.io/@cyberfund
https://steemit.com/@cyberfund
https://twitter.com/cyberfundio
https://www.reddit.com/r/cyber_Fund/
https://www.facebook.com/cyberfund - официальная страница сyber•Fund
https://www.facebook.com/blockchainmeetups/ - официальная страница cyber•Events (Блокчейн митапы, конференции, доклады)
https://www.slideshare.net/CyberFund-Official
Для разработчиков:
https://t.me/CyberFundDev - telegram чат для блокчейн разработчиков
https://github.com/cyberFund - наш репозиторий на Github с open source software
https://github.com/cyberFund/Library - библиотека знаний по блокчейн
Дмитрий Жестилевский — Yet another threading framework: асинхронная разработк...Yandex
Код приложений для мобильных устройств, написанный на C++, часто оказывается сложнее аналогичного на Java, ObjC или C#. Данные языки предлагают решения стандартных задач разработчика «из коробки». Многие из этих задач связаны с асинхронным выполнением операций.
В докладе я представлю подход к написанию понятного и производительного асинхронного кода на С++, который применяется в разработке библиотек для мобильных геоприложений в Яндексе.
"Почему язык Lua — это интересно?", Ник Заварицкий, (Mail.ru Group)Badoo Development
DevConf 2016
"Почему язык Lua — это интересно?", Ник Заварицкий, (Mail.ru Group)
Lua — высокоуровневый язык, похожий на Python/JS, но существенно более простой. Он гибкий и при этом очень быстрый.
Возможно, вы слышали про OpenResty. Это решение для разработки Nginx модулей на Lua. Cloudflare, крупнейший CDN/anti-DDOS провайдер, как раз работает на OpenResty.
На скоростях 10/100Gb сетевой стек в ядре Linux становится “узким местом”. Есть ряд технологий для выноса обработки пакетов из ядра в userspace; например Snabb Switch. Последний написан целиком на Lua и справляется с потоком в 200+Gb.
Как на счет менее экзотических применений? На Lua есть свой Node.js (luvit.io). Lua есть в БД Tarantool. У нас была задача валидации данных на соответствие схеме; мы переписали валидацию с Си на Lua и получили ускорение в 4 раза (за счет JIT-компиляции).
Lua набирает популярность и он объективно хорош. Что будет в докладе:
1) Краткое введение в Lua: мы убедимся в том, что язык простой и там есть все необходимое на каждый день.
2) Секция Lua WAT (смешные контр-интуитивные особенности языка, 0 and 1 == 0)
3) Поговорим о том, почему Tarantool использует LuaJIT, а не V8.
4) Разберемся, почему именно Lua такой быстрый, и как работает трассирующий JIT-компилятор.
Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"Tanya Denisyuk
Тезисы:
За последние 2 года экосистема tarantool пополнилась огромным количеством батареек: дисковое хранение, lua-шардинг, работа со схемами данных и версиями, nginx upstream модуль. Используя эти компоненты, можно создавать высокопроизводительные приложения без использования дополнительных технологий.
В докладе будет описан опыт использования Tarantool для разработки performance-critical restful api: расскажу в чем плюсы и минусы текущей реализации lua-шардинга, как создать restful api прямо в базе данных и почему это быстрее многих популярных решений на примере реальных данных. Кроме того, будет рассмотрен подход использования avro схем для валидации, версионирования и хранения json документов в Tarantool. Для наглядности во время доклада будет разработан микросервис и проведено нагрузочное тестирование.
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014Python Meetup
В своем докладе Олег расскажет о замене стандартных функций на более быстрые и об ускорении работы python. Также продемонстрирует несколько примеров быстрых конструкций python.
В своей работе мы постоянно используем инструменты, призванные облегчить нам жизнь. Но как хорошо мы ими на самом деле владеем? И почему мы пренебрегаем их суперсилами? Например, Chrome DevTools — это не только отладчик и инспектор HTML. Но когда у нас в руках молоток, кругом мерещатся гвозди. Десятки мегабайт и процентов загрузки процессора на вкладку браузера — верный признак того, что пора учиться пользоваться микроскопом.
Роман предложит освоить что-то посложнее молотка и расскажет о том, какую реальную пользу можно получить от профилирования, как найти в огромном отчёте проблему с кодом и что лучше — написать в коде десяток console.log или async debug.
Надежный обмен данными в гетерогенной среде, между разными платформами и технологиями является одним из ключевых моментов разработки сложных систем. Во время обмена данные преобразуются в некоторый промежуточный формат совместимый между платформами. Преобразование в подобный формат и из него — крайне рутинная и подверженная ошибкам работа.
Метаописание данных неким декларативным языком с последующей автогенерацией типизированных структур облегчает жизнь разработчику. Снимает с него необходимость задумываться о промежуточном формате, о правильном порядке полей, а типизированность гарантирует выявление ошибок еще на этапе компиляции кода.
В докладе будет рассмотрено несколько подобных решений, их плюсы и минусы. Также будет рассмотрен с практической стороны наш собственный формат метаданных, используемый нами на протяжении более 5 лет.
Целевая аудитория:
Ограничений нет, но в большей степени разработчики, имеющие уже определенный опыт разработки разнородных систем или приступающие к подобной задаче.
Разработка на блокчейн Голос | Ерлан ШиндаулетовCyber Fund
Данная презентация была представлена на одном из еженедельных образовательных митапов от компании cyber•Fund.
Посмотреть полное видео с митапа можно здесь:
https://www.youtube.com/watch?v=ZkF59_XwraI
Прочитать текстовую версию выступления:
https://golos.io/@cyberevents
Дополнительная информация о компании cyber•Fund
Мы инвестируем и развиваем блокчейн проекты, способные кардинально менять наш мир в лучшую сторону, создавая экономику роботов и самовыражения людей. Больше о нашей работе вы можете узнать из следующих ресурсов:
Наши проекты:
сyber•Fund - аналитика и разработка блокчейн систем
Golos.io - медийная блокчейн платформа
Satoshi•Fund - первый фонд инвестирующий в криптоактивы
Cyberstudio.io - помощь в проведении ICO
Мы ждем вас в наших сообществах:
Блог:
https://blog.cyber.fund/
Email Newsletter:
http://company.cyber.fund/#newsletter
Социальные сети:
https://golos.io/@cyberfund
https://steemit.com/@cyberfund
https://twitter.com/cyberfundio
https://www.reddit.com/r/cyber_Fund/
https://www.facebook.com/cyberfund - официальная страница сyber•Fund
https://www.facebook.com/blockchainmeetups/ - официальная страница cyber•Events (Блокчейн митапы, конференции, доклады)
https://www.slideshare.net/CyberFund-Official
Для разработчиков:
https://t.me/CyberFundDev - telegram чат для блокчейн разработчиков
https://github.com/cyberFund - наш репозиторий на Github с open source software
https://github.com/cyberFund/Library - библиотека знаний по блокчейн
Дмитрий Жестилевский — Yet another threading framework: асинхронная разработк...Yandex
Код приложений для мобильных устройств, написанный на C++, часто оказывается сложнее аналогичного на Java, ObjC или C#. Данные языки предлагают решения стандартных задач разработчика «из коробки». Многие из этих задач связаны с асинхронным выполнением операций.
В докладе я представлю подход к написанию понятного и производительного асинхронного кода на С++, который применяется в разработке библиотек для мобильных геоприложений в Яндексе.
"Почему язык Lua — это интересно?", Ник Заварицкий, (Mail.ru Group)Badoo Development
DevConf 2016
"Почему язык Lua — это интересно?", Ник Заварицкий, (Mail.ru Group)
Lua — высокоуровневый язык, похожий на Python/JS, но существенно более простой. Он гибкий и при этом очень быстрый.
Возможно, вы слышали про OpenResty. Это решение для разработки Nginx модулей на Lua. Cloudflare, крупнейший CDN/anti-DDOS провайдер, как раз работает на OpenResty.
На скоростях 10/100Gb сетевой стек в ядре Linux становится “узким местом”. Есть ряд технологий для выноса обработки пакетов из ядра в userspace; например Snabb Switch. Последний написан целиком на Lua и справляется с потоком в 200+Gb.
Как на счет менее экзотических применений? На Lua есть свой Node.js (luvit.io). Lua есть в БД Tarantool. У нас была задача валидации данных на соответствие схеме; мы переписали валидацию с Си на Lua и получили ускорение в 4 раза (за счет JIT-компиляции).
Lua набирает популярность и он объективно хорош. Что будет в докладе:
1) Краткое введение в Lua: мы убедимся в том, что язык простой и там есть все необходимое на каждый день.
2) Секция Lua WAT (смешные контр-интуитивные особенности языка, 0 and 1 == 0)
3) Поговорим о том, почему Tarantool использует LuaJIT, а не V8.
4) Разберемся, почему именно Lua такой быстрый, и как работает трассирующий JIT-компилятор.
Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"Tanya Denisyuk
Тезисы:
За последние 2 года экосистема tarantool пополнилась огромным количеством батареек: дисковое хранение, lua-шардинг, работа со схемами данных и версиями, nginx upstream модуль. Используя эти компоненты, можно создавать высокопроизводительные приложения без использования дополнительных технологий.
В докладе будет описан опыт использования Tarantool для разработки performance-critical restful api: расскажу в чем плюсы и минусы текущей реализации lua-шардинга, как создать restful api прямо в базе данных и почему это быстрее многих популярных решений на примере реальных данных. Кроме того, будет рассмотрен подход использования avro схем для валидации, версионирования и хранения json документов в Tarantool. Для наглядности во время доклада будет разработан микросервис и проведено нагрузочное тестирование.
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014Python Meetup
В своем докладе Олег расскажет о замене стандартных функций на более быстрые и об ускорении работы python. Также продемонстрирует несколько примеров быстрых конструкций python.
В своей работе мы постоянно используем инструменты, призванные облегчить нам жизнь. Но как хорошо мы ими на самом деле владеем? И почему мы пренебрегаем их суперсилами? Например, Chrome DevTools — это не только отладчик и инспектор HTML. Но когда у нас в руках молоток, кругом мерещатся гвозди. Десятки мегабайт и процентов загрузки процессора на вкладку браузера — верный признак того, что пора учиться пользоваться микроскопом.
Роман предложит освоить что-то посложнее молотка и расскажет о том, какую реальную пользу можно получить от профилирования, как найти в огромном отчёте проблему с кодом и что лучше — написать в коде десяток console.log или async debug.
Доклад рассматривает тонкости nodejs, а так же преимущества Evented I/O для серверных приложений. Будет предоставлен ряд рекоммендаций по правильному построению архитектуры, модульности, масштабированию, дизайну кода. Краткое введение в технологию программирования "волокнами" (fibers) и ряд других эффективных практик.
Нельзя просто так взять и сделать версионирование APIEatDog
"Нельзя просто так взять и сделать версионирование API"
Почему важно иметь версионирование и какие проблемы оно решает
Какие есть подходы к версионированию API
Какие инструменты и решения предоставляют популярные веб-фреймворки
Почему версионирование - это не просто и как решить возникшие трудности
Выводы
Транзакционный фреймворк для сингловых игр и игр с асинхронным мультиплеером ...DevGAMM Conference
В докладе Антон расскажет о транзакционном фреймворке, на котором построен новый проект студии Pushkin: батлер с асинхронным мультиплеером, синхронизацией состояния между устройствами, минимальными требованиями к сети и защитой от читеров.
Докладчик: Данил Руденко
О докладе:
По некоторым оценкам, больше половины профессий будет автоматизировано – это и есть максимальный объём, на который может быть увеличен рынок алгоритмов машинного обучения, ярчайшем представителем которого являются нейронные сети.
В докладе мы поговорим об общей концепции нейронных сетей, рассмотрим основные Python - фреймворки для машинного обучения, а также реализуем решение задачи классификации изображений с применением Keras.
Докладчик: Данил Руденко
О докладе:
У нашего зоопарка опять проблемы, которые необходимо решить максимально технологично!
На первом докладе мы поговорили о сверточных нейронных сетях, в этот раз рассмотрим такие виды нейронных сетей как автоэнкодеры и GAN’ы( генеративные состязательные сети). Также углубимся немного в Keras, напишем кастомный загрузчик данных и немного посмотрим на Jupyter Notebook.
Видео: https://youtu.be/tu-ee_4uAGY
Докладчик: Станислав Каблуков
О докладе:
Расскажу о своём опыте использования Python для разработки игр. В каких игровых движках и программах для моделирования используется Python.
Как и почему стоит использовать python для создания игр, и в каких случаях лучше отказаться от данной идеи. О плюсах и минусах использования Python.
В докладе будет про: python, blender, Ren'py, KivEnt, Boo, UE4 и д.р.
Видео: https://youtu.be/2RrZx_J5twU
Python инструменты для нагрузочного тестированияPyNSK
В докладе я расскажу об использовании yandex.tank с BFG и locustio для нагрузочного тестирования.
Докладчик: Иван Гребенщиков
Видео: https://youtu.be/-kWm5V9pyCY
Python, Django и корпоративные информационные системыPyNSK
Софт для автоматизации бизнеса составляет значительную часть всего существующего на планете программного обеспечения. Рассмотрим требования к нему и особенности его разработки. Оценим, насколько Python для этого подходит, и облегчают ли фреймворки жизнь в кровавом энтерпрайзе.
Докладчик: Анатолий Щербаков
Видео: https://youtu.be/G_ks3sO1Mbs
Как показать релевантный текст для пользователя? Собрать данные, написать разные тексты, а потом написать кучу IF'ов?
В докладе я расскажу, как мы, в Welltory, делаем настройку контента под пользователя.
Поведаю о том, как content writer'ы могут писать 100 вариантов текстов на одно событие в системе.
И конечно, расскажу с чего начать вам.
Докладчик: Александр Сапронов
Видео: https://youtu.be/sG6kUxq6gDY
В докладе я расскажу об устройстве одноплатного компьютера и его периферии на примере raspbery pi.
Установку на него дистрибутива операционной системы, python 3 и управление с помощью него периферией (i2c spi uart и отдельными pin). А ещё я это покажу в живую
Докладчик: Иван Бакланов
Видео: https://www.youtube.com/watch?v=1WiIMeWHMY8
В докладе мы рассмотрим создание переносимого дистрибутива Python для любых нужд и операционных систем (Windows & Linux). Познакомимся с существующими и альтернативными решениями. Сравним их достоинства и недостатки.
Докладчик: Григорий Кареев (Odin)
Видео: https://www.youtube.com/watch?v=fvBJG_IKvaQ
Рассмотрю с практической стороны создание своего предметно-ориентированного языка. Продемонстрирую почти готовое решение возникшей задачи и расскажу, в каких случаях может потребоваться внедрение DSL.
Докладчик: Михаил Воротынцев (AgoraDoxa)
Видео: https://www.youtube.com/watch?v=Qf0TjcBG1oI
Докладчик:
Александр Сапронов
Описание:
Язык Python отлично подходит для прототипирования: простой синтаксис, множество батареек, много готовых решений. Это отлично для бизнеса и для разработчика.
Но давайте снимем розовые очки и озвучим негатив, который вас ждет, когда вы возьмете Python для проекта.
Видео:
https://www.youtube.com/watch?v=YE9Q78QlZiE
Как Python Дайджест работает с внешней статикойPyNSK
Докладчик:
Александр Сапронов
Описание:
В мини-докладе я рассмотрю простой велосипед (django-remdow), который позволяет в автоматическом режиме скачивать внешнюю статику. А также приведу простые инструменты для автоматической оптимизации вашего сайта.
Применение behave+webdriver для тестирования Web-проектовPyNSK
Докладчик:
Иван Гребенщиков
Описание:
Современные веб-проекты представляют из себя совсем не набор статических страниц, что повышает сложность их функционального тестирования.
В докладе будет рассмотрена связка инструментов behave+webdriver, способе их применения, возможные проблемы и пути их решения.
Докладчик:
Игорь Стариков
Описание:
Не секрет, что Питон, благодаря своим свойствам, имеет широчайшую область применения. Не являются исключением и мультимедийные (в том числе игровые) приложения.
В ходе этого выступления:
1. вы узнаете о некоторых средствах и принципах их построения, а также о том, как упомянутые средства могут использовать функции внешних библиотек, написанных на других языках программирования;
2. а я получу, наконец, достижение из одной известной игры, не запуская её.
Докладчик:
Александр Сапронов
Описание:
Мы вместе пройдем по популярным задачам — от парсинга сайтов до научных вычислений и рассмотрим мощь языка Python
Докладчик:
Александр Сапронов
Описание:
Мы рассмотрим популярные библиотеки для функционального программирования на Python — fn.py, functools, itertools, funcy, hask, Toolz. Узнаем возможности каждой из библиотеки, а также как в динамическом язык имитировать мощную систему типов. Затронем характеристики функционального программирования и проверим помогают ли библиотеки выполнить.
Докладчик:
Александр Кацко
Описание:
Как только речь заходит про создание API, особенно для веб или мобильных приложений, то многие, не задумываясь, выбирают принцип REST. Но всегда ли это правильный выбор?
В докладе рассмотрим случаи, для которых хорошо подходит JSON-RPC, посмотрим примеры реализации на Django.
Докладчик:
Антон Голов
Описание:
Поговорим о некоторых функциях для интеграции TestRail c внешними системами и автоматизации деятельности QA. Будет немного про Google Docs, и некоторый набор методов работы с Testrail, рассмотрим возможности работы с системами автоматизированного тестирования.
7. Matches dbs Users dbsBlack Box
1 000 000 000 игр
1 тб сжатых данных
70 тб скачено через Dota Web API
10 000 000 игроков
500 гб данных
Key:value
+1 000 000 каждый день
GET /getMatch/{match_id}
GET /getNextMatch
9. Решение #1
sequential read:
Читаем все матчи подряд и апдейтим игроков
import requests
from config import db_addresses
for db_server, db_port in db_addresses:
while not error:
r = requests.get('http://{}:{}/getNextMatch'.format(db_server,
db_port))
match_json = r.json()
process(match_json)
12. from concurrent.futures import ThreadPoolExecutor
def fetch(server, port):
r = requests.get('http://{}:{}/getNextMatch'.format(server, port))
process(r.json())
with ThreadPoolExecutor(max_workers = 10) as executor:
for db_server, db_port in db_addresses:
while True:
for _ in range(10):
executor.submit(fetch, db_server, db_port)
sleep(0.015)
13. from concurrent.futures import ThreadPoolExecutor
def fetch(server, port):
r = requests.get('http://{}:{}/getNextMatch'.format(server, port))
process(r.json())
with ThreadPoolExecutor(max_workers = 10) as executor:
for db_server, db_port in db_addresses:
while True:
for _ in range(10):
executor.submit(fetch, db_server, db_port)
sleep(0.015)
Накрасивый вызов аргументов
14. from concurrent.futures import ThreadPoolExecutor
def fetch(server, port):
r = requests.get('http://{}:{}/getNextMatch'.format(server, port))
process(r.json())
with ThreadPoolExecutor(max_workers = 10) as executor:
for db_server, db_port in db_addresses:
while True:
for _ in range(10):
executor.submit(fetch, db_server, db_port)
sleep(0.015)
Параметры придется подбирать эксперементально
15. from concurrent.futures import ThreadPoolExecutor
def fetch(server, port):
r = requests.get('http://{}:{}/getNextMatch'.format(server, port))
process(r.json())
with ThreadPoolExecutor(max_workers = 10) as executor:
for db_server, db_port in db_addresses:
while True:
for _ in range(10):
executor.submit(fetch, db_server, db_port)
sleep(0.015)
Треды не бесконечны и затрагивают OS
16. from concurrent.futures import ThreadPoolExecutor
def fetch(server, port):
r = requests.get('http://{}:{}/getNextMatch'.format(server, port))
process(r.json())
with ThreadPoolExecutor(max_workers = 10) as executor:
for db_server, db_port in db_addresses:
while True:
for _ in range(10):
executor.submit(fetch, db_server, db_port)
sleep(0.015)
Неявное отличие блокирующих функций от неблокирующих
17. import asyncio
import aiohttp
async def fetch(session, url):
async with session.get(url) as response:
match_json = await response.json()
process(match_json)
async def main():
async with aiohttp.ClientSession() as session:
for db_server, db_port in db_addresses:
while True:
for _ in range(10):
loop.create_task(fetch(session, url))
await asyncio.sleep(0.015)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
18. import asyncio
import aiohttp
async def fetch(session, url):
async with session.get(url) as response:
match_json = await response.json()
process(match_json)
async def main():
async with aiohttp.ClientSession() as session:
for db_server, db_port in db_addresses:
while True:
for _ in range(10):
loop.create_task(fetch(session, url))
await asyncio.sleep(0.015)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
1 скрипт = 1 loop, 1 thread
19. import asyncio
import aiohttp
async def fetch(session, url):
async with session.get(url) as response:
match_json = await response.json()
process(match_json)
async def main():
async with aiohttp.ClientSession() as session:
for db_server, db_port in db_addresses:
while True:
for _ in range(10):
loop.create_task(fetch(session, url))
await asyncio.sleep(0.015)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
Все еще проблема со sleep и синтаксисом
20. async def main():
async with aiohttp.ClientSession() as session:
for db_server, db_port in db_addresses:
while True:
tasks = []
for _ in range(10):
tasks.append(fetch(session, url))
await asyncio.gather(*tasks)
21. async def main():
async with aiohttp.ClientSession() as session:
for db_server, db_port in db_addresses:
while True:
tasks = []
for _ in range(10):
tasks.append(fetch(session, url))
await asyncio.gather(*tasks)
Gather работает со скоростью самого медленного запроса
22. sem = asyncio.Semaphore(10)
async def fetch(session, url):
async with session.get(url) as response:
match_json = await response.json()
process(match_json)
sem.release()
async def main():
async with aiohttp.ClientSession() as session:
for db_server, db_port in db_addresses:
while True:
await sem.acquire()
loop.create_task(fetch(session, url))
23. async def fetch(session, url):
async with session.get(url) as response:
match_json = await response.json()
process(match_json)
async def main():
async with aiohttp.ClientSession() as session:
for db_server, db_port in db_addresses:
while True:
async with sem:
loop.create_task(fetch(session, url))
24. async def fetch(session, url):
async with session.get(url) as response:
match_json = await response.json()
process(match_json)
async def main():
async with aiohttp.ClientSession() as session:
for db_server, db_port in db_addresses:
while True:
async with sem:
loop.create_task(fetch(session, url))
Размер семафора все еще нужно подбирать эксперементально
25. async def fetch(session, url):
async with session.get(url) as response:
match_json = await response.json()
process(match_json)
async def main():
async with aiohttp.ClientSession() as session:
for db_server, db_port in db_addresses:
while True:
async with sem:
loop.create_task(fetch(session, url))
Данные изменяются в разных частях кода. Нет гарантий точности
26. async def fetch(session, url):
async with session.get(url) as response:
match_json = await response.json()
process(match_json)
async def main():
async with aiohttp.ClientSession() as session:
for db_server, db_port in db_addresses:
while True:
async with sem:
loop.create_task(fetch(session, url))
Можно упереться в нагрузку на стороне сервера с базой
Хочется делать N паралельных запросов к каждому серверу
27. Queue
Читаем данные из любого места в коде
Изменяем данные только в одном месте
Гарантирован порядок выполнения задач
Thinking about Concurrency
Raymond Hettinger, Python core developer
https://youtu.be/Bv25Dwe84g0
28. ●
Максимальный доступ к базам
●
Результат собирается в одном месте
admin_queue = asyncio.Queue(maxsize = 1000)
async def read_from_admin_queue():
while True:
match_json = await admin_queue.get()
process(match_json)
admin_queue.task_done()
async def fetch_from_db(url):
while True:
async with session.get(url) as response():
match_json = await response.json()
await admin_queue.put(match_json)
async def main():
loop.create_task(read_from_admin_queue())
for db_server, db_port in db_addresses:
loop.create_task(fetch_from_db(url))
30. Все круто пока игроки помещаются в память. А если нет?
while True:
for player_id, player_matches in players_matches_list:
player = Player(player_id)
for match_id in player_matches:
match_json = r.get('.../getMatch/{}'.format(match_id))
player.parse_match(match_json)
db.update(player)
31. Все круто пока игроки помещаются в память. А если нет?
while True:
for player_id, player_matches in players_matches_list:
player = Player(player_id)
for match_id in player_matches:
match_json = r.get('.../getMatch/{}'.format(match_id))
player.parse_match(match_json)
db.update(player)
База становится очень зависима от скорости random read.
SSD ~ 40 000RPS
Выгодно брать больше серверов с большим кол-вом дисков
35. read_only для всех баз кроме последней
Можно делать частичную выборку игроков
Можно писать один код для batch и online обновлений
36. async def get_match_json(db_server, db_port, match_id):
async with session.get(url.format(db_server, db_port, match_id)) as
response:
return await response.json()
for player_id, player_matches in players_matches_list:
player = Player(player_id)
tasks = await asyncio.gather(*[get_match_json(db_server, db_port,
match_id) for db_server, db_port, match_id in player_matches])
for match_json in tasks.results():
player.parse_match(match_json)
db.update(player)
37. async def get_match_json(db_server, db_port, match_id):
async with session.get(url.format(db_server, db_port, match_id)) as
response:
return await response.json()
for player_id, player_matches in players_matches_list:
player = Player(player_id)
tasks = await asyncio.gather(*[get_match_json(db_server, db_port,
match_id) for db_server, db_port, match_id in player_matches])
for match_json in tasks.results():
player.parse_match(match_json)
db.update(player)
Gather может собирать результаты функции
38. async def get_match_json(db_server, db_port, match_id):
async with session.get(url.format(db_server, db_port, match_id)) as
response:
return await response.json()
for player_id, player_matches in players_matches_list:
player = Player(player_id)
tasks = await asyncio.gather(*[get_match_json(db_server, db_port,
match_id) for db_server, db_port, match_id in player_matches])
for match_json in tasks.results():
player.parse_match(match_json)
db.update(player)
Одновременно процесим только одного игрока ;-(
42. async def fetch_from_players_matches_list():
for player_id, player_matches in players_matches_list:
await admin_queue.put(('new player', {
'player_id': player_id,
'total_player_matches': len(player_matches)
}))
await asyncio.gather(*[
matches_db_queues[db_name].put(match_id) for
db_name, match_id in player_matches
])
43. Каждый матч придется читать не 1 раз, а в N раз больше.
N — кол-во игроков в одном матче
44. HTTP слишком медленный протокол для такого кол-ва операций
~ 1000-1500 запросов в секунду при 100% CPU
45. HTTP слишком медленный протокол для такого кол-ва операций
~ 1000-1500 запросов в секунду при 100% CPU
HTTP лучше заменить на web socket
~ 10 000 запросов в секунду без нагрузки на CPU
(можно использовать RabbitMQ или Apache Kafka)
46. async def fetch_from_socket(db_name):
async with ClientSession() as session:
async with session.ws_connect('http://
{}/socket'.format(db_name)) as ws:
async for msg in ws:
if msg.type == aiohttp.WSMsgType.TEXT:
match_json = json.load(msg.data)
await admin_queue.put(match_json)
47. async def fetch_from_socket(db_name):
async with ClientSession() as session:
async with session.ws_connect('http://
{}/socket'.format(db_name)) as ws:
async for msg in ws:
if msg.type == aiohttp.WSMsgType.TEXT:
match_json = json.load(msg.data)
await admin_queue.put(match_json)
Пока ждем ответа от сервера негде послать сообщение
48. async def fetch_from_socket(db_name):
async with ClientSession() as session:
async with session.ws_connect('http://
{}/socket'.format(db_name)) as ws:
async for msg in ws:
if msg.type == aiohttp.WSMsgType.TEXT:
match_json = json.load(msg.data)
await admin_queue.put(match_json)
async def send_to_socket(ws):
while True:
match_id = await matches_db_queues.get()
await ws.send_str('get next match {}'.format(match_id))
matches_db_queues.task_done()
49. Даже если мы может процесить несколько игроков одновременно,
их игры будет неравномерно распределены по базам с матчами
50. Даже если мы может процесить несколько игроков одновременно,
их игры будет неравномерно распределены по базам с матчами
51. Даже если мы может процесить несколько игроков одновременно,
их игры будет неравномерно распределены по базам с матчами
52. Даже если мы может процесить несколько игроков одновременно,
их игры будет неравномерно распределены по базам с матчами
Одна база все равно используется неэффективно
53. Даже если мы может процесить несколько игроков одновременно,
их игры будет неравномерно распределены по базам с матчами
Выгоднее один раз посчитать такие наборы игроков,
что их обращение к базам будет наиболее эффективно
54. Итог
●
CPU на 100% на базах с матчами и игроками
●
Скорость ограничена SSD random read
●
Гибко
●
Понятно
●
Легко мониторить