Repository: NickVolynkin/highload-2018 Branch: master Commit: 3a6e825663e9 Files: 65 Total size: 237.1 KB Directory structure: gitextract_hctkx_uf/ ├── .github/ │ └── workflows/ │ └── main.yml ├── .gitignore ├── .gitmodules ├── archetypes/ │ └── default.md ├── config.toml ├── content/ │ ├── aletheia/ │ │ └── 19/ │ │ ├── assessment.md │ │ └── culture-transformation.md │ ├── devopsconf/ │ │ └── 19/ │ │ ├── fast-releases.md │ │ └── werf.md │ ├── devrelconf/ │ │ └── 5/ │ │ ├── brand-ambassador.md │ │ ├── ghostwriters.md │ │ └── technical-authors.md │ ├── frontendconf/ │ │ └── 19/ │ │ ├── promoting-opensource.md │ │ └── style_silver_bullet.md │ ├── highload/ │ │ ├── 18/ │ │ │ ├── 1.1-microservices.md │ │ │ ├── 1.10-neural-nets-cgi.md │ │ │ ├── 1.2-per-aspera-ad-paas.md │ │ │ ├── 1.3-data-discovery.md │ │ │ ├── 1.4-bd-k8s.md │ │ │ ├── 1.5-kafka-bicycle.md │ │ │ ├── 1.6-accelerate-events.md │ │ │ ├── 1.7-postgresql-errors.md │ │ │ ├── 1.8-badoo-infradev.md │ │ │ ├── 1.9-data-engineers.md │ │ │ ├── 2.1-vk-architecture.md │ │ │ ├── 2.2-testing-badoo.md │ │ │ ├── 2.3-such-highload.md │ │ │ ├── 2.4-dababase-pro.md │ │ │ └── 2.5-make-your-database-dream-of-electric-sheep.md │ │ └── 19/ │ │ ├── njs-nginx.md │ │ ├── siberia/ │ │ │ └── docs.md │ │ └── tcp-vs-udp.md │ ├── knowledgeconf/ │ │ └── 19/ │ │ ├── badoo-new-developers-onboarding.md │ │ ├── biocad-knowledge-base-development.md │ │ ├── e-learning.md │ │ ├── holistic-km.md │ │ ├── km-efficiency.md │ │ ├── km-system-and-business.md │ │ ├── knowledge-manger-6-10.md │ │ ├── knowledge-sharing-involvement.md │ │ ├── manager-analyst-km.md │ │ ├── multimedia-documentation.md │ │ ├── ozon-fast-growth-and-knowledge-sharing.md │ │ ├── tiago-forte-practices.md │ │ ├── trello-kb.md │ │ ├── voluntary-forced-knowledge-sharing.md │ │ └── xi-notes-for-developer.md │ ├── moscowpython/ │ │ └── 19/ │ │ ├── accelerate-python.md │ │ ├── go-vs-python.md │ │ ├── kill-mutants.md │ │ └── yandex-python.md │ ├── qualityconf/ │ │ └── 19/ │ │ ├── blameless.md │ │ └── libfuzzer.md │ ├── siberian-community-orgs/ │ │ └── documenting-meetings.md │ ├── teamleadconf/ │ │ ├── 20/ │ │ │ └── documentation_challenges.md │ │ └── 21/ │ │ ├── how_to_create_selforganizing_team.md │ │ ├── learn_the_hard_way.md │ │ ├── process-smell.md │ │ └── right_of_fail.md │ └── whalerider/ │ └── 19/ │ └── investor.md ├── layouts/ │ ├── index.html │ └── table.html ├── readme.md └── static/ ├── .nojekyll └── custom.css ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/workflows/main.yml ================================================ name: Deploy to GitHub Pages on: push: branches: [ master ] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 with: submodules: true fetch-depth: 0 - name: Setup Hugo uses: peaceiris/actions-hugo@v2 with: hugo-version: '0.56.0' extended: true - name: Build run: hugo --minify - name: Deploy uses: peaceiris/actions-gh-pages@v3 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./public publish_branch: gh-pages ================================================ FILE: .gitignore ================================================ .idea public resources ================================================ FILE: .gitmodules ================================================ [submodule "themes/tale-hugo"] path = themes/tale-hugo url = git@github.com:docops-hq/conf-hugo-theme.git ================================================ FILE: archetypes/default.md ================================================ --- title: "{{ replace .Name "-" " " | title }}" date: {{ .Date }} draft: true --- ================================================ FILE: config.toml ================================================ baseURL = "https://docops-hq.github.io/conf/" languageCode = "en-us" title = "Конспекты" theme = "tale-hugo" [taxonomies] tag = "tags" category = "categories" [outputs] home = ["HTML", "JSON", "RSS"] blog = ["HTML", "JSON", "RSS"] [Params] css = ["custom.css"] ga_id = "UA-107215405-3" ================================================ FILE: content/aletheia/19/assessment.md ================================================ --- title: "(Почти) Объективная оценка людей в IT" author: "Георгий Могелашвили, Booking.com" tags: ["Aletheia Business", "2019"] summary: "" --- Автор конспекта — Родион Нагорнов. Георгий начал с того, что назвал айтишников творческими людьми и задался тем, как оценивать творчество? А затем перешёл к любимому вопросу «зачем это делать?» Он назвал желание наказать, поощрить и найти точки роста. Затем указал, что легче всего для разработчика измерить строки кода и отработанные Часы. Но это не работает, т.к. легко читерится. ## Метод What & How Что: Вклад в проект, команду; работа для других команд, закрытые тикеты, скорость работы, т.е. навыки. Как: Это про поведение: как оценивают тебя коллеги, как ты сам себя проявляешь Как оценивать в оценках: Обязательна предподготовка. Описание ролей, матрицы компетенций по методу what&how, обьяснить всем, как будут оценивать. По опыту букинга лучше всего работает оценка менеджером и командой. Не сработала оценка только менеджером, тк менеджер - узкое место+субъективность. ## Методика 360 и открытый фидбек Оценивают по методике 360. Peer feedback - оценка людьми, с которыми работал в течение квартала. Людей выбирает оцениваемый. Ответы видны оцениваемому и менеджеру. Фидбек открытый. Пробовали анонимный, но качество ниже. Много неконструктивных гадостей, отписок, сотруднику непонятно, нельзя уточнить детали, если нет конкретики. При открытом нужен высокий уровень доверия в команде, иначе обратная связь становится льстивее. Self evaluation - про себя, за прошлый квартал, с учетом peer feedback. Manager’s review - заполняется с учётом двух других. Вопросы: * Что человек сделал хорошо? * Что он мог бы сделать лучше, чтобы иметь лучший результат? Без негативных формулировок. ## Оценка сотрудника в баллах Затем оценка по общеизвестным критериям на основе фидбеков, она сопровождается примерами. Оценка от 1 до 5. Оценивает только менеджер. Ушли от оценивания всеми, т.к. 1. не умеют оценивать, 2. сложно оценить коллегу, с которым ходишь на обед и в курилку. На следующем этапе оценки ушли на калибровку. Выравнивают по командам и департаментам. Чтобы одна оценка значила одно и то же для команд с разным уровнем сложности и условиями работы. Минус в очень большом времени. ## Итоговый фидбек сотруднику Сотруднику даётся фидбек в стиле BIO (behavior, impact, options). Подробности очень важны. Вернуть в контекст (behavior), показать, как повлияло (impact), сказать, что можно сделать иначе (options), не в приказном, а рекомендательном стиле. И напоследок цитата из «О чем говорят мужчины»: «В искусстве нет объективных критериев. Не то что в спорте: ты пробежал быстрее, и не важно как, хоть спиной вперёд». ## Последние рекомендации * Много фидбэка всегда, желательно в формате BIO * Оценивать сложно, а объективно - почти нереально. * Сотрудник, которого оценили необъективно, будет недоволен, поэтому менеджер должен быть очень хорошо подготовлен на примерах. Поэтому: если можете не оценивать - не оценивайте! ================================================ FILE: content/aletheia/19/culture-transformation.md ================================================ --- title: "Трансофрмация бизнес-культуры: преодолеть сопротивление, добиться результата" author: "Марина Корсакова, МИРБИС" tags: ["Aletheia Business", "2019"] summary: "" --- Автор конспекта — Родион Нагорнов. Марина начинает с вопроса «зачем». Про этот вопрос я уже дважды выступал в этом году, и через пару дней выступлю ещё раз. Так что, я в тренде, у меня есть единомышленники. Кстати, предыдущие спикеры тоже говорили при «зачем». Итак, речь о создании дружественной среды для инноваций. Говорят, что многие руководители готовы выделять под это не более 2-3% времени на инновации. Но нормально - это хотя бы 30. Дальше про среду. Часто хотят набрать внешних людей с их идеями, чтобы проводить инновации, но те, приходя в компанию, сталкиваются с существующей сложившейся средой. А среда «и так же работала». Поэтому идеи этих людей часто реализуют уже другие люди, а автор уже ушёл. Дружественная инновационная среда должна обладать чертами с фоточки 🙂 Дальше идёт рассказ про цветовую схему Лалу про организации. Марина говорит, что в России понятие бирюзовой организации подменяется - реально под этим цветом имеют в виду зелёный, где в центре люди. А бирюзовость - это баланс между интересами людей и бизнеса. И вопрос «как». Для того, чтобы понять, как должна измениться культура, надо 1. Договориться, что произойдёт, если компания изменится и если не изменится. Это история про то, что нужно представить, что будет иначе после внедрения и изменения корп.культуры. И не менять ее, если эта метафора не достаточно ужасна или «прекрасна» 🙂 2. Придумать метафору будущего. Нужен конкретный план, и конкретный план - это единственный способ меняться. Понимать и применять искусство маленьких шагов (с) экзюпери. Никто не может сделать большой шаг -> это демотивирует -> перестают заниматься. Все хотят сильно вкладываться, чтобы получить много, но лучше сначала собрать «низко висящие фрукты». Поставить задачу на короткий период и небольшое изменение. «Пропаганда» будущего - это очень важно. Много говорить, говорить со всеми, и контент должен быть разным, т.к. Не все работает. Удивительно, что люди, которые прекрасны в самоорганизованности и проектной дисциплине, при трансформации теряют этот сели и не ставят сроков, целей, метрик. Это важно. После внедрения и трансформации нужно продолжать пропаганду, рассказывая людям о том, как теперь у нас все будет и зачем. Для этого снова надо договариваться, помещать и корректировать метафоры будущего сотрудников, чтобы они сами чувствовали себя причастными и считали метафору своей. Об этом я тоже говорил, но с той стороны, что человек лучше что-то делает и быстрее принимает, когда понимает, что это даёт лично ему. Нужен контент о том, что кто-то уже поменялся, и получилось круто (пример есть - лучше принимают). Рассказывать, как конкретно должно измениться поведение человека, самому это понимать. Ведь сотрудники зададут этот вопрос. Метафора из выступления Грэхэма из MIT про молоко и корову (посмотреть ролик). Почему может не получаться. - первые лица не разделяют/ не понимают, зачем - трансформация - это про моду, а не про функции и изменение показателей (не отвечают на вопрос «зачем?» 🙂 - желание измениться очень быстро. По опыту консалтеров изменение пары небольших культурных моментов до 5 лет, в зависимости от численности компании - эмоции очень важны. Для трансформации нужны «легкие» люди - нужно не говорить, а делать. Иначе идея дискредитируется. Иначе может случиться ошибочное понимание, что изменения уже произошли. ================================================ FILE: content/devopsconf/19/fast-releases.md ================================================ --- title: "Как доставить быстро и без боли. Автоматизируем релизы" author: "Александр Коротков, ЦИАН" tags: ["DevOpsConf", "2019"] summary: | * Оптимизация Code Review * Оптимизация тестирования * Оптимизация тестовых (бета) стендов * Оптимизация деплоя * Мониторинг * Канареечное тестирование --- ## Проблемы в ЦИАН: - долгое и некачественное ревью - 1 релиз в день, но хотелось ускориться - конфликты между задачами - длительное ожиданиие релиза - полный откат всего релиза при наличии проблем - в среднем задачи доставляются за 10 дней ## Оптимизация Code Review ### Интеграция с системой контроля версий и трекером задач Для этого делаем несколько операций по автоматизации после перевода задачи в статус: поиск затронутых репозиторий, блокировние ветки от изменений, мёрдж мастер-ветки в фича-ветку, разворачивание на тестовое-окружение и прогон тестов. ### Ревьюеры Выбрали схему с 1 обязательным ревьюером, 1 ревьюером по выбору, а также 1 апрув от CI c проверками и тестами ## Оптимизация тестирования Для задач, которые не требуют ручного тестирования, задача сразу переходит к статусу на деплой. Для прочих задач был добавлен дополнительный статус в флоу задач, который автоматически назначал свободного и подходящего тестировщика для этой задачи. ## Оптимизация тестовых (бета) стендов Было принято решение разбить один бета-стенд на несколько бета-стендов для каждой из команд, каждый из которых обновляется вместе с веткой master, сохраняя таким образом синхронизацию. ## Оптимизация деплоя С помощью интеграции с трекером задач ищем блокирующие задачи, и закидываем задачу на деплой в специальную очередь, чтобы разные деплои не конкурировали друг с другом. ## Мониторинг В ЦИАН сложная архитектура роутинга запросов, поэтому запрос от пользователя идёт по одной схеме, а запросы между микросервисами по другой схеме. Поэтому прямой health check сложен и был выбран путь мониторинга: собираются системные метрики из prometheus, метрики приложения, пользовательские метрики из ELK. Для деплоя основной метрикой является количество 500 ошибок. ## Канареечное тестирование Разворачиваем небольшую часть и смотрим на метрики — если с метриками всё хорошо, то подтверждаем релиз и раскатываем весь релиз. ## Что вышло: - от 1 к 70 релизов в день - задача приходит в прод за два дня ================================================ FILE: content/devopsconf/19/werf.md ================================================ --- title: "werf — наш инструмент для CI/CD в Kubernetes" author: "Дмитрий Столяров, Тимофей Кириллов, Алексей Игрычев, Иван Михейкин, компания Флант" tags: ["DevOpsConf", "2019"] summary: | * Доставка * Сборка (build) * Публикация в registry (push) * Очистка registry * Деплой --- В первую очередь: сюда можно ставить звездочки [github.com/flant/werf](https://github.com/flant/werf) # Доставка Доклад про то, как делать доставку в K8s. Есть софт, его нужно доставить на продакшен. Есть цикл непрерывных улучшений. Разработка, тестирование, доставка, метрики, снова разработка... В нашем случае софт — это докер, а продакшен — это k8s. Пока в проде не было k8s, продакшен для докера был вообще непонятным. А когда появился k8s, продакшен стал стандартизованным и с API. Когда-то то же самое произошло с софтом: было как попало, стало в докере. Как выглядит доставка: * Есть гит с кодом приложения и кодом сборки, * мы собираем из этого докер-образ и пушим его в registry, * ещё в гите есть инструкции как выполнять приложение, мы их отправляем в k8s на тест и на прод. * И ещё там есть тесты, разные. * Наконец, есть CI-система, которая всё это выполняет. Immutable инфраструктура предполагает, что мы собираем образ, его тестируем и его же отправляем на прод. Ещё важно, что инфраструктура — это код. Как только мы это правило нарушаем, всё ломается. Что такое delivery? Это путь git -> build -> test -> release -> run. Продукт доставлен только тогда, когда пользователь смог им воспользоваться. У всей этой схемы на основе Git есть название: GitOps. Давайте посмотрим на эту схему подробнее. # Сборка (build) Вес образа имеет значение. Если идти прямым путём, то получится очень большой образ. А если использовать multistage, то гораздо меньше. ![werf01](../../../images/devopsconf/19/werf01.png) Ещё все знают, что много слоёв — это плохо, а хорошо делать так: ![werf02](../../../images/devopsconf/19/werf02.png) Однако, попробуйте-ка подебажить такую сборку. Где оно упало внутри этого шага? Никто не знает. Приходится вручную выполнять по одной строке. Ещё код приложения меняется часто, а зависимости редко. Поэтому приходится сначала добавлять `requirements.txt`, потом `pip install -r requirements.txt`, и только потом добавлять оставшийся код приложения. ![werf03](../../../images/devopsconf/19/werf03.png) Ещё нередко из одного репозитория мы можем собирать много образов. Мы можем сделать много докерфайлов или один докерфайл со stage'ами, и потом запускать сборку через shell-cкрипт. И всё это только вершина айсберга! * Есть ещё история с монтированием. * Например, мы хотим закешировать результат работы какого-то менеджера зависимостей. * Или мы хотим ssh и нам нужно пробросить сокет ssh-агента. * Или мы хотим собирать образы без shell, а хотим использовать Ansible. * Наконец, можно хотеть собирать образы вообще без Docker. Так нам для сборки понадобится виртуальная машина, но у нас же уже есть k8s. Однако, в нём докер, а в докере собирать докер-образы — это плохо. * Параллельная сборка. Тут параллельность можно понять кучей способов. * Распределенная сборка. Поды теряют кеши, с этим нужно что-то делать. * Автомагия! Чем решаются эти проблемы: * moby/buildkit * Kaniko * Buildpacks.io * buildah * genuinetools/img Параллельно развивается куча альтернативных сборщиков. Каждый из них решает часть задачи, а целиком — ни один. Werf делают пять лет. Сделанное отмечено синим, план к концу этого лета — жёлтым. ![werf04](../../../images/devopsconf/19/werf04.png) # Публикация в registry (push) Вопрос: как тегировать образ? Нужно гарантировать воспроизводимость. У нас есть коммит в гите, он иммутабельный. Мы хотим из него собрать образ и сохранить связь между ними. Когда на проде работает приложение, мы хотим узнавать, из какого коммита оно собрано. ## git tag Обычный путь такой: 1. Поставили тег в гите 2. Собрали образ и поставили тот же тег на него 3. Протестировали 4. Выкатили на прод Тут есть проблемы: * Порядок контринтуитивный. Мы сначала тегировали, а только потом тестируем. * Плохо сочетается с git flow. ## git commit + tag Собираем и тестируем образы из коммитов. Когда очередной коммит/образ прошёл все тесты и мы готовы выкатывать его на прод, ставим тег на уже собранный образ. Ограничение: только fast-forward merging, не поддерживает мерж-коммиты. ## Content addressable Берём хеши исходных докер-образов, текст всех команд и хеши скопированных файлов. Делаем из этого один хеш. Он становится сигнатурой образа. В список файлов можно не включать то, что не влияет на приложение, например changelog. Плюс: сигнатура не меняется от мерж-коммитов. Минус: нельзя точно восстановить, из какого коммита собран образ. Это решается слоем с метаданными. # Очистка registry Рано или поздно место в registry заканчивается. Если мы пушим новый образ с тем же тегом, какие-то слои устаревают, и registry с этим справляется. Но есть и тегированные образы, которые больше не нужны. Давайте будем их удалять. ![werf05](../../../images/devopsconf/19/werf05.png) Стратегии очистки: * Не чистить. * Сделать полный сброс. А после удаления нажать везде build. Но тогда мы создадим много новых непротестированных образов. * Blue-green. Непонятно, когда удалять старый. * По времени. Тут мы либо слишком долго храним, либо удалим что-то нужное. * Вручную. Работоспособные варианты — не чистить вообще, либо сочетать blue-green с ручной очисткой. Как эту задачу решает werf? 1. Git head: собираем все ветки. То, что протегировано в git, наверняка нужно в registry. 2. Что сейчас выкачено в k8s? 3. Что недавно было выкачено в k8s? 4. (в планах) анализируем Helm. Из всего этого получаем whitelist. Всё, что не в нём — удаляем из registry. Потом удаляем из кешей всё, на что не ссылаются существующие образы. # Деплой ## Изменение конфигураций Конфигурация для k8s лежит в гите. В момент деплоя конфиг становится сильно больше. В него добавляются: * идентификаторы, * служебная информация, * значения по умолчанию, * статус, * admission webhook'и, * контроллеры всех видов и планировщик. Получается, что в k8s находится некоторое живое проявление того, что было в гите. Вот у нас новый коммит с новым конфигом. Нельзя эту конфигурацию просто перезаписать. Нужно сделать дифф между старой и новой и его накатить как патч на боевую версию. Это называется «двухсторонний мерж» (2-way merge). Так работает, например, Helm. ![werf06](../../../images/devopsconf/19/werf06.png) Можно делать иначе: между старой и новой версией смотреть, что удалено, а между боевой и новой — что добавлено и изменено. ![werf07](../../../images/devopsconf/19/werf07.png) Вывод: декларативный подход не так прост. Даже с декларативным описанием есть магия. Но без декларативного подхода всё сильно хуже. ## Применено ≠ выкачено Представим, что у нас есть CI-система. Она получает ивент и запускает деплой: 1. Берёт шаблоны в YAML или JSON 1. Отдаёт их движку шаблонов 1. Получает отрендеренную конфигурацию 1. Применяет к ней изменения из боевой конфигурации k8s через 3-way merge. 1. Применяет результат обратно к k8s через API 1. K8s отвечает успехом CI-системе, а она отвечает пользователю. Применена новая конфигурация? Да. Выкачена? Нет. ![werf08](../../../images/devopsconf/19/werf08.png) K8s отвечает OK, когда получил новую конфигурацию. Но применяется она не моментально. Так работают Helm и kubectl. А если pod не сможет рестартануть с новой конфигурацией? «Пуля вылетела, проблемы на вашей стороне». ![werf09](../../../images/devopsconf/19/werf09.png) Поэтому нужен трекер, который следит за состоянием k8s. Если k8s ответил OK, CI будет ждать трекера, который вернёт ОК только когда конфигурация успешно задеплоилась. Подходящий инструмент — библиотека [github.com/flant/kubedog](https://github.com/flant/kubedog). Этот трекер встроен в werf. Главная аннотация — `fail-mode`. Три варианта: * IgnoreAndContinueDeployProcess. Забей и продолжай деплой. * FailWholeDeployProcessImmediately. Падай сразу. * HopeUntilEndOfDeployProcess. Жди и надейся. Ещё важная аннотация: `failures-allowed-per-replica`. Логи: `show-logs-until`. Помогает собирать логи только до тех пор, когда pod готов. Ошибки происходят до того, как он готов, и ошибки нам интересны. А на готовый pod приходят задачи и в логах появляется куча шума, она нам неинтересна. ## Что мы вообще хотим от деплоя? * Надёжную декларативность. * Реальный статус. * Логи. * Прогресс. (Job висит — что происходит? Чего мы сейчас ждём?) * Автоматический откат. Выкат должен быть атомарным: или оно выкатилось до конца, или откатилось назад. # Заключение Всё сложнее, чем кажется с первого взгляда. Дьявол кроется в деталях. Любой софт — сырое и глючное гавно, пока им не начнут пользоваться. Давайте вместе добьём эту тему, и пойдём дальше, решать другие вопросы. ================================================ FILE: content/devrelconf/5/brand-ambassador.md ================================================ --- title: "Как готовить начинающих спикеров, чтобы они превратились в опытных бренд-амбассадоров" author: "Евгения Голева, Lamoda" tags: ["DevRelConf", "2019"] summary: | --- # Результаты: - за три года узнаваемость компании повысилась с 5 до 75 процентов у приходящих людей # Зачем создавать бренд? Жизненный цикл "докладчика": - приходит в компанию и около года въезжает в работу - полгода делает крутые штуки, про которые можно рассказат - остаётся полгода-год до того как он уйдёт, и в это время его очень важно отправить на конференцию с докладом, чтобы он привёл новых людей! Зачем нужно развивать бренд? - чтобы рассказывать на собеседовании не про компанию и отсеивать тех, кому она не подходит заранее - сотрудники внутри компании хотят гордиться своей компания - все хотят знать что происходит внутри Перед тем как крутить бренд, нужно понять кто мы такие и в чём заключается этот бренд. Не нужно самообольщаться и врать себе. # Как создавать бренд? Инженерам не нравится выступать, они всегда придумают оправдания: не умеют, не хотят, все уже всё знают. Можно и нужно начинать не с большим конференций, а с внутренних докладов и митапов. Важно это делать регулярно и тренироваться в публичном выступлении Во внутренних миитапах важно зафиксировать правила: - иметь возможность выступать безопасно (комфортное ощущение, аккуратный фидбек) - иметь возможность делать ошибки - иметь возможность экспериментировать Можно начать с митапов без слайдов, пяти-минутные доклады и обязательная ретроспектива: конкретная (факты, цитаты), положительная (что было хорошо), развивающий (что можно усилить?) После внутренних митапов можно идти на внешние, а после и на большие конференции: это будет уже не страшно Токсичность — большинство начинающих спикеров как только получают понимание выступлений, начинают закидывать помидорами других докладчиков. Важно строго стремиться к правилам и постоянно следить за культурой взаимодействия и общения. Будет отлично, если во время тренировки на внутренних и внешних митапах у человека будет идея для доклада, и он будет его прорабатывать. Поощряйте людей, работающих на развитие бренда: - логируйте время на доклады как рабочее время, если вы логируете время по рабочим задачам - выдавайте бонусы тем, кто молодец - хвалите тех, кто умница # Культура выступать - Люди внутри начали узнавать друг друга, повысилась культура обратной связи и регулярных публичных выступлений - Онбординг после устройства позволил рассказать ключевые детали о компании, которые человек сможет использовать в разговоре с внешними людьми - Публичные каналы с постоянными новостями о выступлениях дали людям "раскрыться" — коллеги начали проявлять иниициативу в выступлениях и статьях # Как строить бренд - выбирать бренд осознанно и понимать зачем его развивать, ради кого; - создавать команду, вдохновлять её, развивать, доверять; - менять продукт и компанию изнутри, формировать культуру ================================================ FILE: content/devrelconf/5/ghostwriters.md ================================================ --- title: "Профессия «Ghostwriter», или Учим программистов писать статьи" author: "Мария Круглова, KODE" tags: ["DevRelConf", "2019"] summary: | --- Мария — PR-менеджер в KODE и лидер GDG в Калининграде. Специфика компании: * Разработка на аутсорс * В регионе * Сотрудники молодые * Системы обучения нет * 1 сотрудник решает все задачи с обучением Руководство: > Хотим статьи разработчиков на Хабре и VC, чтобы нас читали, комментировали и хвалили. И поэтому чтобы к нам шли работать. У топов получается — значит и у нас сработает. Что с этим делать? Да хоть что-нибудь. ## План номер 1: Я напишу сама! Внезапно: * Разработчики редко умеют и любят писать. * Время разработчиков дорогое. * А пиарщику трудно написать статью на техническую тему. В процессе: * 6 месяцев попыток * Страх пустой страницы * Синдром самозванца Плюсы: * Сам себе планировщик. Своё время распланировать проще, не надо договариваться про время разработчика. * Пиарщик пишет грамотнее, чем программист. Минусы: * Нет эксперта или ментора. * Тексты получаются поверхностные. ## План номер 2: интервью В качестве подготовки провели несколько лекций о том, зачем миру и компании нужны технические статьи. Вместе нагенерили темы статей. Идеальный процесс в голове выглядел так: 1. Интервью 1. Редактирование 1. Вычитка 1. Рецензирование 1. Публикация А в реальности так: * Вопросы быстро заканчиваются * Разработчик даёт очень короткие и сжатые ответы * В ответах много терминов и сложных технических подробностей. * Плюс: на первое интервью тратим минимум времени разработчика * Плюс: сразу много материала * Минус: нет четкой структуры интервью, непонятно о чём спрашивать * Минус: разработчики разговаривают на жаргоне и техническом английском, их сложно понять не-разработчику. ## План номер три: пишут программисты Собрали всех заинтересованных в написании статей, объяснили им план. План был такой: Идея -> Драфт -> Статья -> В релиз! Прошло ещё 6 месяцев, не сработало. Похоже, что не получилось до каждого сотрудника донести процедуру. А сотрудникам не хватает команды в написании статьи. Добавили в схему детали: * Прежде чем писать драфт, можно обсудить тему с пиарщиком и провести исследование. * Когда драфт написан, дальше обсуждаем его с пиарщиком и командой. * Когда статья готова, пиарщик её вычитывает и редактирует. * И когда статья опубликована, пиарщик будет её пиарить! ![ghostwriters01](../../../images/darvelconf/5/ghostwriters01.png) Прошло ещё 6 месяцев, выпустили первую статью. ## План номер четыре: ghostwriter Определение от Марии Кругловой: Ghostwriter — человек, влияющий на создание статьи с момента зарождения идеи, в течение всего процесса её написания и защиты, активный модератор статьи, корректор и психолог. Задача — сформировать у разработчика уверенность, что статью написал именно он. Процесс 1. Ищем автора. Вот признаки, что человек может: * человек выступал на внутреннем девклубе, * читал лекцию на стажировках или курсах, * вёл практические занятия, * выступал на конференциях или митапах, * или просто обсуждал что-то в курилке. 2. Создаём основу статьи. Берём что угодно, что осталось от первого опыта: * презентацию от доклада, * инструкции во внутренней доке, * конспект для себя перед лекцией, * видеозапись выступления; * с конференций куча материалов остаётся. 1. Обрабатываем основу: * Проверяем «на bullshit»: насколько это уникально и что нового автор открыл миру. * Наполняем словом. (Сейчас этот этап чаще делает пиарщик.) * Делаем авторский стиль. * Добавляем комментарии. В тех местах, где ghostwriter'y непонятно, уточняем подробности. 1. Смотри, какую статью ты написал! * Проверям, что восприятие в статье верное. * Дополняем и работаем с комментариями. * Подключаем техлида к ревью (впервые в этом процессе). Техлид даёт верные комментарии. * Добавляем лоска тексту. 1. В продакшен * Публикуем статью * Автор в течение нескольких дней отвечает на комментарии * Автор сам публикует куда-нибудь ссылки на свою статью, тренирует способность делиться и самопиариться. 1. Через несколько недель после статьи предлагаем написать ещё. # Результаты * Повышаем уверенность сотрудников в себе. * Показываем сотрудникам основные ошибки в тексте. * Убираем синдром самозванца * Выпускаем статьи, на это есть KPI * Иногда разработчики сами приходят. # Как наладить бесперебойный процесс производства статей Обучение: * Лекции в отделах * Тренинги по написанию статей * Проверяем идеи статей на жизнеспособность * Личные встречи с разработчиками. Мотивация — штука сложная и спорная. Что сделать, чтобы была мотивация? * Статья включается в KPI сотрудника. Выделяем процентов 20 рабочего времени на написание статьи. * Те, кто пишут статьи, перыми едут на конференцию. * Людей мотивирует отклик аудитории и клиентов. Из приятного: заработало сарафанное радио. Люди на собеседованиях вспоминают, что в этой компании ещё и статьи пишут. А ещё все удивляются, что в Калининграде не только военные и корабли есть. # Итоговый процесс выглядит так: ![ghostwriters02](../../../images/darvelconf/5/ghostwriters02.png) # Правила ghostwriter'а * благодарить автора за труд и отмечать интересные моменты статьи; * обращаться к нему за советом, а не говорить об ошибках; * указывать авторство, если статья написана в общем блоге компании; * рассказывать о каждой статье везде; * себя тоже благодарить, чтобы не выгорать. # Давайте делиться У Марии есть: * Чек-лист хорошего текста * FAQ «Хочу написать статью» * Практикум «Как написать хороший текст» * Презентация «Публичный разработчик» Пишите в телеграм [mkruglova](https://t.me/mkruglova). ================================================ FILE: content/devrelconf/5/technical-authors.md ================================================ --- title: "Пишем не только код, но и статьи: как помочь разработчику стать техноавтором" author: "Антонина Татчук, Авито" tags: ["DevRelConf", "2019"] summary: | --- # Нужен ли вам техноблог? > Мы напишем и все придут к нам работать. Нет. > Начальник: «Нам нужен блог» Нет. > Мы будем продавать продукт через блог. Вряд ли. > Это же почти бесплатно. Нет, это очень дорого. # Какие задачи решает техноблог: * Отвечает на обычные вопросы о компании и технологиях * Дает площадку для экспертов * Генерирует контент для других каналов * Работает как публичная энциклопедия Однако: * Время разработчика стоит дорого * Профессиональные писатель не завалит дедлайн * Профессиональный писатель лучше пишет * Фрилансер будет прислушиваться к маркетологу Почему всё-таки вовлекаем разработчиков? * Цель — повышать узнаваемость Авито среди разработчиков * Говорим и пишем именно про свои технологии * Поэтому можем писать только сами. В компании есть два блога, в них 157 статей от 53 авторов, суммарно 1,3 млн просмотров. Ресурсы * Рабочее время разработчиков * Редактор внутри техдепа * Бюджет * на площадки * на спецпроекты * на нематериальную мотивацию авторов * на дистрибуцию * И всё, что ещё покажется разумным. Зачем это разработчикам? 0. Потому что могут 0. Развивают личный бренд и качают писательские скиллы 0. Помогают нанимать близких по духу коллег. Блоги влияют на найм, хоть и косвенно. 92% видели блог, у 69% это повлияло на решение, одного разработчика блог нанял напрямую. 0. Делятся опытом с российским и международным сообществом. Круто, когда тебя цитируют в подкасте от Гугла. # Как помочь авторам Фасилитируем всё, что можем. ## Работа с темой Хорошо, когда тема уже есть, но обычно нет. Можем помочь автору: * отыскать и сформулировать тему * подготовить фактуру * проверить идею на коллегах * докрутить идею, добавив полезных подробностей * найти соавтора Редактор может и сам предложить тему. Для этого: * читаем чаты разработчиков * мониторим обновления сайта и приложений * следим за «днями рождения» инструментов * смотрим за конференциями ## Работа с автором Понадобится много эмпатии * не давить дедлайнами * быть готовым подстроиться под график * понимать, когда стоит повторить опыт * быть готовым отказаться от публикации Как жить в мире, где нельзя заставить разработчика писать? Делайте редакторские заготовки сами! У контента три возможных функции: * полезен для читателя, * развлекательный, * или побуждает к общению. ## Работа с текстом Человеку проще писать, если он знает, что: * редактор вычитает этот текст и исправит ошибки, * в тексте будет драматургия и последовательность изложения (?), * коллеги готовы помочь с технической частью, * текст проверят на NDA и можно не бояться сболтнуть лишнего, * дизайнер нарисует иллюстрации, * и потом кто-то красиво сверстает текст. Главное — что команда поддержит, все придут поддержать в комментариях и поставят плюсики. ## Дистрибуция контента Важно не только написать, но и распространить текст. ## Писать за автора не надо Это плохо и грустно. ## Редактор отвечает за всё * перевод * опечатки * верстка * выбор темы Автор не должен тратить на это своё время. ## Ещё раз о мотивации * Сначала убеждаемся, что у человека всё хорошо в жизни. * Фасилитируем. * Для мотивации не нужны айпады и другие дорогие призы. * Однако это влияет на премию. * Есть сувениры, которые можно получить только так. ## Запуск техноблога Таймлайн * До трёх месяцев займет подготовка контент-плана * Первые значимые результаты будут через полгода * Через год можно будет даже в отпуск уйти Важно: * Помните о цели блога. * Рассчитывайте ресурсы, особенно собственные * Делайте людям проще. Помогайте эмпатией и дистрибуцией контента. ================================================ FILE: content/frontendconf/19/promoting-opensource.md ================================================ --- title: "Продвижение опенсорс-проектов (+1 секретный доклад внутри)" author: "Андрей Ситник, Злые Марсиане" tags: ["FrontendConf", "2019", "Evil Martians"] summary: "" --- Однажды появилась методология БЭМ. Она была реально прорывной. Однако, о ней до сих пор не весь мир знает. И есть ещё много крутых вещей, которые созданы в России и мало известны миру. Это проблема, давайте её решать. Андей занимается фронтендом в компании Evil Martians. А ещё у него есть opensource-проекты, вот такие: > ![promoting-opensource01](../../../images/frontendconf/19/opensource01.png) На самом деле проектов было немного больше: > ![promoting-opensource02](../../../images/frontendconf/19/opensource02.png) ## Реальность * Стать популярным через опенсорс — плохой способ. Гораздо полезнее писать статьи и выступать на конференциях. * Отличный проект не обязательно получит звездочки. Более эффективно будет вложить усилия в небольшой PR в популярный проект: исправить документацию или починить баг. * Хороший смысл заниматься опенсорсом — изменить мир. Доклады и статьи вдохновляют, но ничего не меняют. А код — меняет. Например, Autoprefixer вытеснил Compass. Вот анонс Autoprefixer. Основная ошибка — нет английского языка.

Сделал Autoprefixer — он парсит ваш CSS (или Sass) и по базе с Can I Use добавляет нужные (и только нужные) префиксы https://t.co/2N4JICHhDq

— Андрей Ситник (@andrey_sitnik) April 9, 2013
## Формула успеха проекта Популярность проекта = ваша популярность + продвижение + преимущества для пользователей + удача. Популярность проекта зависит от вашей, а ваша — от популярности проекта. Создайте англоязычный твиттер! Старый проект набирает подписчиков, их можно использовать для Неважно, как пользователь узнает о вашем проекте. Рано или поздно ему потребуется документация. Когда и как люди читают документацию. Спокойно и с чашечкой кофе? Нет! Они в огне, у них нет времени и сил. Объясните, зачем людям читать вашу документацию, иначе они не будут читать. Плохо: > :x: Svelte is cybernetically enhanced web apps Хорошо: > :heavy_check_mark: Svelte is JS framework with unique compiler which generates smaller JS files Конкретнее: 1. Точное описание 1. Чем это полезно 1. Почему это важно Начало README — самый важный текст. Потратьте на его написание много времени и сделайте хорошо. Как сделать хорошее описание? Представьте, что вы в баре объясняете друзьям, что у вас за проект. Теперь сделайте описание лаконичным, сократите до 2-4 предложений. Люди читают не весь текст. Примерно вот столько: > ![promoting-opensource03](../../../images/frontendconf/19/opensource03.png) Что с этим делать? * **Добавляйте иллюстрации** и примеры кода. * **Выделяйте главное** в начале пункта списка. ## Как люди выбирают фреймворки? Кажется, что они делают этот выбор рационально. На самом деле нет. Люди выбирают то, про что говорят лидеры мнений. Важно писать, кто использует проект. Чтобы кто-то его использовать, можно прийти в любой проект и предложить заменить зависимость. После первого проекта становится проще: «а Х уже перешли на наш инструмент». Раз в месяц нужно что-то писать и говорить о проекте. Статьи, доклады, твиттер. Получается, что всё держится на хайпе, и чтобы конкурировать, нужно только подливать масла в огонь хайпа. Всё это грустно. Поэтому доклад закончился и теперь будет другой доклад. --- # Как мы убиваем инновации во фронтенде Андрей Ситник, Злые Марсиане Однажды Испания профинансировала стартап Колумба и он открыл Америку. Это произошло по ошибке. В Америке испанцы нашли серебро, обогатились на нём, но всё потратили на войны и прочую ерунду. В развитии технологии есть три стадии: 1. В проект никто не верит 1. Бурный рост 1. Инновации останавливаются ## Фронтенд умер Фронтенд сейчас в третьей стадии. Мы богаты и пьём смузи, это ок. Но мы на этом богатстве развиваем стагнацию. Например, выбираем проекты по количеству звездочек и скачиваний. Звёздочки не гарантируют поддержки. Например, * CSS Modules популярно, но не поддерживается. * Люди гордятся использованием React, хотя во множестве кейсов есть решения на порядок проще и лучше. Распределение подписчиков в Twitter аномальное. У 1% людей есть 99% подписчиков. В результате один человек решает, о чём узнает вся отрасль. Получается, что социальные лифты сломаны и новым лидерам сложно появиться. Популярность приносит ещё большую популярность. Вместо того, чтобы сломать этот замкнутый круг, мы его поддерживаем. ## Да здравствует фронтенд! Что с этим всем делать? 1. Выбирайте правильно Как НЕ НУЖНО выбирать инструменты и зависимости для фронтенда: * по звёздочкам * потому что хайп * потому что используется в компании Х * потому что лидер мнений рекомендовал Как выбирать инструменты и зависимости для фронтенда: * поискать на npm * сравнить размеры: bundlephobia.com * сделать свои бенчмарки * сколько issues без ответа? * сделать маленькое демо 2. Большой проект не означает, что вам быстро ответят и помогут. Это зависит от мейнтейнера и ещё кучи вещей. А ещё фреймворки на самом деле не очень важны для бизнеса. Специализированные инструменты обычно лучше, чем универсальные. Ищите специализированный инструмент под задачу. 3. Продвигайте непопулярных разработчиков. Андрей проводит черту на 7000 подписчиков: меньше — ретвитить почаще, больше — ретвитить реже. 4. Не ограничивайтесь только математикой и computer science. На стыках с другими областями появляется новое. 5. Постарайтесь увидеть большую картину. Например, метрики — не серебряная пуля. Они не помогут сделать качественный скачок. 6. Наконец, не бойтесь. Фронтенд не первый, где закончились инновации. Чтобы появилось новое — не бойтесь, рискуйте и танцуйте на столах. ================================================ FILE: content/frontendconf/19/style_silver_bullet.md ================================================ --- title: "В поисках Стилевого Грааля" author: "Артур Кенжаев, Яндекс.Маркет" tags: ["FrontendConf", "2019"] summary: "" --- ## Прошлое На заре интернета стили страницы считались статичными и декларативными, и начали появляться решения для подобной стилизации: - tags: abc - JSSS: tags.H1.color - CSS Expressions: expression(a+b) - CSS! У CSS есть множество проблем: отсутствие реиспользования, неявность, неинтерактивность, сложность чтения. Потом начали появляться решения, которые пытались пофиксить CSS -- например, БЭМ, который вводил новые сущности и абстракции, упрощающие стилизацию приложения. А потом bootstrap, shadow dom, webpack, component, css modules, ... И проснулось дублирование! ```html ``` Хотя PostCSS и CSS Modules закрыли большинство вопросов, но остались вопросы: - сборка - семавнтика - порого вхождения - темизация - tree shaking - runtime стили - универсальность ## CSS-in-JS И появился Styled Components, решающий кучу проблем: - специфичность - сборка - семантика - порог вхождения - темизация **А есть недостатки?** Есть! - Производительность, на больших компонентах это тормозит - Можно (легко) написать отвратительный код - Комбинаторика злая: 4 состояния по 3 значения и у нас гигантский блок кода с дублированием - Извлечение статических стилей сложно и ненативно - Язык императивен и if-ами писать около-декларативную вещь сложно - Отсутствие контроля над внешним интерфейсом - Отсутствия контроля над внутренним интерфейсом — непонятно как отделить пропсы от HTML аттрибутов - Смешивание глобальных классов, styled components и всего остального В итоге, решая проблемы мы делаем новые проблемы и попадаем в новый замкнутый цикл проблем. Время посмотреть в прошлое и понять что было придумано раньше. ## shadow dom и высокоуровневые абстракции Одно из решений — reshadow, позволяет семантически абстрагироваться от HTML и стилей, и писать на высокоуровневые тегах, используя shadow dom и не думая о конкретных тегах и селекторах. Из-за особенностей рендеринга с reshadow (использование модфикаторов и css variables в корневых тегах компонентов), есть возможность вынести стили в отдельный файл. Как менять стили компонентов? - модификация компонентов (изменение компонентов) - темизация (декларативное определение различных тем) - стилизация (прямая передача набора стилей) Т.к. reshadow позволяет вынести стили в пропсы компонента, то можно использовать стилизацию как интерфейс к компоненту и получить все преимущества этого подхода. ## Плюшки от reshadow - вынос динамических вещей и экспериментов в чанки; - core-компоненты не имеют прямых зависимиостей от других компонентов, не используют контекст; - в контексте могут быть не только стили, но и любые значения; - есть возможность переопределения render и lifecycle; - производительность (из-за обработки стилей во время сборки); - на выходе получается обычный HTML и CSS, который можно читать; - возможность построить маппинг всех стилей и состояний; - можно использовать вместе с PostCSS; - фреймворк-агностик; ================================================ FILE: content/highload/18/1.1-microservices.md ================================================ --- title: "Что мы знаем о микросервисах" author: "Вадим Мадисон, Avito" tags: ["Highload", "2018", "Avito"] summary: | Авито: много сервисов и очень много связей между ними. Вот основные проблемы от количества: * Много разных репозиториев. Сложно менять код одновременно везде. * Много команд пишут код, не пересекаясь с другими. Знания инкапсулируются и плохо передаются между командами. Нет единой картины. Нет человека, который бы всё знал. * Данные фрагментарны. --- # Intro Авито: много сервисов и очень много связей между ними. Вот основные проблемы от количества: * Много разных репозиториев. Сложно менять код одновременно везде. * Много команд пишут код, не пересекаясь с другими. Знания инкапсулируются и плохо передаются между командами. Нет единой картины. Нет человека, который бы всё знал. * Данные фрагментарны. Проблемы с инфраструктурой: слишком много элементов: * Логирование * Мониторинг * Сборка * Общение * Трекер задач * Документация * Аааааа Слои: service mesh, k8s, bare metal. Отдельно мониторинг и PaaS. Доклад будет как раз про него. В платформе есть три основных части: * Генераторы, управляются через CLI * Агрегатор (коллектор), управляется через дашборд * Хранилище (storage) с триггерами на определённые действия. # Стандартный конвейер разработки микросервиса ## CLI-push Создаём сервис из шаблона. Вместо первого `git push`. Долго учили разработчиков правильно начинать работу, но это всё равно становится узким местом при внедрении микросервисов. Поэтому сделали утилиту в помощь разработчикам. Утилита делает вот что: 1. Создаёт сервис из шаблона. 1. Разворачивает инфраструктуру для локальной разработки 1. Подключает БД одной командой без конфигов. Раньше деплой сервиса был сложный и составной. Сделали проще: один файл `app.toml`. Базовая валидация: * Есть докерфайл * Есть `app.toml` * Есть документация * Зависимости в порядке * УКазаны правила алертов для мониторинга. Владелец сервиса сам это настраивает. ## Документация Входит: * Описание сервиса. В двух предложениях, что сервис делает. * Диаграмма архитектуры. * Runbook. * FAQ * Описание API endpoints * Labels — к какому продукту, функциональности и структурному подразделению относится сервис. * Владельцы. Обычно определяем автоматически, но на всякий случай надо. * Ревью? ## Подготовка пайплайна * Готовим репозитории * Делаем пайплайн в Teamcity * Выставляем права * Ищем владельцев — вычисляем по push'ам в репозиторий. * Одного недостаточно, ненадёжно. Ищем двух. * Считаем количество пушей и количество кода в пуше. * Регистрируем сервис в Atlas * Проверяем миграции. Если они потенциально опасны, инфу в Атлас, а сервис в карантин. ## Дальше * Собираем приложение в докер-образ * Генерируем хелмчарты для сервиса и его ресурсов * Создаем админские тикеты на открытие портов * Юнит-тесты, считаем покрытие кода. Результаты — в Атлас. * Считаем ограничения по памяти и процессору. Go + k8s + GOMAXPROCS — придётся оптимизировать производительность. Поможет библиотека [automaxprocs](https://github.com/uber-go/automaxprocs). ## Проверка Вот что проверяем: * API endpoints * Их ответы соответствуют схеме * Формат логов * Выставление заголовков при запросах * Выставление заголовков при отправке сообщений в шину. Тут проверяется связность сервисов. ## Тесты * Тестируем в закрытом контуре, например hoverfly.io. * Нагрузочное тестирование — важно. Нагрузочное тестирование показывает дельту производительности между версиями. Проверяем, что потребление соответствует заданным ограничениям. * Слишком мало — OOM killer? * Слишком много — оптимизировать. ## Canary tests Начинаем с очень малого процента — меньше 0,1%. Держим от 5 минут до 2 часов. Смотрим: * Метрики, специфичные для языка. Например, воркеры php-fpm. * Ошибки в Sentry * Статусы ответов * Время ответов — точное и среднее * Latency * Исключения обработанные и необработанные * Продуктовые метрики, внезапно, тысячи их! ## Squeeze testing Тестирование через выдавливание. Нагружаем реальными пользователями один инстанс, пока он не нагрузится на 100%, «в полку». Потом добавляем +1, снова смотрим полку, вычисляем дельту. Сравниваем эти данные с данными от искусственной нагрузки. ## Прод Мониторим на продакшене. Смотреть только на CPU — неэффективно, потому что соседи фонят. Поэтому смотрим на специфические для приложения метрики. Результаты — в Атлас. Итого: * CPU + RAM * количество запросов в очереди * время ответа * ? ## Что ещё * Миграции, если не осталось версий сервиса ниже Х * Обновления безопасности * Если сервис давно не обновлялся — пересобрать для проверки * Если метрики выходят из нормы — в карантин ## Дашборд Смотрим на всё сверху в агрегированном виде и делаем выводы. ================================================ FILE: content/highload/18/1.10-neural-nets-cgi.md ================================================ --- title: "Как нейронные сети графике помогали" author: "Евгений Туманов (NVIDIA)" tags: ["Highload", "2018"] summary: | Если у вас есть вычислительно сложная задача, которую вы решаете некоторым классическим вычислительным способом, попробуйте найти в этой задаче самое времязатратное место и найти решение с помощью нейронной сети или любого другого алгоритма машинного обучения. --- ### Обзор ML/DL-задач в графике Учителем выступает что-то “свыше” – либо из реальной жизни, либо что-то нарендеренное из движка: * Создание правдоподобных анимаций * Постобработка отрендеренных изображений * Интерполяция кадров * Генерация материалов Учителем выступает какой-то алгоритм из вычислительной математики: * Рендеринг сложных объектов: например, облаков * Физические симуляции ### Главная идея Если у вас есть вычислительно сложная задача, которую вы решаете некоторым классическим вычислительным способом, попробуйте найти в этой задаче самое времязатратное место и найти решение с помощью нейронной сети или любого другого алгоритма машинного обучения. \- *общий рецепт как еще можно найти применение для машинного обучения* ### Постановка проблемы Нужно нарисовать физически корректно облако, которое представлено как плотность капелек жидкости в пространстве. ![1-problem](../../../images/neural-nets-cgi/1-problem.png) Физически сложный объект: * Не твердый объект, нельзя наложить текстуру и рендерить * Капельки воды почти не поглощают свет * Они его переотражают, делают это анизотропно Рендеринг облака может занимать много часов, дни. Художнику хочется как можно быстрее получать ответ (отрендеренное облако), чтобы иметь возможность экспериментировать с освещением сцены, топологией облака и т.п. Нужно ускорить. ### Классическое решение Сложное уравнение: ![classic-solution](../../../images/neural-nets-cgi/2-classic-solution.png) Второй терм уравнения – прямое освещение (Direct Light). Свет, который приходит от солнца, попадает на точку выхода, по вектору, который выпущен из камеры, приходит в камеру, при этом он как-то затухает, т.е. интенсивность теряется. Первый терм – интегрирование по отрезку луча, проходящего внутри облака – опосредованное освещение (Indirect Light). Моделирует переотражение каплями света внутри облака. Интеграл I1 – это интеграл по сфере, которая окружает точку на луче. В классическом алгоритме считается с помощью Монте-Карло интегрирования. Это самая долгая часть во всем алгоритме и самая сложная. ### Рецепт для ML алгоритма Самое тяжелое – посчитать Монте-Карло оценку. Она дает какое-то число, которое обозначает опосредованное освещение в точке. ![ml-receipt](../../../images/neural-nets-cgi/3-ml-receipt.png) Будем предсказывать Монте-Карло оценку освещения в точке – выход для ML алгоритма. Вход: * Топология плотности вокруг точки * Направление на источник * Направление на камеру (так как капли переотражают свет не изотропно) ### Обучение Нужно сконструировать вход в нейронную сеть. Первое – описать локальную плотность. Вокруг точки на отрезке луча возьмем трехмерную сетку с шагом равным длине свободного пробега в облаке. В узлах сетки – плотность облака. Увеличим шаг между узлами сетки в два раза, возьмем новую сетку, измерим плотности в её узлах. Так сделаем несколько раз. В результате этой процедуры имеем несколько сеток, охватывающих все большую и большую окрестность вокруг точки. Такое представление оправдано, потому что мы хотим максимально подробно описывать маленькую область, и чем мы дальше от точки тем менее подробное мы хотим описание. ![learning](../../../images/neural-nets-cgi/4-learning.png) Обучать будем так: нагенерим разных облаков, будем применять классический алгоритм, записывать что он получает как ответы Монте-Карло интегрирования и фичи, на которых эти ответы были получены. Получили датасет, на котором можно обучаться. ### Архитектура сети Не является ключевой в этой задаче. Каждая сетка попадает в блок из двух fully-connected слоев. ![neural-net-architecture](../../../images/neural-nets-cgi/5-neural-net-architecture.png) ### Результаты Повышение скорости рендеринга в несколько сотен раз. Реализация: * Инструмент для рендеринга произвольных сцен, в которых есть облака * Облако задается кубом в интерфейсе Blender ![results](../../../images/neural-nets-cgi/6-results.png) ================================================ FILE: content/highload/18/1.2-per-aspera-ad-paas.md ================================================ --- title: "Тернии контейнеризированных приложений и микросервисов" author: "Иван Круглов, Booking.com" tags: ["Highload", "2018"] summary: | Бизнес хочет ускорить time to market. Есть роли серверов — server role. Новый продукт — новая роль. Надо писать puppet, открывать доступы и порты, конфигурировать-конфигурировать-конфигурироовать. ВРУЧНУЮ. Это умеет горстка людей — это узкое звено. Они делают это дни или недели, это тоже. Хотим: доступно всем, работает за минуты. Для решения стали строить PaaS. --- # Проблема Бизнес хочет ускорить time to market. Есть роли серверов — server role. Новый продукт — новая роль. Надо писать puppet, открывать доступы и порты, конфигурировать-конфигурировать-конфигурироовать. ВРУЧНУЮ. Это умеет горстка людей — это узкое звено. Они делают это дни или недели, это тоже. Хотим: доступно всем, работает за минуты. Для решения стали строить PaaS. # Первые попытки решения Пробовали: * marathon * openshift * k8s Первые две платформы профакапили, последнюю наполовину. О том и речь в докладе. ## Marathon Начался как хакатон, но так и не закончился. Не хватило фич. Мысль 1: не стоит недооценивать способность кода выживать. ## Openshift Случилась эйфория: * Там же k8s, а его разработал Google * Там же есть Ansible, а это круто. * И ещё Open vSwitch, который должен был порешать все проблемы. Раз фичи есть, хотелось их использовать, просто потому что они клёвые. А потом эйфория закончилась. Началось непонятное поведение системы. А ещё не было нормального мониторинга, алертов и лимитов. Разработчик опечатался и заиспользовал 100500 ресурсов платформы. Мысль 2: Cool vs. boring. Три крупных сложных системы вместе — круто, но нереально. Лучше скучно, но работает, чем интересно, но не работает. ### Проблема с деплоем От платформы хотели простой и удобный интерфейс. Как Heroku. В результате: пользователей научили нажимать кнопку, а внутренности скрыли. При проблемах нужно идти и дебажить людям их приложения. Нет времени на развитие платформы. Мысль 3: стоит сформулировать ожидание пользователей от системы и системы от пользователей. Пользователям нужны хотя бы базовые знания о том, как платформа устроена внутри. ### Проблема с интеграциями Новые приложения должны работать со старой системой. Точки интеграции: * DLB (distributed load balancing) * service discovery * events * storage * DB: MySQL, Cassandra, Redis, Kafka * SSL certivicates, identity key management * Secrets Секреты в k8s: * Не шифруются в etcd (появилось в 1.7 alpha) * Есть Vault, который пришлось форкнуть и дописывать. Сложный, но безопасный workflow. Мысль 4: k8s — клёво, но его интеграция в существующую экосистему компании важнее. ## Результат двух первых попыток внедрения * Устали * Задолбались * Потеряли доверие пользователей * Но был план! ## План! * Минимум клёвых штук. Отказ от Ansible и Open vSwitch. * Мониторинг инфраструктуры. Сами сообщаем, что у нас проблемы. * Выстроили чёткие ожидания внутри команды, между командой и пользователями: > Если вы хотите использовать платформу, вы должны 1) иметь базовые знания о k8s, 2) обеспечить свой сервис поддержкой. и ещё ожидания с провайдерами интеграций. * Инвестиции в знания. * тренинги * онлайн-курсы * книги * документация С этими идеями пришли к третьему шагу: внедрять чистый k8s. # kubernetes (Пока что) не профакапленная платформа. Сделали несколько кластеров — застраховались сами от себя. Если положат один, то только один, а не всю систему. Архитектура: ![booking-k8s-arch](../../../images/booking-k8s-arch.png) ## Directly Routable Pods Цель — плоская и простая сеть. Каждой ноде назначен /27, маленькая подсеть. Каждый под получает адрес, как любой физический сервер — `10.*`. Между подами и другими хостами во внутренней сети — прямой доступ. Поэтому не нужен ingress. Поощряем использование Pod IP-адреса. Экспортируем в Service Discovery и почти в DLB. service.namespace.svc.cluster.local service.namespace.svc.eu-nl-prod-a.booking.com ## Тестирование kube-probe — функциональное тестирование для k8s. Проверяет способность кластера выполнять: * базовые функции * сетевое соединение * интеграции # Результаты и достижения * Есть стабильная система * ~200 уникальных сервисов, количество растёт * Понимаем происходящее * Отладили взаимодействие * Вся система самообслуживается * Выстроили отлаженную систему обучения # Заключение: * Управление ожиданиями — ключ к успеху. * k8s хорош, но интеграция важнее. * k8s — это экосистема, он требует понимания даже со стороны пользователей. * важно вкладываться в обучение. ================================================ FILE: content/highload/18/1.3-data-discovery.md ================================================ --- title: "Один из вариантов реализации Data Discovery в микросервисной архитектуре" author: "Николай Голов, Avito" tags: ["Highload", "2018", "Avito"] summary: | Николай руководит Data Platform в Avito. Сотни сервисов, сотни баз. Как это бывает сначала: shared database. У всех сервисов есть связь между собой и через базу. Тестировать невозможно. Поэтому при переходе на микросервисы у каждого сервиса своя база. Если шардов несколько, то базы надо синхронизировать. В реальности в компании есть сразу всё: и микросервисы с отдельными базами, и макро, и монолиты с shared database. Как начинается переписывание монолита на микросервисы? С доменного моделирования. Кто может его сделать? Никто, но есть люди, которые могут попробовать. --- Николай руководит Data Platform в Avito. Сотни сервисов, сотни баз. Как это бывает сначала: shared database. У всех сервисов есть связь между собой и через базу. Тестировать невозможно. Поэтому при переходе на микросервисы у каждого сервиса своя база. Если шардов несколько, то базы надо синхронизировать. В реальности в компании есть сразу всё: и микросервисы с отдельными базами, и макро, и монолиты с shared database. Как начинается переписывание монолита на микросервисы? С доменного моделирования. Кто может его сделать? Никто, но есть люди, которые могут попробовать. ## Data discovery Чтобы ориентироваться, нужен цифровой двойник инфраструктуры — Avito Platform Digital Twin. Задачи: * В каких сервисах хранятся какие важные данные? * Как важные данные путешествуют между сервисами? * Кто может работать с какими данными? Как выдать и забрать права? * Как поднять информационно-целостный подграф микросервисного графа? В частности, как прогреть ему кэши? Решение — Persistent Fabric, «помнящая ткань». База — это место, где сущности создаются и редактируются. Остальное — кеши. К сущностям нужно как-то получать доступ, поэтому появляются команды, которым принадлежат сервисы. С сервисом без команды работать сложно. Конкретный человек, который много коммитил — не решение, потому что он может уволиться. Поэтому нужно хранить команды и людей за ними. ![](../../../images/persistent-fabric.png) Не нужно заполнять весь граф вручную, данные можно достать во внутренних системах. * Команды — 1С * Сотрудники — LDAP * Сервисы — Atlas * Storages — Storage Discovery * Entities * Service Endpoints — из мониторинга. Если что-то не мониторится, значит оно не нужно. * Метрики — тоже из мониторинга. ## Сценарий: выдача прав Через граф проходим от хранилища к человеку, который подтверждает, что права можно давать. Теперь нужно пройтись ещё раз и везде отметить вновь выданное право. ## Сценарий: точки использований сущности Например, с персональными данными часто нужно стирать даже логи. Связка: вызов сервиса сервисом Запрос — проверка периметра. Откуда может утечь? Через сервисы или через шины. ## Сценарий: расследования сбоя на endpoint ## Сценарий: подграф изолированного тестирования Поднять изолированный подграф и его тестировать или нагружать. Проблема: у почти любого сервиса подграф входит и выходит в монолит. А монолит тянет всю систему. ## Поддержка системы Как поддерживать и наполнять Persistent Fabric * Каждый источник заполняет свою маленькую часть информации и связи между элементами. * Эта инфа загружается в базу, с сохранением истории Задачи in-progress * Граф потоков данных через шины * Граф связей UI points — граф пользовательских траекторий на основе клиентского логирования. ================================================ FILE: content/highload/18/1.4-bd-k8s.md ================================================ --- title: "Базы данных и Kubernetes" author: "Дмитрий Столяров, Флант" tags: ["Highload", "2018"] summary: | 1. Философия высокой доступности в k8s 1. Гарантии согласованности в k8s 1. Хранение данных и k8s --- Вопрос: * А можно ли базу в k8s? * А можно ли вообще stateful в k8s? А зачем нам вообще это? Потому что k8s — это клёво, удобно. Что именно stateful? * relational database * nosql database * in-memory database * message queue * search engine * object storage * configuration & service discovery Тема доклада: 1. Философия высокой доступности в k8s 1. Гарантии согласованности в k8s 1. Хранение данных и k8s # Философия высокой доступности в k8s Питомцы или стадо? (Pets vs. cattle) Раньше: два сервера-питомца. Мы их со всех сторон охраняем, чтобы не упали. Теперь: загончик из pod'ов и стадо контейнеров. Сдох — заменим. Механизмы HA^ * Deployment, StatefulSet * PodAntiAffinity * PodDisruptionBudget — сколько максимум подов можно погасить. # Гарантии согласованности в k8s At-most-once guarantee. Запрос обрабатывает не более чем один узел. Предположим, у нас нарушение связности. Как раньше: узел отвалился, снаружи неясно, совсем он умер иил просто недоступен. Применяем fencing — пытаемся выключить/убить сервис. Когда удостоверились, только тогда другой узел может стать мастером и принимать соединения от клиентов. Тогда клиенту точно не ответят два. В кубе есть два контроллера: Deployment и StatefulSet. В первом он сразу пересоздаёт контейнер. Во втором ждёт точных результатов. Но всё ещё нужен fencing. Его из коробки нет, но сделать можно. ## Consistent Switchover Как обойтись без fencing? Пусть у нас есть хитрый load balancer. Он может атомарно выключить весь трафик на один узел. Если узел упал, мы говорим LB выключить трафик на тот узел, дожидаемся реплики базы, включаем трафик на себя. Простой есть, но гораздо меньше. Называется «Consistent Switchover». А где это в k8s? Расскажут позже. # Хранение данных и k8s k8s монтирует сетевой диск на ноду и так передаёт её контейнеру. Если контейнер выключается, диск перемонтируется и передаётся. Сразу проблема: у диска есть латенси. Чем больше латенси, тем больше нужно потоков, чтобы выдержать заданный IOPS (input-output operations per second). ![666](../../../images/iops-hell.png) Итог * C ReadWriteOnce всё отлично. * Старайтесь избегать Network File System. # Кейсы ## Кейс 1: Standalone Есть множество случаев, когда HA не нужна. * Тестовые и стейджинги * Бывают некритичные микросервисы: 15 минут полежит и встанет, и нормально. Как на виртуалке, но мы же любим когда всё в k8s. ## Кейс 2: Реплицированная пара с ручным переключением Два инстанса. Вручную включаем и выключаем трафик, когда нам это нужно. Эквивалент двух виртуалок с ручным переключением. ## Кейс 3. Масштабирование нагрузки на чтение Да, это не совсем про стейтфул. Но можно. Когда нагрузка выросла — добавили инстансов, ушла — убрали. ## Кейс 4. Умный клиент Вместо балансирования запросов, выдаём всем узлам разные домены. Некоторые клиенты сами умеют в шардинг-репликацию. ## Кейс 5. Cloud native решения Сами умеют: * failover * recovery * consistency Ставятся в StatefulSet и всё сами умеют. Как узнают друг о друге? * K8s API * DNS (несколько А-записей) * Статически * Seed-узлы, которые друг друга сами помнят уже * Сторонний service discovery Как подключается клиент? Есть поддержка из коробки. Горизонтальное масштабирование? Может быть или не быть, зависит от продукта. Суть: все cloud native решения хорошо работают с k8s, потому что их делали сразу в расчёте на режим cattle. ## Кейс 6. Stolon PostgreSQL PostgreSQL cloud native high availability. Stolon помогает перейти от питомцев к стаду. * keeper автоматически конфигурирует инстансы * sentinel следит за конфигурацией кластера и решает, кто будет мастером или стендбаем * proxy реализует consistent switchover # Выводы Технологии развиваются волнами. Сначала технология появляется, потом она становится простой. Пока что стейтфул в k8s — уже можно, но ещё сложно, но со временем станет проще и лучше. Компания Flant делает инструмент https://github.com/flant/dapp. ================================================ FILE: content/highload/18/1.5-kafka-bicycle.md ================================================ --- title: "Apache Kafka как основа для велосипедостроения" author: "Николай Сивко, okmeter.io" tags: ["Highload", "2018"] summary: "Цель okmeter: найти проблему. Для этого нужен контент — метрики. Их собирает агент, отправляет в платформу и считает метрики. " --- Цель okmeter: найти проблему. Для этого нужен контент — метрики. Их собирает агент, отправляет в платформу и считает метрики. ## Metric store v1: chunked * копим данные за 4 часа * интервал знаем, поэтому не храним timestamp * сериализуем и жмём lz4 * пишем в cassandra * при каждой точке перезаписываем весь chunk * чтобы не читать при записи, версионируем чанки * при чтении объединяем все версии Результаты: * примерно десятикратное сжатие объема * в несколько раз ускорилось чтение * увеличилась нагрузка на Cassandra * в результате нагрузка на диск в форме пилы. ![](../../../images/cassandra-saw.png) ## Metric store v1.1: bunched Bunch — набор метрик, который пишется и читается одновременно. Пишем в один BLOB. * Ещё вдвое сжали * В несколько раз ускорилось чтение * Иногда читаем лишнее ## Metric store v2: идея! Научиться хранить «хвост» данных в памяти надёжно. * Уметь восстановить откуда-то за разумное время * несколько консистентных реплик Сможем хвост читать из этой памяти, а более давние данные — уже из Casssandra. В результате начали изобретать велосипед. В любой БД есть WAL — write ahead log. Копим данные, а потом асинхронно пишем их, потому что сразу писать — дорого. Есть offset — какие данные мы уже записали. Концепция такая: * Пишем в primary * Он реплицируется в реплики * Читать можем только из реплик В качестве WAL будем использовать kafka. Это просто надёжный лог. Producer в него пишет, а Consumer читает. Преимущества kafka: * репликация из коробки * шардинг из коробки Как работает Consumer: * на низком уровне: ConsumePartition(...), GetOffset(...), и другие методы * на высоком уровне: Consumer groups. В okmeter использовали низкоуровневый интерфейс. Если большой лаг или запрашивают диапазон больше чем у нас есть — ошибка. In-memory storage: реузльтаты * быстрое чтение * легко масштабируется * простой код (ничего не знаем про репликацию, всё из коробки) Проблема: на полный потк метрик нужно 1,5 ядра на каждом инстансе # Long-term storage ## Long-term storage: chunker * сидит на потоке и формирует 4х-часовые чанки * знает, откуда нужно начинать читать * готовые чанки складывает в отдельный топик * если пришла точка из прошлого — дописывает в тот же чанк, но с отдельным типом сообщения ## Long-term storage: chunks-writer * Читает чанки * если прилетает чанк — пишем его в C* * если точка из прошлого — достаём чанк, добавляем точку, перезаписываем Результаты Cassandra: 30000 → 150 writes/second. # Kafka в production * 6 x brokers v1.o * подселяем брокеры на ноды k8s * сырые точки храним 5 дней, это 5 терабайт * чанки храним 2 месяца, это 3.3 терабайта с учётом репликации * 20000 produced messages/second * суммарно на kafka: 10 ядер и 45Gb памяти # Рекомендации * Не обновляйтесь на *.0 релизы, даже если очень хочется. Могут быть баги. * Kafka не парится о том, чтобы уменьшить количество копирований. Используйте generate. * Если не задать лимит на скорость копирования, kafka убьёт диск, сеть и проц. После запуска лимит для операций копирования задать нельзя. Но если задать лимит заранее, можно поменять значение лимита. * Не запускайте много переносов партиций за раз. С одного брокера-лидера только одну партицию за раз. # Результат * Больше года в продакшене * Поняли, как всё работает Бонус: легкость экспериментов. * Можно выгрузить настоящие сырые данные * можно сесть на поток настоящих сырых данных * небольшой overhead на хранение * можно хранить много данных на дешёвых и больших дисках Бонус: точка опоры * от БД теперь не требуется распределённость * Consumer + standalone db # Итоги Если вы хотите написать свою специализированную БД: * Подумайте 100 раз * разберитесь, как работают взрослые БД * используйте kafka в качестве wal * напишите остаток кода * Profit!? ================================================ FILE: content/highload/18/1.6-accelerate-events.md ================================================ --- title: "Разгоняем обработку событий до 1.6М/сек. Опыт Badoo" author: "Александр Крашенинников, Badoo" tags: ["Highload", "2018", "Badoo"] summary: | Темы доклада: * Зачем собирать статистику * Как это делать * Как показывать и анализировать --- Темы доклада: * Зачем собирать статистику * Как это делать * Как показывать и анализировать # Зачем собирать статистику * Мониторинг жизнеспособности проекта * давать ответы на вопросы бизнеса * хочешь улучшить — измерь # Жизненный цикл статистики ## 1. Define Что собираем? * Бизнес-метрики приложения * Полутехнические — инсталляции приложений, UX * Трекинг поведения пользователей ## 2. Collect Статистика отсылается одновременно с бизнес-событием, но отдельным потоком. Доставка событий * конвейер обработки — внешняя система. Так лучше, потому что статистику создают микросервисы. * статистика отвязана от хранилищ для бизнес-логики * данные из контекста приложения переносим вовне Нужен транспорт. Выбираем его под задачу и мощности. Аспекты: гарантии доставки, биндинги для языков программирования, масштабируемость. Варианты: РСУБД, Flume, Kafka, LSD. В Badoo используют LSD — Live Streaming Daemon. ## 3. Process Что хотим получить из данных? * Построить графики с долгосрочной историей * выполнять ad-hoc запросы Как рисовать график? * из сырых данных * из time series Будем использовать гибридный подход: от каждого свои преимущества. Хвост из сырых данных и долгосрочный timeseries. Метрики росли, компания последовательно переходила по технологиям: * MySQL * Sharding * Hadoop * Spark * ClickHouse ### ClickHouse «Инструмент классный, документация ваще огонь, я сам туда писал». Итоги фазы: * Научились выбирать технологии под масштаб * Выбрали ClickHouse и пока не упёрлись в потолок ## 4. Present Доступ к данным * Дашборды из time series * drop detection — самое необычное поведение пользователей * anomaly detection. Для каждой метрики вычисляем предсказание и threshold. Если потом метрика выходит за пределы, включаем alert. Результаты фазы Present: * дашборды с графиками * ручной мониторинг метрик * автоматика Anomaly Detection ================================================ FILE: content/highload/18/1.7-postgresql-errors.md ================================================ --- title: "Топ ошибок со стороны разработки при работе с PostgreSQL" author: "Алексей Лесовский, Data Egret" tags: ["Highload", "2018"] summary: | В компаниях любого размера бывают проблемы. Откуда они берутся? 1. Из фич. Начинаем использовать продвинутые фичи, утилиты и прочее. «Хочется взять дежурный пистолет, положить в ящик стола, иногда достать, застрелиться и работать дальше». 1. Из хранения данных. Когда оно усложняется, больше шансов написать кривой запрос. 1. Из жизненного цикла. Разработчики пилят, админы настраивают, а улучшать систему некому. База работает с дефолтными конфигами и когда-нибудь ломается. --- # Intro В компаниях любого размера бывают проблемы. Откуда они берутся? 1. Из фич. Начинаем использовать продвинутые фичи, утилиты и прочее. «Хочется взять дежурный пистолет, положить в ящик стола, иногда достать, застрелиться и работать дальше». 1. Из хранения данных. Когда оно усложняется, больше шансов написать кривой запрос. 1. Из жизненного цикла. Разработчики пилят, админы настраивают, а улучшать систему некому. База работает с дефолтными конфигами и когда-нибудь ломается. # Наводим порядок ## Планирование и мониторинг Пока проект новый, всё работает быстро. Потом приложение растёт, появляется больше клиентов — приложение тормозит. Где могут быть проблемы: * Диск занят `pg_xlog`. Разработчик: «а давайте его удалим!». Не надо так. Там журнал транзакций. * Диск занят базами, больше всего в `history_log`. Пытаемся почистить базу запросом, но она не уменьшается, потому что постгрес не отдаёт автоматически место ОС. * Disk I/O. Некто составил запрос на M таблиц в N потоков X тысяч раз в секунду. Результат — сервер пятисотит. * Тормоза фоновых процессов СУБД. * Накладные расходы от виртуализации * Хранилище от китайского noname * Дефолтные конфиги * ... Что делать? Мониторить и планировать! * Сразу на SSD, не раздумывая. * Схема данных: планировать заранее и писать только нужное. Например, не писать в логи JSON весом в несколько мегабайт. * Партиционирование Мониторинг: * Storage: latency, utilization * PostgreSQL: подключенные клиенты, ошибки, запросы (statements) ## Масштабирование Типичный разработчик видит БД как строчку конфига и не интересуется тем, как она работает. Это источник проблем. OLTP-транзакции — быстрые, короткие, лёгкие. OLAP-транзакции — медленные, долгие и тяжёлые. Те и другие нужно разносить. Вторые мешают первым. Как масштабировать PostgreSQL так, чтобы разнести нагрузку? * Streaming replication — создаём реплики, в том числе каскадные, на разные реплики вешаем разные запросы. Например, аналитику на отдельную реплику. * Logical publications, subscriptions. Конкретные наборы таблиц подключаем в соседние базы и их приложения могут ими пользоваться. * Внешние таблицы (foreigh tables), декларативное партиционирование (declarative partitioning). Несколько баз с разными наборами таблиц. С помощью механизма внешних таблиц объединяем их в одной базе, приложение работает с ней, но на самом деле качает данные из тех нескольких баз. С чего начать? * С репликации. Разнести нагрузку на чтение и запись. Пишем в мастер, читаем из реплик. Для аналитических запросов делаем отдельную реплику. * Балансировка: лучше на стороне приложения, можно DNS round robin, интересно Keepalived и Haproxy, совсем хорошо Patroni, DCS. ## Приложения и СУБД-транзакции Idle transactions приводят к снижению производительности, блокировкам и дедлокам, потом к пятисотым. Откуда берутся такие транзакции? 1. Внешний источник: 1. Приложение открывает транзакцию 1. Потом идёт на какой-то другой источник, встречает там ошибку, падает. 1. Profit, транзакция висит, пока её явно не убьют. 1. Нет обработки ошибок 1. Человеческий фактор — открыл и забыл. Что делать: * Алерты в мониторинге * `pg_terminate_backend` * устранять ошибки в приложении Избегайте пустых транзакций любой ценой! ## Велосипедостроение Фоновая обработка событий. Бизнес хочет необычного. Появляются самописные очереди. От долгих транзакций эти таблицы распухают. Растёт время их обработки, очередь перестаёт работать. Что делать: использовать Skytools PgQ. Но и в нём есть проблемы: * Мало документации * Нужно применять джедайские техники * Много нужных знаний находятся в почтовых рассылках (mailing lists) Плюсы PgQ: * Настроил и забыл. * Дешевле отдельных брокеров. Вывод: для каждой задачи сначала ищите инструменты, которые уже изобретены. ## Автоматизация Админы хотят: * инстансы * деплой * конфиги Разработчики хотят: * деплой * миграции катить без ручных вмешательств Все хотят autofailover! Но всё не так просто: * Случается split-brain. Потеряли связность сети, fencing'а нет, приложения пишут сразу в два мастера. Так было недавно у GitHub. * Каскадный failover. Мастер падает, переключаем на второй, который не успел отреплицироваться, он тоже падает, остаётся один сервер, который складывается под нагрузкой. Как делать failover? * [-] bash-скрипты! (НЕТ!) * [-] ansible — баш на стероидах * [+] [Patroni](https://github.com/zalando/patroni) * [+] [PAF](https://github.com/clusterlabs/PAF) * [+] [Stolon](https://github.com/sorintlab/stolon) ## Контейнеры и оркестрация А что, если развернуть базу в k8s? * Нужно где-то хранить. Решения есть (CEPH, GlusterFS, DRBD), но они медленные. И нужно поддерживать кластерную файловую систему. Это работает, пока база маленькая, нет требований к производительности и не страшно потерять данные. Т.е. это не работает. Вывод: использовать для стейджингов и девелоперских машин, но не на проде. Если очень хочется — то использовать local volumes, streaming replication и операторы PostgreSQL. ================================================ FILE: content/highload/18/1.8-badoo-infradev.md ================================================ --- title: "«Платформа» в Badoo: как мы построили инфраструктурную разработку" author: "Антон Поваров, Badoo" tags: ["Highload", "2018", "Badoo"] summary: | * Всё растёт. Больше пользователей и нагрузки. * Бизнес хочет ещё больше. * Инфраструктурные задачи бизнесу непонятны, но необходимы для развития. --- # Как появляется инфраструктурная команда * Всё растёт. Больше пользователей и нагрузки. * Бизнес хочет ещё больше. * Инфраструктурные задачи бизнесу непонятны, но необходимы для развития. Примеры: * Шардинг, масштабирование * Visibility: логи, метрики, визуализация * Второй ДЦ * ... Нужна отдельная инфраструктурная команда, которая будет это поддерживать. Направления: * Продуктовые бэкенды. C/C++/Go. * Инфраструктурные сервисы * скриптовое облако * очереди * фотографии * миграция данных между ДЦ * mobile API gateway * Инструменты разработчика * метрики: хранение и визуализация * деплой PHP-кода * сборки и модули для PHP и nginx * тестирование: soft mocks * unified data system (UDS) # Путь инфраструктурной команды над которой не стоит стейкхолдер из бизнеса и не требует задач. Есть задачи: * от бизнеса * от продуктовых команд * развивать инфраструктуру Полезность команды растёт. Потом становится так: * от бизнеса — но зачем, это же фичи? * от продуктовых команд — некогда нам? * развивать инфраструктуру!!! Полезность команды падает. Приуныли. Нужна коммуникация и баланс между развитием платформы и конкретными фичами для бизнеса. # Как выбирать важное? Важна культура. * горизонтальные связи * фокус на результате * постоянный инженерный фидбэк Воронка рождения проекта: 1. Источники: собрать боль и хотелки. Делаем максимально широкую воронку. Сами идём к разработчикам и ищем боль. Устраиваем формат AMA (ask me anything) — в назначенное время в переговорке отвечаем на все вопросы. 1. Вовлечение: найти заказчика. Слушаем, вовлекаем, предлагаем решения, формируем видение. 1. Бизнес-цели: какую задачу решаем? Могут быть про продукт, про time to market, про оптимизацию работы или страховку «от метеорита». Бизнес-цели имеют нетехнические критерии оценки и меняют технический проект. 1. Ready to dev: инженерный проект и ресурсы. Важный вопрос здесь — что НЕ делать? Помним о принципе YAGNI. Понять, что критично, и построить именно это. 1. Приоритеты. Делаем сквозную приоритизацию всех проектов. Сверяемся с командами, которые делают фичи. # Разработка * проекты долгие * высокая цена ошибки * нельзя просто «написать код» * внедрение часто сложное * хорошее качество должно быть сразу (а в разработке фич не так; можно сделать как-то, а потом допилить, если выстрелит) Кто делает? Разработчик * проводит kick off * формирует технический план * ведёт проект * отвечает за результат Любой проект режется на этапы. Каждый этап: * что именно будет сделано? * сроки: когда на бою? * длительность — 1-2 недели * выкладываем на прод * стараемся анонсировать, что получилось # Пиар важен * проекты долгие * изменения часто невидимы «by design» пользователям и даже разработчикам. поэтому: * собираем фидбэк * рассказываем, что нового * делаем это постоянно результат: * разработчик понимает, что проблемы решаются * доверяет и приносит новые проблемы # Цикл работы инфраструктурной команды 1. слушаем 1. вовлекаем 1. предлагаем решения 1. делаем 1. вовлекаем и пиарим ================================================ FILE: content/highload/18/1.9-data-engineers.md ================================================ --- title: "Дата-инженеры и кому они нужны" author: "Валентин Гогичашвили, Zalando SE" tags: ["Highload", "2018"] summary: | Тема доклада: что такое данные, откуда они берутся и почему онлайн-магазин обуви заинтересован в данных. --- > «Когда я начинал в Zalando, он рос на 100% в месяц и через два месяца всё, что мы строили, уже не работало. Поэтому мы научились строить впрок.» # Данные — это стратегический ресурс Тема доклада: что такое данные, откуда они берутся и почему онлайн-магазин обуви заинтересован в данных. Данные — это новая нефть. Как и нефть, сами по себе они ничего не значат и получат ценность при обработке. Ценен процесс и продукт обработки данных. Однако, продукт обработки нефти не создаёт новую нефть, а обработка данных создаёт ещё больше данных. (Piero Scaruffi, 2016) В 2016 году компания Zalando приняла новую стратегию данных (data strategy): * Данные — стратегический ресурс компании. * Департаменты компании должны делиться друг с другом этим реурсом. (В рамках закона.) Пирамида потребностей в Data Science. Чем выше — тем больше науки (знания), чем ниже — тем больше процессинга и технических проблем. ![data-science-pyramid](../../../images/data-science-pyramid.png) # Кто такие дата-инженеры Как на самом деле работают учёные, в том числе data scientists? Кажется, что они только наслаждаются полётом научной мысли и периодически производят «Эврику». Но на деле они 80% занимаются фигнёй: борются с плохим качеством и недостаточностью данных, либо страдают от несовершенств инфраструктуры и инструментов. Кроме дата-саентистов (математиков) ещё нужны дата-инженеры (программисты). Дата-инженеры — это обслуживающий персонал, как сантехники. Они собирают и обслуживают системы для работы с данными. # Data engineering — это продукт и сервис В больших компаниях data engineering — это продукт и сервис. Знайте своих клиентов, для которых вы строите систему: * data scientists, * developers, * product analysts, * product managers. Проектируйте и доставляйте, как обычный продукт: * интервьюируйте клиентов, * предлагайте гипотезы о том, что им нужно, * проверяйте эти гипотезы, * доставляйте изменения наименьшими возможными итерациями. # Опыт разработки платформы в Zalando В Zalando есть платформа machine learning на основе manaded Jupiter notebooks. Для одних фич гипотезы окзаались верными, для других — нет: * Data Lake integration — вместо неё захоттели BigQuery и Exasol. * Пришли к пилотной команде, предложили сделать ядро на R/Python, те потребовали Spark. В итоге только две команды используют Spark. * Думали что понадобится поддержка вычислений на GPU, на деле почти не понадобилось. * Польователи попросили в срочном порядке AirFlow scheduling, теперь строят свои пайплайны обработки данных прямо там. * Подумали, что понадобятся Shared team spaces (NFS) — угадали, фича оказалась очень востребованной. Важно обучать пользователей. Часто они не пользуются просто потому, что не знают. Чтобы фичу использовали десять команд, расскажите о ней сотне команд. # Data Lake Централизованное хранилище данных, которое учитывает требования закона и аудита. Интегрируется с остальными системами. Все данные, проходящие через Nakadi, попадают в Data Lake. Столкнулись с проблемами: * Структуры данных, которые попадают в Data Lake, оказались гораздо сложнее, чем ожидали. Вложенность до 10 уровней, неудобно вытаскивать данные обратно. * Эффективно использовать Presto SQL с такими данными не получается, пытаемся найти новое решение. # GDPR Compliance & regulations — важная проблема, вынуждает строить централизованные системы. Важны такие фичи: * discoverability, * searchability, * usability. # Автоматизируй это! Важно автоматизировать весь процесс и следить, не создаём ли мы бутылочное горлышко. Например, security team хочет проверять всё ручками — это не будет масштабироваться. Найдите решение, которое распределит ответственность за принятие решений по данным. # Качество данных Качество суперважно. Вообще есть 160 параметров качества, вот главные. Выделены те, которые легче всего обеспечить. * Аccuracy (правдивость, точность в смысле верно/неверно) * *Completeness* (полнота: все обязательные поля заполнены; есть все данные, которые бывают обычно) * *Timeliness* (? данные сохраняются сразу, как только они получены) * *Currency* (своевременность? Данные доступны к тому моменту, когда они нужны) * Validity and integrity (валидность и целостность) * Consistency (консистентность, надёжность: данные консистентны, если каждый элемент данных сохраняется в разных системах с одинаковым значением) * Accessibility (доступность: данные легко достать и использовать) * Precision (точность в смысле «4,98 точнее чем „почти пять“») * Lineage (?) * Representation (?) Что делать: * Думаем о том, как будем измерять и отслеживать качество. * Проблемы с качеством данных считаем настолько же серьёзными, как если у нас упал онлайн-магазин. # Не изобретайте колесо Задача — решать проблему компании. Не стройте новые собственные инструменты, используйте готовые. ================================================ FILE: content/highload/18/2.1-vk-architecture.md ================================================ --- title: "FAQ по архитектуре и работе ВКонтакте" author: "Алексей Акулович, ВКонтакте" tags: ["Highload", "2018", "ВКонтакте"] summary: | * фронты: независимые сервера с nginx, анонсируют общие IP,терминируют HTTPS/WSS. * бэкенды: http сервера на kPHP, модель работы prefork, вместо перезапуска сбрасывают состояние (global/static vars). --- # Архитектура * фронты: независимые сервера с nginx, анонсируют общие IP,терминируют HTTPS/WSS. * бэкенды: http сервера на kPHP, модель работы prefork, вместо перезапуска сбрасывают состояние (global/static vars). Для распределения нагрузки: * Бэкенды группируются: general, mobile, api и т.п. Выбирает между ними nginx на фронте. * Сбор метрик и перебалансировка. * Content server (cs). Хранят и обрабатывают файлы. * Часть cs закрыты специальными pu/pp серверами (photo upload / photo proxy). Зачем они нужны? * для терминирования HTTPS * чтобы использовать серые IP-адреса для cs * для отказоустойчивости через общие IP * спорно — чтобы клиент держал меньше соединений Обычно видео гоняется напрямую, а более лёгкий контент — через прокси. * sun — новая альтернатива pp. Зачем: * у pp один IP на группу, в результате один файл оседает во всех кешах * pp нельзя шардировать и ставить в регионах Как устроены sun: * маршрутизация anycast * кеширование * поддержка весов * можно ставить в регионах * шардирование по id контента (например, когда 100000 человек запрашивают аватарку одного пользователя) * cache — региональные кеши. Регион определяем так: 1. сбор сетей региона по BGP 1. инфа загружается в базу, + geoip 1. по IP пользователя определяем регион * engines — базы данных # Базы данных Называем engines, потому что это не совсем базы данных. В 2008-2009 использовали MySQL и Memcached, но они не выдержали взрывного роста пользователей. Заменили их на велосипеды. Типов движков очень много. На каждую задачу — новый тип движка. Очереди, списки, сеты — всё что угодно. Движки одного типа объединяются в кластеры. Код не знает расположения и размера кластеров. Для этого между серверами и базами есть ещё rpc-proxy: * общая шина * service discovery, forwarding * circuit breaker На каждом сервере есть локальный rpc-proxy, который знает, куда направить запросы и где находятся engines. Если один engine идёт в другой, то тоже делает это через прокси. Engine не должен знать ничего, кроме себя. Персистентное хранение данных: * движки пишут бинлоги: binary log (WAL, AOF). Пишутся в одинаковом бинарном формате (TL scheme), чтобы админы их читали своими инструментами. * снапшоты: слепок данных + offset в бинлоге. Общее начало, тело произвольное. При перезапуске движок сначала читает снапшот, восстанавливает из него своё состояние. Потом из него находит offset, по нему дочитывает остаток из бинлога, восстанавливает окончательное состояние. Результат: репликация данных: * statement-based * инкрементальный унос «хвоста» бинлога Эта же схема используется для создания бэкапов. ![vk-binlog](../../../images/vk-binlog.png) # Логи Как собираются? * отправка в memcached. Там кольцевой буфер (`ring-buffer: prefix.idx = line`). * отправка в logs-engine (разработан in-house) Хранятся в ClickHouse. Чтобы это заработало, приходится локальный rpc-proxy заменить на KittenHouse, а на движке добавлять KittenHouse reverse proxy. А ещё есть nginx, чтобы получать логи по UDP. ![clickhouse-logs](../../../images/clickhouse-logs.png) # Мониторинг Есть два типа метрик. Системные и админские метрики: * netdata собирает статистику, * отсылает в Graphite Carbon * ClickHouse * можно смотреть через Grafana Продуктовые и разработческие метрики: * много метрик * очень много событий — от 0,6 до 1 триллиона в сутки * храним 2+ года Эксперимент: собираем метрики на ClickHouse * удобнее основной системы * требует меньше серверов, но сами сервера жирнее # Деплой Git, GitLab, TeamCity PHP: 1. git pruduction branch 1. diff файла 1. записывается в binlog copyfast 1. реплицируется на сервера через gossip replication 1. применяется локальными репликами на локальной файловой системе kPHP: * большой бинарь, сотни МБ * git master branch * версию пишем в binlog copyfast * реплицируем версию на сервера * сервер вытягивает свежий бинарник через gossip replication * graceful-перезапуск на новую версию Движки: * бинари в .deb * git master branch * версию пишем в binlog copyfast * реплицируем версию на сервера * сервер вытягивает свежий .deb * dpkg -i * graceful-перезапуск на новую версию # Другие доклады про архитектуру VK * [Системный администратор ВКонтакте. Как?](https://highload.ru/2016/abstracts/2416) * [Разработка в ненадёжной нагруженной среде](https://2018.codefest.ru/lecture/1250) * Как VK вставляет данные в ClickHouse с десятков тысяч серверов: на [Highload Siberia](https://highload.ru/siberia/2018/abstracts/3614) и на [Highload Moscow](https://highload.ru/moscow/2018/abstracts/4066) * [Архитектура растущего проекта на примере ВКонтакте](https://highload.ru/2016/abstracts/2414) ================================================ FILE: content/highload/18/2.2-testing-badoo.md ================================================ --- title: "Монолит для сотен версий клиентов: как мы пишем и поддерживаем тесты" author: "Владимир Янц, Badoo" tags: ["Highload", "2018", "Badoo"] summary: | Темы: 1. Наш процесс разработки 1. Юнит-тесты 1. Интеграционные тесты 1. Тесты на API 1. Прогон тестов --- Темы: 1. Наш процесс разработки 1. Юнит-тесты 1. Интеграционные тесты 1. Тесты на API 1. Прогон тестов # Процесс разработки К сроку выкатывания фичи добавляется: * desktop web + два месяца * mobile web + неделя * iOS + месяц * android + полгода Разработчик отвечает за фичу от бэкенда до реализации на платформах. Интеграция бывает нескоро. Поэтому хочется сделать так, чтобы интеграция прошла хорошо. Нужны автотесты! # Unit-tests Тесты на изолированные кусочки кода. Сложно тестировать легаси. Для него делаем SoftMocks. Оно перехватывает все include/require в PHP-файле, подменяет подключаемый файл на другой. Можно мокать любые методы: статические, приватные, финальные. Проблема: SoftMocks расслабляют — можно писать плохо тестируемый код и всё равно покрыть его тестами. Решили правилами: * новый код должен быть легко тестируемым с помощью PHPUnit * SoftMocks — крайний случай, когда иначе нельзя. Правила проверяются на код-ревью. Мутационное тестирование. 1. берем код 1. берем code coverage 1. парсим код и генерируем мутации: меняем плюс на минус, true на false 1. для каждой мутации прогоняем набор тестов: * если тесты упали — они хорошие * если тесты успешно прошли — они недостаточно эффективны Для PHP есть готовые решения: Humbug, Infection. Но они несовместимы с SoftMocks. Поэтому написали своё. # Интеграционные тесты Тестируем работу нескольких компонентов в связке. Стандартный подход: 1. Поднимаем тестовую БД 1. Заполняем её 1. Запускаем тест 1. Очищаем БД Есть проблемы: * нужно поддерживать актуальность содержимого базы * требуется время на подготовку * параллельные запуски делают тесты нестабильными и порождают дедлоки (когда тесты работают с одной и той же таблицей) Решение: DBMocks 1. Методы драйверов DB перехыватываются с помощью SoftMOcks на setUp теста 1. из запроса вытаскиваются db + table 1. создаются временные таблицы с такой же схемой 1. все запросы идут во временные таблицы 1. потом на tearDown они удаляются Результаты: * тесты не могут повредить данные в оригинальных таблицах * тестируем совместимость запроса с версией MySQL. * тесты вообще ходят в ту же БД по тому же адресу (просто таблица другая) * тесты изолированы друг от друга # API-тесты * имитируют клиентскую сессию * умеют слать запросы к бэкенду * бэкенд отвечает почти как реальному клиенту Обычно такие тесты требуют авторизованного пользователя. Его нужно создать перед тестом и удалить после. Это порождает риск нестабильности, потому что при создании пользователя есть репликация и фоновые задачи. Решение: пул тестовых пользователей. 1. Нужен пользователь 1. ищем в пуле 1. если нет — создаём 1. после теста очищаем, потому что тест загрязняет пользователя Тестовые пользователи в одном окружении с реальными? Зачем вообще их тестировать на бою? Потому что devel ≠ prod. Надо изолировать, иначе пользователи будут флиртовать с кучей фиктивных Олегов. Путь 1: флаг `is_test_user`, по флагу изолируем внутри сервисов. Путь 2: всех пользователей переселяем в условную Антарктиду и они там тусят друг с другом. ## QA API бэкдор для тестирования * хорошо документированные методы API * быстро и легко управляют данными * пишут их бэкенд-разработчики * применимы только к тестовым пользователям Позволяют сменить пользователю неизменяемые данные, вроде даты регистрации. Безопасность * сетевая изоляция — доступно только из офисной сети * с каждым запросом передаётся secret, валидность которого проверяем * методы не работают с реальными пользователями * программа BugsBounty на hackerone # Прогон тестов * 100 000 юнит, 40 минут * 6 000 интеграционных, 90 минут * 14 000 API, 600 минут Распараллелили тесты в TestCloud. Как распределить тесты между потоками? * поровну — фигня, все тесты разные, получатся неравные по времени части * запустить несколько потоков и скармливать тесты по одному — тратим время на инициализацию PHP-окружения. Долго! Как сделали: * собираем статистику по времени прогона * компонуем тесты так, чтобы один chunk прогонялся не более чем за 30 секунд Проблема: медленные тесты занимают ресурсы, не давая выполняться быстрым. Т.е. API могут занять весь Cloud. Решение: разделили Cloud * часть 1 прогоняет только быстрые тесты * часть 2 прогоняет любые тесты Результат: * Unit — 1 минута * Интеграционные — 5 минут * API — 15 минут Какие тесты выполнять? Покажет code coverage. 1. Получаем branch diff 1. формируем список измененных файлов 1. получаем список тестов, которые его покрывают 1. запускаем прогон набора только из этих тестов А где взять coverage? * раз в сутки, ночь, полный прогон с test coverage * результаты складываем в БД Плюсы: * прогоняем меньше тестов: меньше нагрузка на железо и быстрее обратная связь * можем запускать тесты для патчей. Это позволяет быстро выкатить хотфикс. В патчах скорость важнее всего. Минусы: * Релизим бэкенд дважды в день, так что coverage актуален только для первого. Поэтому для билда прогоняем полный набор тестов. * API-тесты генерируют слишком большой coverage. Для них этот подход не даёт большой экономии. # Итоги * все уровни пирамиды тестирования нужны и важны * количество тестов ≠ качество. Делайте ревью кода тестов и мутационное тестирование. * изолируйте тестовых пользователей от реальных. * бэкдоры в бэкенде упрощают и ускоряют разработку тестов. * собирайте статистику по тестам. # Ссылки * Слайды: bit.ly/yants-HL18 * Наш протокол: [«Как мы поддерживаем 100 разных версий клиентов в Badoo» / Ярослав Голуб](https://youtu.be/G-AiDkZLOIs) * SoftMocks: [«SoftMocks: наша замена runkit для PHP 7» / Юрий Насретдинов](https://habr.com/company/badoo/blog/279617/), [github.com/badoo/soft-mocks](https://github.com/badoo/soft-mocks) * [Badoo BugsBounty](https://hackerone.com/badoo) * UI тесты: [«Cross Platform Mobile Test Automation and Continuous Delivery» / Sathish Gogineni](https://youtu.be/N0hYSHmRJTQ) * TestCloud: [«Оптимальная параллелизация юнит- тестов или 17000 тестов за 4 минуты» / Илья Кудинов](https://tech.badoo.com/ru/article/115/parallelizatsija-unit-testov-badoo/) ================================================ FILE: content/highload/18/2.3-such-highload.md ================================================ --- title: "Как устроить хайлоад на ровном месте" author: "Олег Бартунов, Федор Сигаев, Postgres Professional" tags: ["Highload", "2018"] summary: | Highload — чисто русское слово. Остальные используют high-volume. Хайлоад — это ситуация в системе, грозящая отказом в обслуживании из-за недостатка ресурсов. Внештатная ситуация. В идеале хайлоада не должно быть, но есть человеческие ошибки, которые ведут к недостатку ресурсов (железа, людей, денег), а он приводит к угрозе отказа в обслуживании. Спешная починка костылями. --- # Что такое хайлоад Что такое хайлоад на самом деле? *Производительные* и *масштабируемые* системы *высокой доступности*. Highload — чисто русское слово. Остальные используют high-volume. Хайлоад — это ситуация в системе, грозящая отказом в обслуживании из-за недостатка ресурсов. Внештатная ситуация. В идеале хайлоада не должно быть, но есть человеческие ошибки, которые ведут к недостатку ресурсов (железа, людей, денег), а он приводит к угрозе отказа в обслуживании. Спешная починка костылями. Костыль — решение задачи без серьёзного редизайна системы. Документированный костыль — полноценная фича системы. Про что доклад: * действия, которые создают хайлоад на ровном месте * известные, но важные ошибки * в частности про PostgreSQL Ошибки проектирования * Неэффективное использование ресурсов, блокирование спящим процессом. Процесс ждёт, пока клиент заберёт свой запрос. * База наружу — внешний трафик внутри сети. * Разные сервисы на одной машине дерутся за ресурсы. * Останов мастера при исчезновении единственной синхронной реплики. Используйте одну синхронную и одну асинхронную реплику. * Неправильное или недостаточное тестирование * Пиковые нагрузки — по времени, по событиям, таймзонам. * Разумный отлуп роботов # Ошибки проектирования БД * Пагинация. На страницу N+1 попадают 3% посетителей, и это скорее всего роботы. Не надо заранее выгружать вторую страницу с LIMIT/OFFSET. А если пользователь все-таки перешел на вторую, то далее выгружайте больше страниц сразу в кэш. * Узкие таблицы — оверхед постгресовых заголовков. Заголовок в постгресе всё равно займет не меньше чем 32 байта, даже если колонки — два bool. Пример: id-координата, 60 терабайт. Объединили 200 точек в 1 JSON, получилось 10 терабайт. * Широкие таблицы — тоже плохо. * NoSQL когда не надо. На больших данных джойны в клиенте приводят к аду. * JSON/XML когда не надо. * «Ненужная» точность вычислений * Виртуализация и докер # Graceful degradation * Мало кто думает * ПОС по нагрузке * Лучше обслужить кого-то, чем попытаться обслужить всех и упасть. * Поисковые системы лучше всего ищут в ночь с субботы на воскресенье. Когда нагрузки больше, они ограничивают задачу, чуть ухудшают качество, но зато не деградируют. # Нелепости * Забытая клавиатура на стойке блокирует отвод тепла, процы понижают частоту. * Скомпилировали с дебагом (`--enable-cassert`). * Не материализация настроек — настроили, но не сохранили нигде * Логирование (prepared statements & syslog). * foreign keys / triggers * бесконечные with recursive * зависшие транзакции — вакуум встаёт намертво * freeze и вообще автовакуум * неумеренное использование временных таблиц (bloat системного каталога) * ненужные и бесполезные индексы * много памяти без huge pages * ненужное шифрование * множественные savepoint (SubtransControlLock) * планируемые дедлоки * отключение генетического оптимизатора (geqo) Сложность оптимизации — факториал от количества таблиц индексов. Генетический оптимизатор избавляет от этой зависимости. В PostgreSQL есть таймауты! Используйте их! * `authentification_timeout` * `wal_sender_timeout` * `statement_timeout` * `lock_timeout` * `idle_in_transaction_session_timeout` * `deadlock_timeout` * TCP keepalive (оба два!) И еще много других! Камни, под которые редко заглядывают: * `Max_files_per_process` * `bgwriter_*` * `Effective_io_concurrency` * `Effective_cache_size` * Параллелизм помогает только когда есть свободные ядра. * `Wal_level` * `Random_page_cost` * `*_collapse_limit` если скорость работы зависит от порядка джойнов — упёрлись в этот лимит. * `default_transaction_read_only` * `max_connection` (и на реплике!) * временные файлы постгреса — следить, чтобы постгрес создавал их меньше * отстающие реплики (гроханье таблиц по одной для освобождения диска) # Срочные костыли (не делайте так) * fsync = off (data_loss = on) * synchronous commit = on (лог и миримся с потерями) * unlogged table (кстати, и hash index тоже (до PG10)) # Хайлоада не избежать! * Всегда нужен план Б: * жертвуем доступностью, чтобы избежать эффекта домино * сохраняем целостность данных * Обязательны полевые учения. ================================================ FILE: content/highload/18/2.4-dababase-pro.md ================================================ --- title: "Как стать классным спецом по базам данных" author: "Илья Космодемьянский, Data Egret" tags: ["Highload", "2018"] summary: | БД — вещь простая, а люди сложные, поэтому советы могут не всем подойти. Сам следовал не всем советам. --- БД — вещь простая, а люди сложные, поэтому советы могут не всем подойти. Сам следовал не всем советам. # Кем мы хотим стать Карта навыков: ![db-skills](../../../images/db-skills.png) Любой роли полезно иметь навыки из соседних областей. # Надо ли оно нам * Скучно точно не будет. БД — это интересно. * Покуда есть данные, будут и базы. Они могут поменяться, но они будут. * DBA — как сантехник, но в тепле и за клавиатурой. Иногда не в тепле. :) Как? * Получить профильное образование? Забудьте, нет такого образования. Но есть ВУЗы, которые хорошо этому учат. Но выйдя из вуза, вы не станете спецом. Можно стать классным разработчиком ба данных или спецом по database computer science. * Пройти курсы? * Прочитать книжку? * Методом проб и ошибок? Идеальный экзамен на DBA в вакууме. * На время починить базу, которую вы видите в первый раз, проблема непонятна, но всё тормозит. * Экзаменаторов 10-20-30. * 3 спрашивают «ну как» в слаке * 3 спрашивают «ну как» по телефону * 1 требует залогировать время * 3 внедряют скрам прямо сейчас # Теоретические знания * Что первым приходит в голову? Реляционная алгебра. О ней стоит знать, но не изучать её больше недели, потому что она бесконечна. Пример: первая нормальная форма. Надо знать, но этого достаточно. Хорошая вводная книга: Новиков, Домбровская: Настройка приложений баз данных. * Что вторым приходит в голову? B+, B* и т.п. Тоже не останется времени на дело. Суть: СУБД — это фреймворк для работы с данными. Он универсальный, надёжный, производительный. Как это происходит — нужно знать досконально. # Практические технические навыки Конкретно что нужно знать: * Concurrency control * 2 phase locking * deadlock detection * multi version concurrency control * Recovery * write ahead log * redo * undo * Distributed transactions * 2 phase commit * distributed recovery Что читать? * минимум — википедия * лучше книжка: G. Weikum, G. Vossen, Tranactional Informatino Systems: Theory, Algorithms, and the Practice of Concurrencty Control and Recovery. Как читать? * в первый раз не читать про объекты и поисковые структуры * потом читать ещё и ещё Подводные камни: * не путать двухфазное блокирование и двухфазный коммит * не противоставлять двухфазное блокирование и MVCC Всё это — пессимистические алгоритмы, они самые распространённые, но мир ими не ограничен. Отвыкайте читать книги и привыкайте читать документацию: * Хороших книг по практике мало. * Они редко и недолго бывают актуальными. Как читать документацию? * Если один раз прочитать документацию о каждом параметре `postgresql.conf`, вы станете намного круче. * Это же касается любой другой базы. * Заведите тестовый сервер и экспериментируйте, как влияют разные параметры. Решаем проблемы * сохраняйте спокойствие * ищем причину: do not tune the query / know your data — думайте как устроен запрос, а не пытайтесь решить силком * учите **заранее** средства диагностики — top, iostat, perf и другие # Практические нетехниеские навыки * Учитесь говорить, писать и читать по-русски и по-английски. * Делайте доклады — учите коллег, выступайте на митапах, подавайтесь на Highload! * Учитесь общаться с девелоперами, бизнесом и не только с ними. Без девелоперов и бизнеса не будет БД. Всё это придётся делать одновременно. ================================================ FILE: content/highload/18/2.5-make-your-database-dream-of-electric-sheep.md ================================================ --- title: "Make Your Database Dream of Electric Sheep: Designing for Autonomous Operation" author: "Andy Pavlo (Carnegie Mellon University)" tags: ["Highload", "2018"] summary: | Background – complexity of modern systems, DBAs take up 50% of cost. 1970-2000s – Self-adaptive, self-tuning databases (index selection, partitioning/sharding). Human input, workload trace analysis, human decision. --- ### History Background – complexity of modern systems, DBAs take up 50% of cost. 1970-2000s – Self-adaptive, self-tuning databases (index selection, partitioning/sharding). Human input, workload trace analysis, human decision. ![autonomous-dbms](../../../images/make-your-database-dream-of-electric-sheep/1-autonomous-dbms.png) Automating knob configuration. Database knob – configuration parameter you can set to modify runtime behavior. Growing complexity for human DBAs – hundreds of knobs. 2010s – Cloud databases. Automating deployment of large number of databases in cloud environment. ### Why is this all insufficient? * Problem 1 – Human judgements – is smth a right thing to do, observe over time if it continues to be the right thing to do, application and needs evolve. Human judgement is not scalable. * Problem 2 – Reactionary measures – feedback on a workload trace from the past. It can’t look ahead and prepare the system to what’s coming. Humans can. * Problem 3 – No transfer learning between database instances in all these solutions. What’s different now? Better hardware, better machine learning tools, better appreciation for data. We seek to complete the circle in autonomous databases. Make decisions and learn from them automatically. ## 2 research projects ### OtterTune For existing databases – black boxes – we only see what they’re exposing to us. Database Tuning-as-a-Service * Automatically generate DBMS knob configurations. * Reuse data from previous tuning sessions. Target database -> Controller (collector) -> Tuning manager (metric analyzer, knob analyzer, configuration recommender) -> Controller (install agent) -> Target database ![ottertune](../../../images/make-your-database-dream-of-electric-sheep/2-ottertune.png) Repeat: collect more runtime metrics, feed back into ML algorithms, see if we get better performance, make recommendation, over and over. Objective function – latency or throughput, or whatever you want to optimize. Another key thing that’s different about OtterTune - the only thing algorithms need to see is benign information about runtime metrics. It doesn’t need to see your data or user queries. Live demo of OtterTune. Comparison with DBAs. Efficiency. Scalable. ### Peloton (in process or renaming) What things you can do better than OtterTune if you control the entire software stack. Self-Driving Database System * In-memory DBMS with integrated ML framework. * Designed for autonomous operations. ML components can observe all aspects of database runtime behavior, and then make recommendations. Goes beyond just knob configuration like OtterTune – all other things like picking indexes, picking partition schemes, scaling up, scaling out. Self-driving cars comparison * Self-driving car sees what’s coming ahead in the road and makes predictions on how to get there * Target database -> Workload history -> Forecast models (predicting how the target database’s workflow is going to look like in future – e.g. in one week from now or in one hour from now) -> Planning component “The Brain” * Bunch of actions like “drop index”, “add index”, “scale up”, “scale out”, etc. -> sequence of actions that will get you towards maximizing your objective function -> throw out all actions except the first one, apply it and repeat the process ![peloton](../../../images/make-your-database-dream-of-electric-sheep/3-peloton.png) Being built from scratch because existing systems are too slow (e.g. adding index is slow). Apply changes and learn as quickly as possible what the right configuration is. The first problem (predicting workload) is solved. The big problem not yet solved is action catalog. How to determine whether one action is better than another, in terms of what happens before you deploy it or after you deploy it, how you reverse things, etc. How to interact internally and with outside world. This all is ongoing research. Story - automatic index selection tool, customer kept undoing indexes, so many times that the tool got stuck and didn’t know what to do – turned out customer didn’t like names of indexes. ### Design Considerations for Autonomous Operation Configuration knobs * Anything that requires a human value judgement should be marked as off-limits to autonomous components (file paths, network addresses, durability/isolation levels). * Autonomous components need hints about how to change a knob (min/max ranges, separate knobs to enable/disable a feature, non-uniform deltas). * Indicate which knobs are constrained by hardware resources. The problem is that sometimes it makes sense to overprovision. * If knobs are able to tune themselves, that’s an additional externality that ML components have to model. Vendors should remove these features. Internal metrics * Expose DBMS’s hardware capabilities. * Separate metrics for sub-components that are tunable (RocksDB bad example – aggregated metrics). Action engineering * No action should ever require the DBMS to restart in order for it to take effect. * Provide a notification to indicate when an action starts and when it completes – need to know whether degradation is due to deployment or bad decision. * Allow replica configurations to diverge from each other. ### Oracle rant ### Main takeaways True autonomous DBMSs are achievable in the next decade. For anybody who’s working on database systems – you should think about how each new feature can be controlled by a machine. ================================================ FILE: content/highload/19/njs-nginx.md ================================================ --- title: "njs ‒ родной JavaSсript-скриптинг в nginx" author: "Дмитрий Волынцев, Nginx, Inc." tags: ["Highload", "2019"] summary: | Современный proxy-server уже умеет: * балансировать нагрузку * TLS-терминирование, * отдавать статику, * кешировать. --- (модуль для создания переменных и обработчиков стадий запроса на JavaScript) # Скриптинг в nginx Современный proxy-server уже умеет: * балансировать нагрузку * TLS-терминирование, * отдавать статику, * кешировать. Сервисы делятся на микросервисы. Теперь мы движемся от прокси к API-gateway. Теперь nginx умеет ещё и в авторизацию. ![njs-nginx 1](../../../images/highload19/njs-nginx-01.png) Авторизация средствами прокси: nginx проверяет специальный токен. * Если токена нет, перенаправляет пользователя к identity provider. * Если токен есть и это верный токен, то пользователь авторизован и получает доступ к сервисам. Выбор: либо реализовать логику авторизации самостоятельно на низкоуровневом языке, либо...? ## Что не так с openresty? Вот что: * Создаётся отдельной командой с другим подходом к философии разработки. Так, в nginx философия такая: все директивы — это кирпичики, которые хорошо сочетаются между собой. А в openresty директивы — это самостоятельные ad-hoc решения. Чтобы написать на нём своё решение, надо хорошо знать openresty. И ещё директивы могут не работать друг с другом. * одна виртуальная машина на воркера (до 3Gb памяти на воркера). При этом у воркера могут быть десятки тысяч соединений в секунду. Если там появится нетривиальная логика, всё может упасть. * язык Lua — это ограничение: * узкая ниша; * синтаксис своеобразный, индексация массивов с 1 (еретики!); * язык не развивается. # Цели проекта Хочется написать своё решение, в котором не будет недостатков openresty. Вот, что нам важно: * Использовать популярный язык программирования. * Быстрый и легковесный, nginx way. * Безопасность и устойчивость. Выбрали JavaScript: * Все знают JS, это современный lingua-franca. * С-подобный синтаксис, который хорошо ложится на конфиги в nginx. * Язык активно развивается, ежегодные релизы, заимствует хорошее из других языков. * Модель языка хорошо ложится на архитектуру nginx. Чтобы обрабатывать десятки тысяч сообщений в секунду, нужен именно такой механизм. # Интерпретатор njs Так, а зачем делать собственный интерпретатор? * V8 и SpiderMonkey неэффективны для задач внутри nginx. * Duktape предназначен для встраивания в другие процессы. Но он недостаточно быстро для nginx. И он реализует только стандарт языка ES5.1 (это примерно 2009 год). * Свой интерпретатор может быть заточен под особенности окружения. ## Чем njs не является * nginx + njs ≠ application server * полноценной реализацией стандартов ECMAScript тоже не является, хотя работа идёт. Почему njs работает быстро? * Компиляция в байт-код при старте nginx. * Новая VM клонируется для каждого запроса (copy-on-write). * Нет JIT-компиляции. * Нет сборки мусора. Она не нужна, потому что для каждого запроса мы создаём маленькую VM, которая не успевает создать много объектов. Бенчмарк: создаём пустые контексты запроса на основе каждого из интерпретаторов. График логарифмический! ![njs-nginx-2](../../../images/highload19/njs-nginx-02.png) # njs в nginx ## Начало работы ```bash apt-get install nginx nginx-module-njs ``` Пример в докере: [https://github.com/xeioex/njs-examples](github.com/xeioex/njs-examples) ## Напишем hello world nginx.conf: ```nginx #Сначала загрузим с помощью директивы `load_module` load_module modules/ngx_http_js_module.so; #... http { # Директива `js_include` добавляет код из `example.njs`. js_include example.njs; server { listen 8000; location /hello { # Директива `js_content` указывает на имя функции, которая должна вернуть ответ. js_content hello; } #... ``` Код обработчика в example.njs: ```javascript function hello(r) { r.return(200, "Hello world!"); } ``` ## Проксирование запросов с заголовком авторизации Давайте сделаем что-нибудь поинтереснее. Будем проксировать запросы в S3 bucket на амазоне. aws-s3-njs.conf: ```nginx #... # Вот это стандартные вещи, которые уже есть в nginx: location ~* ^/s3/(.*) { set $bucket 'test-bucket'; set $aws_access '...'; set $aws_secret '...'; proxy_set_header Host $bucket.s3.amazonaws.com; proxy_pass http://s3.amazonaws.com; # Но нам ещё нужно вычислить два заголовка: # тут будет дата в специальном формате proxy_set_header x-amz-date $now; # А тут подписать своим ключом путь, на который мы хотим пойти proxy_set_header Authorization "GET $aws_access:$aws_sign"; } ``` И теперь в начало `aws-s3-njs.conf` мы добавляем такое: ```nginx js_set $now now; js_wet $aws_sign aws_sign; #... ``` Эти директивы связывают переменные в конфиге nginx с кодом на JS: aws-s3-njs.njs: ```javascript function now(r) { return new Date().toISOString().replace(/[:\-]|\.\d{3}/g, ''); } function aws_sign(r) { var v = r.variables; var to_sign = `GET\n\n\n\nx-amz-date:${v.now}\n/${v.bucket}/${v.path}`; return require('crypto').createHmac('sha1', v.aws.secret) .update(to_sign).digest('base64'); } ``` Ура, мы сделали подписанный заголовок авторизации. ## Сложные редиректы nginx.conf: ```nginx location / { auth_request /resolv; auth_request_set $route $sent_http_route; proxy_pass http://backend$route$is_args$args; } location = /resolv { internal; js_content resolv; } location = /_add { allow 127.0.0.1; deny all; js_content add; } ``` И такой complex_redirects.js: ```javascript function resolv(r) { var map = open_db(); var mapped_uri = map[r.uri]; // ... r.headersOut['Route'] = mapped_uri ? mapped_uri : r.uri r.return(200); } // пополняем map с парами редиректов function add(r) { var body = r.requestBody; var pair = JSON.parse(body); if (!pair.from || pair.to) { r.return(400, "invalid request: ..."); return; } var map = open_db(); // ... map[pair.from] = pair.to; r.return(commit_db(map)); } ``` ## Отладка Для отладки используем докер: ```bash docker run -i -t nginx:mainline /usr/bin/njs ``` ## Что уже есть в интерпретаторе * ES5.1: * Object, Array, Number, String, Date, Regexp, Function, JSON * exceptions * closures, anonymous functions * >= ES6: * modules, * arrow functions — скоро будет * Extra, OS: * crypto, files ops and more ## Ближайшие планы * Писать код на JS прямо в конфиге nginx, без `js_include`. * Развитие функциональность модулей. * Расширение поддержки стандартов ECMAScript. # Ссылки Репозиторий: [github.com/nginx/njs](https://github.com/nginx/njs) Написать автору вопрос или устроиться на работу в команду njs: ![njs-nginx-03](../../../images/highload19/njs-nginx-03.png) ================================================ FILE: content/highload/19/siberia/docs.md ================================================ --- title: "Как сделать так, чтобы документация не болела" author: "Семён Факторович, Николай Волынкин" tags: ["HighLoad", "2019"] summary: | --- Конспект [митапа](https://www.highload.ru/siberia/2019/meetups#2171805) на [Highload++ Siberia 2019](https://www.highload.ru/siberia/2019). Ведущие: * Семён Факторович, Chief Technical Writing Officer, [documentat.io](http://documentat.io) * Николай Волынкин, технический писатель, [Plesk](http://plesk.com), телеграм-канал [@DocOps](http://t.me/docops) # Определимся с терминами Мы по профессии техписатели, и у нас своя специфика трактовки термина «документация». Техписатели традиционно занимаются той документацией, которая пишется после написания кода — справочники API, руководства пользователя, описание архитектуры и дизайн-решений. Документация, которая пишется до написания кода (ТЗ, спецификации требований), в нашей картине мира — область ответственности системных аналитиков. То, о чем мы сегодня говорим, в большей степени относится к той документации, которая пишется до кода. В архитектурной документации есть такое же разделение: есть доки «как мы хотим сделать» и доки «как мы сделали». # Документация — какая она? Примеры документации из практики участников митапа: * Входные требования * REST API * Как решать типовую задачу Х: дописать модуль, экран, тест... * Sequence diagram как объяснение сложного бизнес-процесса * User stories как постановка задачи разработчику и полуфабрикат для тест-кейсов * Шаблоны GUI, мокапы дизайна * Дока для внешних разработчиков: tutorials, how to * Релиз-план * Installation guide, server deployment * «Паспорт» сервиса: от разработчиков к опсам * README: что это такое, зачем, чьё * Документация в коде * Тесты на Gherkin? # Формальное определение документации Идем в PMBOK, Project management body of knowledge. В проекте есть стейкхолдеры и коммуникации между ними. Аналитики передают информацию разработчикам, пользователи API забирают информацию тоже у разработчиков, потенциальные клиенты имеют вопросы к product owner'ам. Документация — это проектный артефакт, заменяющий или дополняющий личную коммуникацию между двумя конкретными стейкхолдерами проекта. # Что бывает не так с документацией ## Документации нет * нужны ресурсы, чтобы сделать * есть, но плохо доступна * информация искажается Следствия отсутствия документации: * нет механизма подтверждения договоренностей * при устной передаче информация искажается ## Сложно структурировать * как и куда добавлять новую статью, чтобы ее потом нашли? * барьер для поддержки и создания документации слишком высок. Непонятно, как ее писать (и когда), и куда складывать. ## Документация устарела или ошибочна ## Написана так, что извлекать информацию сложно * слишком много аббревиатур и внутреннего жаргона * сложный стиль * термины, непонятные читателю * на языке, который неизвестен читателю * нет примеров использования или иллюстраций Обобщая: документация очень часто не решает задачи принимающего стейкхолдера (неполна, ошибочна, написана для решения другой проблемы). ## Пользователь не хочет читать * хочет решить проблему, а не изучать предметную область * слишком много читать * документация написана не для того, чтобы помочь пользователю * есть конкурирующий канал коммуникации: спросить тимлида проще, чем читать доки ## Документация низкоприоритетна. Обычно в команде разработки есть что ещё поделать. Свободное время идёт на техдолг. Документация хуже регламентирована, чем, например, разработка и тестирование. # Что с этим делать ## Тезисно 1. Четкое понимание, каких двух стейкхолдеров связывает документация, и какую проблему принимающей стороны мы решаем. 2. Инструментальный стек и инструментальные сценарии. * «Чтобы задокументировать API для очередного микросервиса, мы берем OpenAPI и коммитим сваггер-файл вот сюда, назвав его по такой-то конвенции» * «Дизайн-решения по компонентам мы описываем в Confluence и складываем вот сюда» 3. Шаблоны и эталонные примеры документации для повторяемых объектов документирования. 4. Критерии качества и процедуры проверки (как мы проверяем, что в документации нет ошибок? а как мы проверяем, что она полна?) 5. Четкое место документации в цикле разработки. Документация — часть definition of done фичи. 6. Четкие процессы поддержания документации в актуальном состоянии. Нельзя пофиксать баг, не обновив всю релевантную документацию (и не прогнав QA-процесс, подтверждающий, что она действительно обновлена). 7. Documentation owner или documentation champion: человек, которому больше всех не пофиг на документацию, который видит и чувствует, как она должна жить и выглядеть, и у которого есть административные рычаги внедрить пп.1-6 выше или продать все это высшему менеджменту. ## Инструментальный стек Есть барьер на написание документации, во многом психологический. Неясно, как начать. Решение: * инструментальные сценарии и шаблоны документов. «Чтобы документировать микросервис, возьми инструкцию Х, заполни шаблон Y». * критерии качества и проверки документов. Что должно быть в документе, когда мы считаем задачу выполненной. ## Роль документации в общем цикле разработки Если строгого процесса нет, то его нет вообще. * В definition of done фичи входит документация на фичу * Изменение кода и фичи => изменение документации # Вопросы ## Актуализация доки в Swagger Можно считать coverage с помощью Cucumber, проверять что не уменьшилось ## Визуализация диаграмм Есть сложная процессная диаграмма с несколькими представлениями. Как сделать ее читаемой? Человек выходит к чистой доске, рисует диаграмму с нуля и рассказывает. Всё это записываем на видео. ## Внятная opensource-документация Есть опенсорсный продукт. Можно описать всё, но это слишком много. Можно описать часть. Пользователи: * которые онбордятся * которые уже пользуются Решение: посмотреть на практики больших опенсорсных продуктов, например [Google Protobuf](https://developers.google.com/protocol-buffers/). Для новых пользователей делать отдельную документацию. Необязательно текст, можно видео, доклады на конференциях, что угодно. Строим «лесенки» для новых пользователей, по которым они могут зайти в продукт. ## Контекстуальность документации Документация от программистов к программистам очень часто «прячет лес за деревьями»: детали заглушают общую картину. Как надо: «описываемая система — это..., она нужна, чтобы ... и позволит вам сделать...». «Прочитав этот документ, вы сможете...», «по завершению этого документа у вас будет...», «этот документ расчитывает, что вы знаете...» # Что почитать и посмотреть Книга «Пиши, сокращай» Ильяхова и Сарычевой [KnowledgeConf (апрель 2019)](https://knowledgeconf.ru/2019), доклад [Alexandrа White про видеодокументацию](https://knowledgeconf.ru/2019/abstracts/4729). Линтеры для документации: [testthedocs.org](https://testthedocs.org/index.html) Курс по документированию API: [Tom Johnson, Documenting APIs](https://idratherbewriting.com/learnapidoc/) # Продукты с хорошей документацией * Docker: полное описание команд * Bitbucket REST API * [Stripe](https://stripe.com/docs) * [Square](https://squareup.com/us/en/developers) * [Twilio](https://www.twilio.com/docs/) * [Learn Git Branching](https://learngitbranching.js.org/) * [Google Protobuf](https://developers.google.com/protocol-buffers/) * [Gstreamer](https://gstreamer.freedesktop.org/documentation/) # Ещё хорошие практики * Postmortems * [Architecture Decision Record](https://github.com/joelparkerhenderson/architecture_decision_record) * Глоссарий: описание концепта и обозначающих его терминов. ================================================ FILE: content/highload/19/tcp-vs-udp.md ================================================ --- title: "UDP против TCP, или Будущее сетевого стека" author: "Александр Тоболь, Одноклассники" tags: ["Highload", "2019", "Одноклассники"] summary: | TCP задуман как протокол надёжной доставки данных, а UDP — нет. Может ли оказаться, что UDP лучше решит задачу надёжной доставки? --- # Что мы знаем об IP-сетях * Мы отправляем пакеты * черный ящик их пересылает клиенту * клиент собирает пакеты Внутри черного ящика есть уровни: ![tcp-vs-udp-01](../../../images/highload19/tcp-vs-udp-01.png) Давайте сравним TCP и UDP. В них сильно отличается структура пакетов: ![tcp-vs-udp-02](../../../images/highload19/tcp-vs-udp-02.png) Главное: TCP задуман как протокол надёжной доставки данных, а UDP — нет. Может ли оказаться, что UDP лучше решит задачу надёжной доставки? # Цели на сегодня * Как работает сеть * Зачем сравнивать TCP или что с ним не так * С чем и на чём сравнивать TCP * Как это сделал Google * Какое будущее сетевых протоколов нас ждёт Теорию и математику обсуждать не будем. Будем разбирать практические кейсы. # Мобильный мир победил Важно: сначала появились проводные сети, но беспроводные, которые появились позже, сейчас явно победили. Большая доля трафика — мобильный трафик или хотя бы вайфай. В беспроводных сетях бывают потери пакетов, смена порядка и jitter. Протокол TCP/IP скрывает от нас эти ошибки. ![tcp-vs-udp-03](/images/highload19/tcp-vs-udp-03.png) Вот средние параметры соединения у пользователей мобильного интернета. ![tcp-vs-udp-04](../../../images/highload19/tcp-vs-udp-04.png) Итоги: * \> 80% используют беспроводной интернет * парметры беспроводных сетей постоянно меняются * в них высокие показатели packet loss, jitter, reordering * фиксированный асимметричный канал, возможна смена IP-адреса Статистика показывает, что потребление мобильного видео зависит от качества канала. Получается, что TCP не очень эффективен для доставки контента. Пробовали распараллелить загрузку данных с клиента — использовать несколько одновременных соединений. Получается быстрее. Ошибки уменьшают утилизацию канала, а распараллеливание при ошибках помогает увеличить утилизацию: ![tcp-vs-udp-05](../../../images/highload19/tcp-vs-udp-05.png) # Почему нам не подходит TCP Итого: зачем же нужно сравнивать ТCP? * беспроводные сети победили и они нестабильны * потребление контента зависит от скорости интернета (а мы хотим, чтобы пользователи потребляли больше) * TCP плохо утилизирует канл на нестабильных сетях. Распараллеливание помогает, но не всё можно распараллелить. Что с этим делать? * Можно сделать свой протокол рядом с TCP и UDP. И годами ждать, пока его поддержат все участники интернетов. * Или сделать свой надёжный протокол поверх UDP в User Space. получаем smUDP: self-made UDP У разного контента разные профили потребления сети. ![tcp-vs-udp-06](../../../images/highload19/tcp-vs-udp-06.png) # HTTP 1.1 и HTTP/2 Конечно же мы должны сравнить протоколы на HTTP 1.1 и HTTP/2. HTTP 1.1 предлагает использовать по одному соединению на каждую единицу контента. HTTP/2 — одно мультиплексированное соединение. ![tcp-vs-udp-07](../../../images/highload19/tcp-vs-udp-07.png) При этом в HTTP 1.1 клиент (браузер) обычно использует пул соединений. Проблема в том, что между соединениями есть конкуренция. Картинка, которую пользователь уже пролистал и больше не увидит, конкурирует с другой, которая впереди в ленте. И в HTTP 1.1 сложно отменить загрузку — только закрыть сокет и отменить соединение. ![tcp-vs-udp-08](../../../images/highload19/tcp-vs-udp-08.png) HTTP/2 лучше: * бинарный, со сжатием заголовков; * есть мультиплексирование, * приоритизация, * отмена загрузки, * и server push. Приоритизация позволяет получить приоритетный контент раньше: ![tcp-vs-udp-09](../../../images/highload19/tcp-vs-udp-09.png) Server push: сервер может отдать контент, который точно понадобится в будущем. ![tcp-vs-udp-10](../../../images/highload19/tcp-vs-udp-10.png) Отмена загрузки: если клиенту уже не понадобится контент, клиент может отказаться от загрузки. ![tcp-vs-udp-11](../../../images/highload19/tcp-vs-udp-11.png) # Сравниваем TCP и smUDP Итого, на чём нам сравнивать TCP и smUDP * Профили сети: WiFi, 3G, LTE * Профили потребления: * стриминг * мультиплексирвоание и приоритизация с отменой загрузки (в HTTP/2) ## Простая сеть: bandwidth + RTT В TCP важен размер буфера отправки. Сервер держит контент в буфере, пока не получит подтверждение (acknowledgement), что контент получен. Но чем больше RTT, тем дольше ждать подтверждения. ![tcp-vs-udp-12](../../../images/highload19/tcp-vs-udp-12.png) Если мы увеличим размер буфера, то фактическая ширина канала вырастет. ![tcp-vs-udp-13](../../../images/highload19/tcp-vs-udp-13.png) Но всё не так просто. Важны on-the-fly packets. Это те, которые мы отправили, но ещё не получили подтверждения. Если буфер слишком мал, то мы недоиспользуем сеть, как мы уже поняли. Но если буфер слишком большой, то мы приходим к распуханию буфера (bufferbloat). Буфер заполнен кучей on-the-fly пакетов, а скорость снова маленькая. Казалось бы, давайте временно увеличивать буфер, когда нам нужно отправить много пакетов. Но буфер нельзя просто так уменьшить. А если у нас свой протокол, то мы можем: * уменьшать буфер * раньше отправлять более важные пакеты * если клиент отправил cancellation, сбросить пакеты из буфера ![tcp-vs-udp-14](../../../images/highload19/tcp-vs-udp-14.png) Как это делается? Присваиваем отправляемым пакетам сквозной sequence number. Итак: * размер буфера имеет значение * mutable buffer — это хорошо ## Сложная сеть: bandwidth + RTT + packet loss Стандартный алгоритм: если за установленное время сервер не получил acknowledgement, он повторно посылает пакет. Давайте снова будем терять пакеты. Разберёмся, как работает Congestion Control. Для начала, TCP window: количество одновременно отправляемых пакетов. Отправитель начинает с 10 и разгоняется, увеличивая количество. Если в какой-то момент пакеты теряются, он уменьшает окно и снова разгоняется. ![tcp-vs-udp-15](../../../images/highload19/tcp-vs-udp-15.png) Congestion Control придуман для предотвращения перегрузки сети. Вот где-то в сети есть роутер, который больше всего нагружен. Он умный: не ждёт когда совсем перегрузится, а начинает дропать пакеты чуть раньше, чтобы отправитель уменьшил окно. ![tcp-vs-udp-16](../../../images/highload19/tcp-vs-udp-16.png) Вся эта схема придумана давным-давно для проводных сетей. Там потеря пакетов могла означать только одно: где-то перегружен узел, надо снизить скорость. Но в беспроводных сетях не так! Там пакеты теряются просто потому что соединение беспроводное. Получается, есть два типа потерь: * congestion loss, от переполнения * random loss, от плохого беспроводного соединения ## Каким бывает Congestion Control Congestion Control эволюционирует. Нам особенно интересны реализации Cubic и BBR. ![tcp-vs-udp-17](../../../images/highload19/tcp-vs-udp-17.png) Если скорсть растёт, BBR схлопывает окно заранее, Cubic дожидается потери пакетов и тогда схлопывает окно. ![tcp-vs-udp-18](../../../images/highload19/tcp-vs-udp-18.png) Работают они так: * BBR прощупывает размер окна и поддерживает его. За счёт этого получается минимальная задержка. BBR различает congestion loss и random loss. * Cubic работает агрессивно: переполняет буфер до потери пакетов, сбрасывает скорость, потом снова постепенно повышает. ## Совсем сложная сеть: bandwidth + RTT + packet loss + jitter Казалось бы, BBR решит все наши проблемы. Но есть ещё и jitter! Он влияет в том числе на получение acknowledgements от получателя. То есть в некоторых случаях пакет доставляется успешно, но отправитель не успевает получить подтверждение и шлёт пакет снова. BBR уязвим к высокому jitter. Было бы здорово, если бы сервер мог знать jitter клиента. Но в стандартном пакете acknowledgement (ACK Frame) в TCP этой информации нет. Зато мы можем добавить её в smUDP ACK Frame. ![tcp-vs-udp-20](../../../images/highload19/tcp-vs-udp-20.png) Мобильные сети асимметричны. Обычно 70% на приём и 30% на отправку. Стоит разделить jitter на приём и отправку. Какой congestion control выбрать на сервере? ![tcp-vs-udp-21](../../../images/highload19/tcp-vs-udp-21.png) А на клиенте всегда Cubic и мы не можем на это повлиять. Выводы такие: ![tcp-vs-udp-22](../../../images/highload19/tcp-vs-udp-22.png) ================================================ FILE: content/knowledgeconf/19/badoo-new-developers-onboarding.md ================================================ --- title: "Добро пожаловать на борт: вводим в строй новых разработчиков" author: "Глеб Дейкало, Badoo" tags: ["Knowledgeconf", "2019", "Badoo"] summary: | * департамент вырос в 2 раза за последние несколько лет * ожидание от найма и реальность разнятся, так как на онбординг тратится время не только новичка, но и техлида и ментора большой объем новой информации, которую необходимо изучить --- # Проблемы онбординга * департамент вырос в 2 раза за последние несколько лет * ожидание от найма и реальность разнятся, так как на онбординг тратится время не только новичка, но и техлида и ментора большой объем новой информации, которую необходимо изучить # Цели онбординга * краткосрочная - сократить время онбординга * долгосрочная - воспитать в сотрудниках самостоятельность, использование базы знаний вместо опроса коллег # 1 день * важно, чтобы новичка вел ментор, которому можно назвать любой вопрос. у ментора должны быть хорошо развиты софт-скиллы. желательно выбрать заранее. * лид встречает новичка, проводит экскурсию по офису, знакомит с командой и ментором, есть интерактивная карта, где можно посмотреть, кто где сидит * ни новичок, ни ментор не должны тратиться на то, что не относится к их работе. должно быть настроено рабочее место, инструкция, чек-листы и автоматизация того, что не поддается чек-листам, например, получение доступов * инструкция над микроволновкой и кофемашиной - полезная вещь # Способы передачи знаний * все начиналось с личных бесед, полезно, когда нужно объяснить ценности компании или почему мы делаем так, а не иначе. минус - каждому новичку ментор рассказывает одно и то же, но каждый раз по-разному. знания фрагментированы, могут быть неполными, если ментор занят. устный разговор нельзя перечитать. устные беседы не стимулируют к самостоятельности, так как новичок получает конкретный ответ на конкретный вопрос * семинары - сначала проводили, потом записали видео. тяжело актуализировать, в 1,5-2 часа не войдет вся необходимая информация - wiki - первый вариант был плохо структурирован, был объемным, голая теория плохо запоминается без практики, список ссылок тяжело поддерживать в актуальном состоянии - документ Quick Start - текущие реалии. ## Quick start * опирались на практики структурирования документации Laravel. собрали список инструментов и технологий, отсортировали от простого к сложному. один человек расписал первые главы, выработал методику подачи материала и стилистику, создал несколько шаблонов. остальные главы писали старшие разработчики * вместо больших задач стали давать небольшие практические задачи, иногда искусственно выдумывали под разделы, эти задачи выполняются как боевые, но не тестируются и не релизятся. плюс - знакомство с флоу. помогает поддерживает quick start в актуальном состоянии * бонус - полезные инициативы от новичков. один проставил полезные ссылки, второй - estimate на изучение отдельных разделов Quick start * в конце - блоки с более подробной документацией для самостоятельного изучения и более серьезные задачи, контрольные вопросы * на выходе - документ с четкой структурой, идут от простого к сложному, покрыли все нужные темы, получили практические задачи для закрепления знаний, предсказуемое время обучения новеньких. в среднем онбординг занимает 1 месяц * в quick start есть описание взаимодействия с другими командами * первые две недели новичок не вылезает из quick start, ментор не сильно загружен * на прохождение quick start - тикет с сабтасками, иногда подсовывают реальные задачи к учебным * к концу второй недели можно брать реальные задачи * для закрепления знаний - тест из 100 вопросов, для quick start рандомно выбирается 25, опрос анонимный, помогает найти вопросы, которые вызывают большую боль и обновить quick start, к вопросам можно писать комментарии * старички тоже проходят тест, помогает выявить белые пятна, провести ревизию quick start * к концу 1 месяца освоены ключевые знания, есть опыт реальных задач, новичок может брать средние задачи и справляться с ними самостоятельно * через 2-3 месяца system design - проектирование большой фичи, почелленджить требования, расписать архитектуру проекта, презентация решения, на которой проводится брейншторм с коллегами, как решить задачу, задаются каверзные вопросы. после проектирования большой фичи считается, что сотрудник подтвердил свою самостоятельность # В заключение * если штат активно растет, нужно думать об онбординге, большие системы онбординга не имеет смысла строить, если в год приходит 2-3 новых человека * автоматизация и покрытие чек-листами бытовых вопросов * Quick Start - не так страшно и многократно окупается * практические задачи - закрепление и актуальность * тест - позволяет проверить и откалибровать знания * quick start работает и для других команд, вышел за пределы департамента ================================================ FILE: content/knowledgeconf/19/biocad-knowledge-base-development.md ================================================ --- title: "Разработка базы знаний компании, которой действительно пользуются" author: "Екатерина Гудкова, Биокад" tags: ["Knowledgeconf", "2019"] summary: | * биотехнологическая компания, 50% - R&D * необходимо одно место для хранения и переиспользования знаний --- # Исходные данные * биотехнологическая компания, 50% - R&D * необходимо одно место для хранения и переиспользования знаний # Проблемные зоны при построении базы знаний * с точки зрения системы - масштабируемость, соответствие стандартам, структура данных, безопасный доступ * с точки зрения человека - любознательность, ответственность, саморазвитие, осознанность # Подход к построению базы знаний * отталкиваются от набора ролей и компетенций - роли, типовые задачи, компетенции, материалы базы знаний * в каждой команде есть HR-специалист + специалист операционного менеджмента, они собирают данные, которые уходят в ИТ-отдел * для новых сотрудников * индивидуальный план обучения строится под роли * FAQ-бот для часто встречающихся вопросов, вытащили поисковые запросы из портала и добавили в бот, топ-5 - работа с системами, оформление командировки, льготы и компенсации, ролевая модель, глоссарий * для опытных сотрудников * нужно узнавать о новостях области, о коллегах * для каждой роли прописали теги, по текстам строят графовую репрезентацию, используют для поиска, в том числе аномальных связей * информация приходит в новостной бот, есть обязательные теги, на которые подписаны сотрудники, есть рекомендуемые (Universal recommender, открытое ПО) ================================================ FILE: content/knowledgeconf/19/e-learning.md ================================================ --- title: "Естественное развитие: как перейти от e-learning к управлению знаниями" author: "Елена Тихомирова, eLearning Center" tags: ["Knowledgeconf", "2019"] summary: | Большие вложения и мало повторного использования. * Одноразовые курсы. Второй раз пройти почти невозможно. Сложно использовать как справочник. * Не формируется привычка учиться. Разовое обучение не только не даёт нужного результата, но и не формирует привычку пользоваться информацией. --- # E-learning сегодня Большие вложения и мало повторного использования. * Одноразовые курсы. Второй раз пройти почти невозможно. Сложно использовать как справочник. * Не формируется привычка учиться. Разовое обучение не только не даёт нужного результата, но и не формирует привычку пользоваться информацией. * Сложный трансфер в рабочую деятельность. После обучения трудно соединить изученное и то, как это применять в рабочем процессе. Мало кейсов. # E-learning на самом деле * Захват знаний экспертов. Разработка курса внутри компании — это сохранение знаний. * Обмен знаниями: передача и сохранение. Три новых инструмента * Многоразовые курсы. Должны позволять переиспользовать их. Для этого нужна структура и поиск. * Storytelling. Сбор кейсов из реальной практики, примеры для развития контента курсов. * Курируемый контент. Наполняем внешними и внутренними источниками, постоянно поддерживаем осведомлённость. Обучение и управление знаниями хорошо работают вместе. ================================================ FILE: content/knowledgeconf/19/holistic-km.md ================================================ --- title: "Холистическое управление знаниями в IТ-компании" author: "Алексей Сидорин, КРОК" tags: ["Knowledgeconf", "2019"] summary: | Есть разные пути по созданию системы управления знаниями: сверху и снизу. Хорошо это работает совместно (30% сверху на 70% снизу). Перед началов надо определить, что такое управление знаниями. Управлением знаниями можно бороться: --- https://knowledgeconf.ru/2019/abstracts/4918 Начали с видео из Игры престолов. Серсея против Мизинца - экономика ресурсов против экономики знаний. В экономике знаний важен человек. Каждая компания выбирает экономику для себя:) ## С чего начать? Есть разные пути по созданию системы управления знаниями: сверху и снизу. Хорошо это работает совместно (30% сверху на 70% снизу). Перед началов надо определить, что такое управление знаниями. Управлением знаниями можно бороться: * с двойной работой, чтобы не совершить второй раз ошибку * сложным поиском из-за того, что не знаем где актуальное * сложность масштабирования знаний Средства: горизонтальные связи, тиражирование знаний и координация усилий. ## Методология 3 пути: методологический, культурный и технический. Сначала понимаем, как работают процессы, где нужнее всего знания, разбираем барьеры к управленияю знаниями. Потом определяем пользователей базы знаний и какие у них сценарии. В конце появляется платформа и вовлечение сотрудников. Матрица знаний нужна, чтобы понимать с какой информации начать. Для каждой ячейки матрицы нужно выбрать свои инструменты работы. Типы знаний: * есть формализованные знания, которые созданы специалистами знающими в области * полуформальные знания, это когда тебе их кто-то порекомендовал * экспертные, никто не подтверждает, но человек, например ведет блог по теме ## Геймификация В Кроке много разной, примеры: * после участия в проекте участники дают баллы коллеги, субъективно, но помогает реально оценить тех, кто перформит * по фото угадать имя или департамент коллеги, Тоже за баллы ## ТЗ на систему знаний Профили сотрудников и лендинг платформа. От лендинг платформы нужны: быстрое создания страницы, совместная работа над документами, сообщества, нематериальная мотивация, поиск,обратная связь… У компании Крок есть Jive для управления знаниями, при этом жив Confluence. Лендинги на тильде. Слак+телеграм. ## Итого * Это всегда небезопасно * Автоматизация ради автоматизации * Изменения ради изменений ================================================ FILE: content/knowledgeconf/19/km-efficiency.md ================================================ --- title: "Проектирование показателей эффективности отдела по управлению знаниями" author: "Ольга Искандирова, Открытый портал | тренинги и курсы" tags: ["Knowledgeconf", "2019"] summary: | Дано: * 400 изменений в месяц * задача от бизнеса не останавливая работу провести оптимизацию * высока конкуренция, услуга компании может быть легко скопирована конкурентами за неделю --- https://knowledgeconf.ru/2019/abstracts/4873 ## Кейс компании "Паровозофф" Дано: * 400 изменений в месяц * задача от бизнеса не останавливая работу провести оптимизацию * высока конкуренция, услуга компании может быть легко скопирована конкурентами за неделю Мы должны вписать новые процессы по управлению знаниями с привязкой к показателям бизнес-подразделений. Для компании важна скорость (так конкуренты могут быстро скопировать услугу) и точность (неточность приводит к увеличению числа жалоб в поддержку). ## Мысль 1 > Управление знаниями повышает стоимость компании Но люди врут и ошибаются, не со зла. Вывод: нужно мимнимизировать ошибку. Что делаем для "Паровозофф": KPI на критичные показатели об ошибках (количество ошибок при консультации, количество ошибок в контенте) ## Мысль 2 > Интеллектуальный капитал Строим для себя модель Wiig, определяем по ней что делаем и на какие показатели это влияет. Вывод: нужно явно обозначать процессы. Что делаем для "Паровозофф": Описали процессы и согласовали их со всеми участниками. ## Мысль 3 > За процесс должен кто-то отвечать Без этого никто не будет делится знаниями в вашей компании. Вывод: нужен человек, который будет отвечать за управление знаниями. Что делаем для "Паровозофф": Назначили ответственных и определили их зоны. ================================================ FILE: content/knowledgeconf/19/km-system-and-business.md ================================================ --- title: "Как внедрить систему управления знаниями в бизнес" author: "Владимир Лещенко, Роскосмос" tags: ["Knowledgeconf", "2019"] summary: | Зачем внедряют системы управления знаниями? 1. Чтобы отчитаться: ПИР, стандарт ISO, акционеры. 1. Чтобы было: это модно, CEO захотел, есть иллюзии. 1. Чтобы заработать: нематериальные активы, продукты, тендеры. --- Зачем внедряют системы управления знаниями? 1. Чтобы отчитаться: ПИР, стандарт ISO, акционеры. 1. Чтобы было: это модно, CEO захотел, есть иллюзии. 1. Чтобы заработать: нематериальные активы, продукты, тендеры. Иллюзии: * СУЗ — это решение проблем компании. * СУЗ начинается с HR Если начать с HR, оно там и останется. * Все хотят систему управления знаниями. Нет, это обуза и неизвестность, пока не станет отлаженным бизнес-процессом. # Вопросы для начала работы Чтобы проектировать СУЗ, нужно ответить на ключевые вопросы: * Какое состояние компании в текущий момент? Провести аудит зрелости компании. * Инновационность продукции и услуг. * Средний возраст сотрудников. * Состав капитала компании. ================================================ FILE: content/knowledgeconf/19/knowledge-manger-6-10.md ================================================ --- title: "10 компетенций и 6 ролей Knowledge Manager" author: "Мария Мариничева" tags: ["Knowledgeconf", "2019"] summary: | * Обучение и развитие * Управление информацией * Социология * Управление изменениями --- # Компетенции * Обучение и развитие * Управление информацией * Социология * Управление изменениями * Управление персоналом * Информационные технологии * Библиотечное дело * # Стандартные роли ## Архитектор, разработчик Стратегия и тактика управления знаниями. Выполняет задачи и кандидат на роль Chief Knowledge Officer. Политики, процедуры и форматы. Системы и структуры ресурсов. Выбор IT-решений. ## Исследователь, аналитик Проводит аудит знаний, определяет информационные потребности и способность самообучаться. Аналитические услуги для «внутренних клиентов» ## Продавец, коммуникатор, информатор Продаёт идею КМ, доносит ценности, задачи, смысл изменений. Информирует о новых возможностях. ## Организатор, фасилитатор Часто бывает менеджером проекта по управлению знаниями. Фасилитирует понимание стратегии и тактики. Модерирует дискуссию и «извлечение уроков». Организует и модерирует сообщества, сессии, встречи для обмена опытом. ## Навигатор, поисковик Знает, кто что знает и где что найти. Указывает путь к ресурсам знаний. Может искать информацию по запросу или составлять карту знаний. ## Наставник, учитель Обучает других. # Что с этим делать В зависимости от задачи может быть совсем разное распределение ролей. Например, в оргкомитете Сочи-2014 половина задачи — роль архитектора. А в Ernst & Young преобладали роли организатора, навигатора и учителя. Многое зависит от точки отсчёта: где находится компания и насколько сформирована в ней культура управления знаниями. Ещё важна бизнес-задача, которую решают с помощью управления знаниями. ================================================ FILE: content/knowledgeconf/19/knowledge-sharing-involvement.md ================================================ --- title: "Как вовлечь всех сотрудников ИТ-компании в обучение новичков и друг друга" author: "Анна Тарасенко, 7bits" tags: ["Knowledgeconf", "2019"] summary: | В компании пробовали нанимать людей с рынка (как все). Столкнулись с проблемой, что у специалистов с рынка недостаточный уровень знаний, а денег хотят много. Например, нет знаний даже базовых алгоритмов. Еще все хотят работать из дома. Решили, что нет смысла ждать своего человека -> надо растить своих специалистов. --- https://knowledgeconf.ru/2019/abstracts/4655 Задачи компании-аутсорсера: * операционная деятельность * поиск новых проектов * найм Доклад будет про найм. В компании пробовали нанимать людей с рынка (как все). Столкнулись с проблемой, что у специалистов с рынка недостаточный уровень знаний, а денег хотят много. Например, нет знаний даже базовых алгоритмов. Еще все хотят работать из дома. Решили, что нет смысла ждать своего человека -> надо растить своих специалистов. ## План А Обучение студентов в институте. Не сработало. Студенты прогуливали занятия, большой спрос на студентов. ## План Б Практика на лето для студентов. Не сработало. Студентов взяли в штат на время. Задачи сложно подобрать, старшие специалисты не сильно занимаются студентами. ## План В Стажировка, делают свой проект или стартап внутри. Сработало, но отказались от идей самих студентов и перестали делить разработчиков на фронтенд и бэкенд. Инсайт в процессе: школьники не понимают, что такое IT. Поэтому сделали конференции, где рассказывют об этом школьникам. И стали звать туда родителей. ================================================ FILE: content/knowledgeconf/19/manager-analyst-km.md ================================================ --- title: "Как из менеджера сделать аналитика: опыт подготовки инженеров по знаниям" author: "Татьяна Альбертовна Гаврилова, Высшая школа менеджмента СПбГУ" tags: ["Knowledgeconf", "2019"] summary: | О чём доклад * Мистер/Мисс Х: Аналитик * Information Science & Knowledge Engineering * Акцент на визуально-аналитическом мышлении * Подготовка аналитиков --- О чём доклад * Мистер/Мисс Х: Аналитик * Information Science & Knowledge Engineering * Акцент на визуально-аналитическом мышлении * Подготовка аналитиков Кто такой аналитик? Это тот, кто думает, как жить дальше, пока технари налегают на вёсла. Системный взгляд на управление знаниями. 1. Охват: личный, корпоративный и отраслевой 1. Теоретические аспекты: организационный, технологический, информационный 1. Практики 1. Жизненный цикл: создание, кодификация, извлечение и структурирование, хранение, распространение. 1. Профессионалы: бизнес-аналитик, менеджеры знаний, инженеры по знаниям, когнитологи, CIO Задача — перейти от хаоса к структуре, которой можно делиться. Уровни категоризации: 1. Мета-категориальный. Уровень высокой абстракции, работа с классами понятий. 1. Базовый. Уровень средней абстракции, работа с понятиями. 1. Суб-категориальный. Низкая степень абстракции, работа с объектами. Information Science — это наука о процессах хранения и передачи информации. Она объединяет библиотечное дело, информатику, лингвистику и психологию. Artificial intelligence ≠ искусственный интеллект. Intelligence — это способность рассуждать разумно, но это не интеллект. Самое главное в интеллект-картах (mindmap) — это выделить первый уровень. На нём не должно быть слишком много объектов, иначе это ошибка обобщения. ================================================ FILE: content/knowledgeconf/19/multimedia-documentation.md ================================================ --- title: "How to Create Compelling Multimedia Documentation" author: "Alexandra White, Google" tags: ["Knowledgeconf", "2019"] summary: | * Images and gifs. * Video documentation. * Great for making complicated concepts seem simple. * But much more expensive to produce. * Webinars and recorded trainings. --- # What is multimedia * Images and gifs. * Video documentation. * Great for making complicated concepts seem simple. * But much more expensive to produce. * Webinars and recorded trainings. ## When should you make a video? * Documentation is complete * Describing complicated concepts * Long processes with completed UI * Marketing * Big revenue clients who want videos * For internal training ## When to make webinars * Marketing strategy * Repetitive internal training * Process takes 10+ minutes * Multiple outcomes * Seeking feedback ## When not to make a video * No time to learn the software * Unfinished product, UI changes a lot * Small audience, low revenue * When you have no content strategy (so the video would look unprofessional) # Making a video ## How to write your script * Tell a story * Break ideas into sectinos * Avoid buzzwords and complex language * Read it out loud and listen to yourself ## Get approval Just get approval for the whole idea. ## Creating a storyboard Write the text for each frame/fragment of the video. Animations at Google: * A team of three people * 40-60 hours to create 1 minute video. ## Style and branding Style guidelines include: * Logos * Color * Typography * Voice & tone. E.g. “friendly and respective”. Voice and tone of a video should match those of the whole company. Be consistent! Set high expectations and keep to them. Respect employees like customers and make the same high quality content for them. ## Quality * Use high quality audio * Test everything * Price of the software doesn't mean much, but the skill of the editor (person) is crucial. # Making a profit Did the video bring more revenue than cost? * Analytics for the video * Analytics in the docs * Customer service tickets * Get feedback # Getting feedback Active feedback: * written comments * thumbs up & down * clicking some button Passive feedback * Collect analytics * Monitor user behaviour # Ask the right questions # Final takeaways * Be brief * Get approval * Use a style guide * Test everything * Learning how to use a tool properly is better than spending money on fancy tools ================================================ FILE: content/knowledgeconf/19/ozon-fast-growth-and-knowledge-sharing.md ================================================ --- title: "Управление знаниями при быстром росте компании" author: "Мария Смирнова, Ozon" tags: ["Knowledgeconf", "2019"] summary: | * 400+ компонентов, 20 лет компании, большой объем знаний * база знаний нужна для техподдержки, для новых разработчиков --- # Исходные данные * 400+ компонентов, 20 лет компании, большой объем знаний * база знаний нужна для техподдержки, для новых разработчиков # Пошаговый план * среда для базы знаний -> неактуальные знания -> стандарты и новые знания -> вовлечение разработчиков -> оценка качества документации ## Шаг 0. Среда для базы знаний * было confluence + gdocs + word. попробовали onebar и локальный stackoverflow. вернулись к confluence, чтобы не травмировать разработчиков ## Шаг 1. Неактуальные знания * было 22460 страниц, разбирали руками, осталось 10365 страниц, позже стало 12028. процесс замедлился, идеально актуального и чистого пространства не получилось ## Шаг 2. Стандарты и новые знания * создали стайлгайды и шаблоны, зафиксировали договоренности. должны быть простыми, понятными и короткими. * термин, how-to, страница сервиса и инструкция - шаблоны * новые знания - глоссарий, база знаний для 1 команды, описание архитектуры ## Шаг 3. Разработчики (как привлечь?) * писали на общую рассылку, рекламировали сделанные работы другим командам * DoD = база знаний, команда сама вносит правки, если необходимо * deadline driven documentation - пишем -> публикуем -> фидбек -> правки -> пишем, метод сработал, разработчики писали комментарии, говорили, где нужно обновить * как привлечь - сарафанное радио, сначала заработать репутацию ## Шаг 4. Оценка качества документации * взяли метрики - актуальность, посещаемость, снижение затрат на техподдержку, не подошли. * решили измерить охват - количество команд, с которыми работали. * также измерили используемость - 80% документации живая. # Итого * 4 базы знаний, стайлгайд и шаблоны, глоссарий, описание архитектуры, описание архитектуры * осталось 4387 неразобранных страниц * ушло 6 месяцев и 2 технических писателя ================================================ FILE: content/knowledgeconf/19/tiago-forte-practices.md ================================================ --- title: "Применение практик Тиаго Форте для управления своими знаниями" author: "Андрей Александров, Express42" tags: ["Knowledgeconf", "2019"] summary: | Прочитал полезную статью или послушал доклад. Как запомнить полезное? --- # Мы всё забываем Прямо как рыбки. А бывает, что хотелось бы помнить. Что с этим делать? Прочитал полезную статью или послушал доклад. Как запомнить полезное? * Запоминание требует много времени * Нужно много источников * Не всё можно опубликовать * Спустя время не хватает контекста * Нужен оригинал. Можно писать конспекты. Но они не идеальны. Перечитываешь оригинал — понимаешь новое. Можно записывать одни цитаты. Но, вырванные из контекста, они бесполезны. Нужно скопировать абзац до и абзац после. А лучше — главу до и главу после. # Тиаго Форте Тиаго — мудрая черепаха. Организовал движение «Second brain». Попытка выработать подходы, чтобы всё оцифровать и хранить в компьютере. Он становится основным инструментом управления знаниями. ## Progressive summarization Первая практика. Конспект над конспектом над конспектом... Берём книжку, загружаем её в читалку, пишем конспект прямо поверх неё. Слои: 1. Оригинальный текст. 1. Bold passages: выделить жирным ключевые фрагменты. На следующем прочтении мы будем читать это быстрее. 1. Highlight passages. Подчеркиваем цветом конкретные ключевые фразы. 1. Mini-summary. Пишем мини-конспект. 1. Remix. Почему это работает: * Легко добавлять слои * Оригинал всегда перед глазами * Читаем с нужным уровнем погружения. * Распознаем быстрее: по одной детали узнаём весь контекст. * Когда не хватает понимания, спускаемся на уровень ниже. ## Практика В программе для заметок сложно читать книгу целиком. Поэтом разбиваем: 1 глава = 1 заметка. Закидываем это в читалку MarginNote. Оттуда результат в Evernote. При первом прочтении заполняем слой первоначального выделения (полужирным или желтым фоном). Потом при втором прочтении — выделяем конкретные фразы красным фоном. На выходе из MarginNote получается PDF, а Evernote умеет по нему искать. Проблемы: * Добавлять новые слои при каждом прочтении — это долго. * Как помнить, что уже есть в собственной базе знаний? Для этого есть практика RandomNote. ## Random Note Открываем случайную заметку, смотрим, оцениваем, обновляем. ## Как начать применять 1. Скопируйте в заметочник 1. Прочитайте и выделите первый слой 1. Отложите заметку! Не заполняйте все слои сразу. Когда добавляешь новые слои спустя время, получается гораздо лучше. Выделений получается меньше, так что перечитывание статьи будет быстрее. ================================================ FILE: content/knowledgeconf/19/trello-kb.md ================================================ --- title: "Trello — эффективная система управления знаниями для небольшой IT-команды" author: "Роман Хорин, Atman Digital" tags: ["Knowledgeconf", "2019"] summary: | 1. Молодой команде нужно быстро расти 1. Для этого требуется место, где собраны все референсы 1. Создание такого места капитализирует опыт команды и ускоряет рост сотрудников --- ## Три вида сайтов * Совсем сложные * Уникальные лендинги * Типовые лендинги ## С чем столкнулись 1. Молодой команде нужно быстро расти 1. Для этого требуется место, где собраны все референсы 1. Создание такого места капитализирует опыт команды и ускоряет рост сотрудников Почему выбрали Trello * Легко систематизировать внешние ссылки, из которых и состоит база знаний дизайнеров ## Конкретно Первый этап — разделение по процессу. Заголовки списков в трелло — этапы процесса: аналитика и аудит, прототипирование, референсы и мудборд, отрисовка дизайна и так далее. Второй этап — разделение по типам материалов. Например: «вдохновение: сайты», список сайтов где публикуют хорошие работы. Третий уровень — чекбоксы: описание + ссылка ## Особенности базы знаний * Вся база знаний построена на ссылках. Для дизайнера наиболее важен визуальный опыт. Нужно только его оцифровать и сделать доступным. * База загрязняется, поэтому нужен модератор, который следит за чистотой. Как знание попадает в базу: 1. Кто-то увидел интересный материал и поместил его в распределитель. Есть вкладки «точно полезно» и «может быть полезно». 1. Модератор проверяет все добавленные ссылки и сортирует их. 1. Материал попадает в базу. Столкнулись с проблемой. Сначала заполнять базу был просто, потмоу что был энтузиазм. Но через несколько недель все кроме модератора забывают, что есть база. Решили проблему с помощью уведомлений и напоминаний. Когда в базу добавляется ссылка, в чат приходит уведомление. На еженедельном созвоне задаём вопрос: а что нового мы узнали, что можно было бы добавить в базу. # Что получилось хорошо * материалы хорошо структурированы * базу легко редактировать и пополнять * есть инструкция по применению * есть система напоминаний, которая стимулирует команду наполнять базу * есть распределитель, который фильтрует бесполезное * каждый член команды может участвовать в процессе наполнения знаний # Что получилось плохо * К знаниям можно давать только короткое описание. Сложно охарактеризовать ссылку кратко, ёмко и уникально. * база не очень удобна для размещения видео, фото и текста * есть риск, что члены команды удалят материалы или добавят лишнее * в базе нельзя автоматически контролировать битые ссылки * у команды есть склонность добавлять в базу статьи-агрегаторы, но они не несут пользы. Это лишний уровень агрегации. * без доступа к интернету база недоступна. # Выводы и рекомендации * База знаний в виде ссылок удобна для команды дизайнеров * Трелло позволяет быстро организовать сбор данных * Чем опытнее специалисты, тем реже они пользуются базой знаний. Зато новички пользуются активно. * Без системы уведомлений активность в базе знаний затухает. * Базу удобно использовать в качестве хранилища идей. * Если рабочее пространство базы (Trello) не связано с другими, то активность в базе затухает. ================================================ FILE: content/knowledgeconf/19/voluntary-forced-knowledge-sharing.md ================================================ --- title: "Не хочешь мокнуть – плыви: добровольно-принудительный обмен знаниями" author: "Мария Палагина, Тинькофф Банк" tags: ["Knowledgeconf", "2019"] summary: | * обмен знаниями - катализатор развития * два способа обмена - демократический и диктаторский --- # Исходные данные * всего 350 QA, 120 - в отделе привлечения * 1500 технических специалистов, быстрый рост - в 1,5 раза за два года * никто не хочет переключения контекста и дублирования работы (велосипеды) * 15 минут занимает одно переключение контекста, большая трата времени при частом переключении # Способы обмена знаниями * обмен знаниями - катализатор развития * два способа обмена - демократический и диктаторский ## Демократический * включает новостные рассылки, внутренние конференции, демо внутри отдела, базу знаний * новостные рассылки работают, когда их есть кому рассказать * внутренние конференции - было 2 итерации, первая неудачная. проводили целый день, любые доклады. в месяцы конференций выпускали на 1 релиз меньше, чем в остальные месяцы, это -25% продуктовых фич. не было переиспользования, цели не достигли * вторая попытка в новом формате "завтраки". начало в 9.30-10 утра, занимает мало рабочего времени, только внутренние сотрудники, реальность без купюр, только заинтересованная аудитория -> правильный фокус, можно сразу применить на практике * демо внутри отдела. фокус на задачах функциональной команды, переключение ресурсов, формирование новых команд, например, для завоза мутационного тестирования * база знаний - один вход, фильтры по тегам, регламент для расширения базы знаний - опиши, что добавил, навесь теги. самообучение, дала толчок к ведению документации. * плюсы демократического подхода - правильная атмосфера, знакомство людей. минус - тратится много времени, 8 ч в неделю ## Диктаторский * включает дежурства в другой команде, индивидуальные и командные планы развития, голодные игры * дежурства по продукту в другой команде, которая связана с текущей работой QA стеком или задачами. 10% команды, 20% рабочего времени, на один день. есть план работ, по которому надо отчитаться. плюсы - новые навыки, разнообразие, новые знания о своем продукте. команда получает объективный фидбек, усиление команды, более устойчивая команда, перераспределение ресурсов, объективная обратная связь * планы развития - оценка себя -> оценка ментора -> синхронизация оценок -> выбор, что качать -> задача в план. планы открытые, со списком полезностей, связь с командным планом развития * командный план - командный челлендж, например, завести CI/CD -> декомпозиция -> синхронизация с индивидуальными планами -> выполнение. * плюсы планов - развитие, пополнение базы знаний, правильная атмосфера * голодные игры - проводятся утром или перед обедом. теория -> изучение -> проверка знаний. плюсы - проверка группы людей за один раз, меньше стресса при формате игры, интеграция в коллектив * плюсы диктаторского подхода - система контроля, легко проводить performance review, возможность прокачать команду, которая была не заинтересована в развитии. минусы - демотивация, паранойя, подтасовка результатов, отсюда, применяется вместе с демократическим # Результаты * ожидаемые результаты - быстрое внедрение новых решений, использование opensource-проектов, уменьшение парка технических решений, рост компетенций, публичные выступления * неожиданные результаты - увеличилось количество горизонтальных переходов, люди сами предлагают применить свои скиллы максимально эффективно, увеличилась кроссфункциональность команд ================================================ FILE: content/knowledgeconf/19/xi-notes-for-developer.md ================================================ --- title: "Как я 15 лет делал себе персональную Wiki для программиста" author: "Григорий Петров" tags: ["Knowledgeconf", "2019"] summary: | 2 типа инструментов: * WYSIWYG, например, Google Doc, Word, и т.п. * Lightweight Markup Language, например, markdown, которые можно писать в любом редакторе. --- ## Существует два типа инструментов * WYSIWYG, например, Google Doc, Word, и т.п. * Lightweight Markup Language, например, markdown, которые можно писать в любом редакторе. Программисты предопочтивают второе, потому что пользуются vim, emacs, кучей разных шорткатов. Пример такой софота, который работает через Markup Languages и предназначен для wiki: Wikipad. ## Григорий когда использовал Wikidpad * 10-15 записей в день * Текст часто меняется * С заголовками и параграфами проблема, при чтении не видно вложенность В итоге Григорий пришел к собственному синтаксису, похожему на markdown. Синтаксис параграфов работает как блоки в pyton. Отступ это вложенный параграф или вложенный список. Максимальная вложенность -- 6 ## Еще разработчики привыкли к дереву файлов(outliner) Однако, записи программиста это не дерево, а граф. Outliner не умеет это отображать, а поиск по контенту работает лучше чем поиск по outliner. ## Плагин Сейчас Xi существует в виде плагина для раскраски синтаксиса, позволяет кликать на слова. Каждая статья -- 1 файл. Outline`а в привычном виде нет, он переехал в начало статьи, сделан в виде ссылок на другие статьи, связанные с темой статьи. Сейчас плагин работает в VSCode, существует отдельная цветовая схема, в которой много контрастных цветов для более гибкого обозначения типов контента. Отдельные цвета для терминов, уровня вложенности, кода, списков, примеров и т.д. За основу взята темная тема, синтаксис разметки тоже сделан темным, чтобы сливаться с фоном редактора и не мешать во время чтения заметки. ## Фичи * Ссылки в xi поддерживаются через хеши. Т.е. можно сделать ссылку на заголовок другой статьи через якорь * Термины выделяются пайпом `|` * На очень важные вещи, на которые обязательно нужно обратить внимение, используется вырвиглазный цвет :) * Все что после вертикальной черты -- код * Списки ничем не отличаются от параграфа, можно использовать любой символ: #, \*, ! и т.д. * Есть аналог тегов * Поиск работает через regexp по контенту, тегам, заголовкам Для таблиц и картинок используются Google Drive и Google Sheets. ## Выводы * Развитие базы знаний это серьезная инвестиция, которая нужна не всем * Окупается, если задачи повторяются * Хорошо работает, если языков много ================================================ FILE: content/moscowpython/19/accelerate-python.md ================================================ --- title: "Что делать, если ваш код на Python тормозит" author: "Григорий Бакунов, Яндекс" tags: ["Moscow Python Conf", "2019", "Яндекс", "Python"] summary: | Когда в списке `resp` оказываются сотни тысяч элементов — а их реально столько — программа внезапно очень медленно работает. 10 000 сообщений: --- > «Если хочешь делать что-то большое в каком-то интересном тебе проекте, то ты обязан разбираться в его кодовой базе и понимать, что там происходит. А если ты сам код не пишешь — ну как ты будешь разбираться в кодовой базе?» # Введение Изначальный код, в котором не всё в порядке: ```python from copy import copy def crc_code(text: str) -> int: res = 0 for x in text: res += ord(x) return res def send_notification(respondents: list, message: dict) -> None: for resp in respondents: to_send = copy(message) if "subject" not in to_send: to_send["subject"] = "Hello, " + str(resp) if "from" not in to_send: to_send["from"] = None to_send['body'] = to_send['body'].replace('@respondent@', resp) to_send['crc'] = crc_code(to_send['body']) # rpc_real_send(to_send) ``` Когда в списке `resp` оказываются сотни тысяч элементов — а их реально столько — программа внезапно очень медленно работает. 10 000 сообщений: ``` * simple 1.69s. * with subject 1.68s. * with from 1.70s. ``` Возьмём это время 1.69s за эталон, 1х. # Cython Будем ускорять код, не особо его оптимизируя. ```bash $ cythonize -a -i modulename.pyx ``` Результат: ``` * simple 0.5610x * with subject 0.5391x * with from 0.5837x ``` # PyPy PyPy — альтернативный интерпретатор с другим подходом к интерпретации языка. Раньше нижняя строчка была больше, а теперь она меньше. ``` * simple 0.1040x * with subject 0.0912x * with from 0.0809x ``` # numba Ок, теперь давайте попробуем менять код. Используем [numba](https://numba.pydata.org/): ```python @jit(nogil=True, cache=True) def crc_code(text: str) -> int: ... @jit(nogil=True, cache=True) def send_notification(respondents: list, message: dict) -> None: ... ``` Стало хуже! ``` * simple 1.440x * with subject 2.197x * with from 1.912x ``` Это неспроста. Цель numba — ускорять работу с научными приложениями и бигдатой. Фокус на обработке большими списками и другими структурами данных. А при работе со строками становится хуже. Из официальной документации: > Optimized code paths for efficiently accessing single characters may be introduced in the future. # Вынести операции из цикла Похоже, придётся менять код. Если внутри цикла есть операции, которые можно не выполнять внутри цикла, обязательно выполняйте их вне цикла: ```python def send_notification(respondents: list, message: dict) -> None: to_send = copy(message) no_subj = "subject" not in to_send if "from" not in to_send: to_send["from"] = respondents[0] for resp in respondents: if no_subj: to_send["subject"] = "Hello, " + str(resp) to_send['body'] = message['body'].replace('@respondent@', resp) to_send['crc'] = crc_code(to_send['body']) # rpc_real_send(to_send) ``` Результат так себе: ``` * simple 0.9633x * with subject 0.9457x * with from 0.9446x ``` Когда правишь очевидные вещи, не выигрываешь в производительности. Надо профилировать. В нашем коде больше всего тормозит самописная «контрольная сумма», которая на самом деле просто сумма. # Go Можно было бы взять [grumpy](https://github.com/google/grumpy) и конвертировать код на Python в код на Go. Но он поддерживает только Python 2.6. И не работает. Ок, есть программа для биндинга кода на Go — [pybindgen](https://github.com/gjcarneiro/pybindgen). Пишете программу на Go, а pybindben генерит биндинги, чтобы обращаться из Python. Проблема в том, что код работает медленнее, чем на Python 3.7. # Nim Попробуем [nim](https://nim-lang.org/) и [nimpy](https://github.com/yglukhov/nimpy). Вот это мы напишем прямо посреди кода на Python. ```nim import nimpy proc crc_code(text: string): int{.exportpy.} = var res = 0 for x in 0..text.len-1: res = res + ord(text[x]) return res ``` ```bash $ nim c --app:lib --out:crc.so crc.nim ``` Результат примерно как с PyPy: ``` * simple 0.1199x * with subject 0.0968x * with from 0.1085x ``` Но ради этого результата придётся тащить в свой код на Python код на другом языке программирования. Готовы ли вы к этому? Готова ли команда? А вот Григорий готов! # Снова Cython Давайте перепишем контрольную сумму с использованием кода на Cython. Было: ```python from copy import copy def crc_code(text: str) -> int: res = 0 for x in text: res += ord(x) return res ``` Стало: ```cython def crc_code(text: str) -> int: data_text = text.encode('UTF-8') cdef char* c_text = data_text cdef bint res = 0 for x from 0 <= x < len(data_text): res += c_text[x] return res ``` Важно: Cython плохо совмещает вызов функций из Python и из C в одной строке. Поэтому здесь `encode` и присваивание разнесены на две строки: ```cython data_text = text.encode('UTF-8') cdef char* c_text = data_text ``` Результат: ``` * simple 0.0135x * with subject 0.0114x * with from 0.0126x ``` Cython и Nim работают похожим образом: созадют код на C, из которого потом компилируется бинарник. При этом в Cython код получается почти таким же, как если сразу писать на C. А накладных расходов на программирование очень мало. Программист на Python вполне способен понять, что делает этот код. # Выводы * Иногда достаточно PyPy, если он уже поддерживает всё, что вам нужно. Ускоряет примерно в 10 раз. * Оптимизация *простого* кода тоже важна. Но если вы оптимизируете код, который уже хорошо написан, наверняка вы делаете его менее понятным. * Инструментарий должен быть стабильным и не регрессировать от релиза к релизу. Автор считает стабильными и активно использует PyPy, Cython и Nimpy. * Не бойтесь эзотерических языков, особенно если это ваш пет-проект или команда маленькая. Это весело. Кстати, Python 3 в Яндексе долгое время считался эзотерическим языком. * Ускорять приложения с помощью новых приложений — необоснованный риск. В большинстве случаев проверенных инструментов и роста производительности в 10-15 раз вам хватит. # Вопросы и ответы Q: Нач что ещё посмотреть из эзотерических вариантов Python? A: На GraalVM. В некоторых случаях работает в 3-4 раза быстрее Cython, но нестабилен. Q: А почему бы не подгружать функции напрямую из C с помощью [CFFI](https://cffi.readthedocs.io/en/latest/)? A: Потому что придётся писать прямо на C. Автор законтрибьютил 14 строк на C в ядро Linux, и за два года в них нашли 4 ошибки. Но если у вас есть хорошие программисты на C — используйте. Q: Что из вышеперечисленного используется на проде в Яндексе? A: Есть PyPy и Cython, но не везде. ================================================ FILE: content/moscowpython/19/go-vs-python.md ================================================ --- title: "Go против Python" author: "Виталий Левченко, организатор Go-митапов в Санкт-Петербурге" tags: ["Moscow Python Conf", "2019", "Python", "Go"] summary: | Как нам сравнивать языки? Обычно начинают с бенчмарков. Ок, давайте тоже так сделаем. --- # Бенчмарки Как нам сравнивать языки? Обычно начинают с бенчмарков. Ок, давайте тоже так сделаем. Есть бенчмарк web: * HTTP * Достать 16 текстов из БД * Отсортировать и дополнить * Отрендерить на шаблоне * (Fortunes test) Результаты: | Язык | фреймворк | rps | latency, ms | |--------|:----------------------------|-------:|------------:| | Go | fasthttp | 329k | 0.4±0.2 | | | native http, chi | 128k | 2.9±1.7 | | Python | uvicorn/starlette, gunicorn | 65-71k | 7.1±3.0 | | | aiohttp | 30k | 14.9±5.5 | | | django/tornado/flask | 14-23k | 2.0±0.8 | Источник: techempower.com/benchmarks # Аллокации в Python * List 1M строк = 10k объектов по 100 полей. * Размер JSON — 20Mb * Redis отдаёт эти данные за долю миллисекунды `json.loads()` работает 193 миллисекунды, это долго! В Go это примерно так же долго, зато там есть кеш в памяти. Давайте так же в Python! Что если если shared cache? * `multiprocessing.Manager` * Create dict: 2.2s * Update dict: 1.7s * И в это время приложение не может делать ничего другого с кешем. Так, а если не shared? * 1M объектов это примерно 100 MB памяти * 10Gb всего * На 28 ядер нужно 280 Gb! Вывод: Python не подходит для обработки большого количества объектов. # Асинхронность Кейс — обработка очереди: * Много запросов в БД и арифметики. * CPU bound На машине 14 ядер. Вопрос: сколько воркеров надо запустить, чтобы утилизировать CPU? Оказывается, что около 100-200, зависит от базы. Если база отвечает медленнее, CPU недогружен. Если быстрее — CPU перегружается, load average 200, машинка перестаёт отвечать. Нужны корутины. Если корутины, то во время запроса в базу приложение обрабатывает другие потоки. Если не корутины, то всё залочено. В Go всё хорошо с асинхронностью: * syscall отдает тред в scheduler; * mutex-ы отдают управление в scheduler; * и это всё работает из коробки, в стандартной библиотеке. Asyncio * Всё круто, асинхронно и без лапши * ...пока **все** функции неблокирующие. * А как только блокирующие, то рантайм встаёт, пока функция не разблокируется. Поэтому приходится выбирать библиотеки, которые поддерживают asyncio. * 11 популярных БД: aio-libs * очень многое не production-ready * нет важных для продакшена вещей вроде [aerospike](https://aerospike.com/) * есть не все таймауты, приходится дорабатывать или страдать ## Коммуникация между тредами Go: коммуникация между тредами есть из коробки. Python: нет. * Уведомить корутину о graceful shutdown ```go select { case task := <-queue: // processing case <-closeChannel: waitGroup.Done() } ``` В Python нужна поддержка соответствующих обработчиков и всё равно это неудобно. * Чтение разом из нескольких каналов ```go select { case task := <-queue1: // processing case task := <-queue2: // processing } ``` В Python в этом случае нужно объединять потоки в единый queue c потерей типов, потом разъединить с нахождением типов... Всё сложно. # Machine learning Go: * мало production-ready библиотек * но можно сделать своё * и оно может получиться в разы быстрее Кейс: рекомендации. Dataset — MovieLens 1M | Язык | Scikit | SVD | SVD++ | |--------|--------------------------------------------|-------:|----------------:| | Python | [github.com/NicolasHug/Surprise][surprise] | 2m 13s | **2h 54m 00s** | | Go | [github.com/zhenghaoz/gorse][gorse] | 1m 48s | **0h 02m 47s** | [gorse]: https://github.com/zhenghaoz/gorse [surprise]: https://github.com/NicolasHug/Surprise # Оптимизация ## Профилирование В Go профилирование делается в одну строку: * Онлайн-диагностика: ```go import _ "net/http/pprof" ``` * Ссылка работает в консоли ```bash go tool pprof -seconds 5 http://server/debug/pprof/profile ``` * Или сразу в браузере ## Результаты профилирования * показывает горячие строки в либах * list *func* даёт листинг функции * disasm *func* даёт asm-код функции Можно вот так посмотреть: ![go-vs-python-01](../../../images/static/go-vs-python-01.png) Есть flame-graph: ![go-vs-python-02](../../../images/static/go-vs-python-02.png) Построчный вывод: ![go-vs-python-03](../../../images/static/go-vs-python-03.png) ## Наконец, оптимизация * `gcflag -S` и `disasm` дают исполняемый asm-код * `gcflag -m` сообщает об инлайн-функциях и аллокациях на heap'е * Можно переписать *функцию* на C или asm * Можно сравнить 2 профайлинга Разработчики языка всерьёз занимаются оптимизацией и часто рассказывают о результатах. ## Online tooling `pprof` очень хорош: * есть профилирование CPU и памяти (heap) * есть профилирование блокировок и их использования * есть стектрейс для горутин * и полный трейсинг работы приложения * можно отслеживать создание тредов ## Moar Tooling Ещё фишечки: * `go build -race` * `go test -bench -benchmem` # Разработка * В Go снова всё хорошо. Апгрейды мажорных версий Go не вызывают проблем. * Обновление библиотек редко ломается. Тут важное отступление. Долгое время работа с зависимостями работала так: `go get` — и последняя версия библиотеки прилетает прямо из ветки `master` на гитхабе. Мейнтейнеры библиотек привыкли, что если что-то несовместимо поменять, придёт много недовольных пользователей. * Python 3.6→3.7 — ломаются библиотеки. * Обновление мажорных версий библиотек часто ломает совместимость. ## Зависимости в Go * Зависимости от внешних библиотек бывают редко. Если что-то нужно, то это берут и пишут в этой библиотеке. * В 1.12 появился go mod: 1 файл, заполняется автоматически, везде semver * Все зависимости лежат в общем месте с версионностью, без vendor / virtualenv. Нет папочки вроде `venv` или `node_modules`, в которой лежит половина интернетов. * Библиотеки версионируются, подписываются ключиками и проверяются по контрольным суммам. * Библиотеки не переделывают рантайм, не вмешиваются в работу GC, не патчат системные функции. Импорт библиотеки не влечёт сторонних эффектов. ## Своя библиотека в Go * Берём библиотеку с go mod * Анонс = git push * Документация сразу будет на godoc.org * PR приняли — можно пользоваться. А если (пока) не приняли, то забираем из своего форка. В Go высокодоступная документация. `godoc http` — и документация доступна на локальной машине, даже если вы в самолёте. Есть один способ собирать документацию — godoc. # Обработка ошибок Говорят, в Go нет исключений. Неправда, они есть, просто называются паниками. Задачка: в скольки местах это может сломаться с исключением? ```python def fetch_user(id: int) -> 'User': response = requests.get('/api/users/{0}'.format(id)) response.raise_for_status() return response.json() ``` Тут могут быть разные исключения, хорошо бы их все обработать. Go позволяет нам это сделать и даже заставляет. ```go func fetchUser(id string) (*User, error) { resp, err := http.Get(`/api/users/`+id) if err != nil { return nil, errors.Wrap(err, `get user by id`) } // теперь обработаем код ответа if resp.StatusCode != http.StatusOK { return nil, errors.Wrap(errors.New("API got status " + resp.Status), `get user by id` } user := &User{} // теперь декодируем if err = json.NewDecoder(resp.Body).Decode(user); err != nil { return nil, errors.Wrap("Incorrect user profile", err) } return user, nil } ``` # Кодировки * Go — сразу UTF-8 * Python — вообще UTF-8, но в легаси встречается ASCII # Выводы Опытному бэкендеру на самом деле не важно, на чём писать. ## Зарплаты | Язык | МойКруг, РФ | | GetIT, Москва, senior | StackOverflow, (медиана) | |--------|-----------------:|-----------------:|----------------------:|-------------------------:| | | 75% (процентиль) | 90% (процентиль) | | | | Python | 150 000₽ | 185 000 ₽ | 175-200 000 ₽ | $98 000 в год | | Go | 178 000₽ | 225 000 ₽ | 201-250 000 ₽ | $110 000 в год | Вывод: писать на Go выгоднее на 20%! ## Когда Python лучше * Когда важна скорость бутстрапинга приложения * Задачи data science * Нравится async/await ## Когда Go лучше * CPU/memory/io-bound app * Важна простота эксплуатации приложения (operations) * Хочется интересных задач * Хочется больше денег ================================================ FILE: content/moscowpython/19/kill-mutants.md ================================================ --- title: "Убивай мутантов, спаси свой код" author: "Никита Соболев, wemake.services" tags: ["Moscow Python Conf", "2019", "Python"] summary: | Как мы работаем: 1. Прилетает пуллреквест с изменениями кода и тестов 2. Проходит CI 3. Ревью кода. 4. Мерж в мастер 5. Всё в огне! --- Доклад про мутационное тестирование. Если у вас уже есть 100% покрытие по всем параметрам, то вам сюда. # Наши тесты ничего не проверяют. Что с этим делать Как мы работаем: 1. Прилетает пуллреквест с изменениями кода и тестов 2. Проходит CI 3. Ревью кода. 4. Мерж в мастер 5. Всё в огне! Почему так? Потому что наши тесты ничего не проверяют. «Логичные» выводы: * писать больше тестов * увеличивать покрытие * больше ревьюить. Давайте разберём их подробнее. ## Писать больше тестов? Давайте попробуем. * больше тестов = больше кода (тестов), * больше кода = больше багов, * а ещё, больше тестов = больше дубликатов, * и наконец, больше тестов = затык на CI. Не надо больше тестов! Надо меньше, но лучше. ## Повысить покрытие? Дальше, повысили покрытие. Ну вот у нас 100% покрытия. И что? Вот функция из одной строчки. Она полностью покрыта тестами и работает. ```python def negate(first: float): """Return the negated number.""" return 0 - first ``` А вот тест, который полностью покрывает эту функцию. ```python @pytest.mark.parametrize('given, expected', [ (-1,1), (0,0), (0.5,0.5), ]) def test_negate(given, expected): function_result = negate(given) # TODO: uncomment this line: # assert function_result == expected ``` Покрытия мало, нужны сами проверки. Вывод: надо тестировать тесты. ## Cтроже ревьюить? В хорошем проекте тестов гораздо больше, чем кода. В коде хорошая понятная логика, а в тестах — сборник непонятных ситуаций, которые могут и не произойти. А ещё тесты обычно написаны плохо, но их читаемость можно повышать. Бывает, что человек удалил тест. Почему? Может, тест падал? Или он больше не нужен? Очень сложно понять это на ревью. ## Нет, придётся тестировать тесты Ничего из этого не работает. Придётся тестировать тесты. Давайте поймём, как это делать. Как обычно выглядит первая задача на новом проекте: * Сотни тысяч строк кода * Десятки тысяч тестов * Одна простая новая фича Мы что-то меняем и проверяем, работает или нет. Пока знания кода нет, мы меняем код в случайных местах. Посмотрим на пример: оптимизировали сортировку пузырьком. ```diff def bubble_sort(array: list) -> list: length = len(array) for first in range(length - 1): +++ swapped = False for second in range(length - 1 - first): if array [second] > array[second + 1]: +++ swapped = True array[second], array[second + 1] = \ (array[second + 1], array[second]) +++ if not swapped: +++ break return array ``` Тесты проходят, всё отлично, да? Давайте точно зафейлим метод: ```diff length = len(array) for first in range(length - 1): +++ raise ValueError('Should fail!') ``` А тесты снова проходят. О_о. Как же так? Давайте поправим тест, который не упал, а должен был. Теперь тесты падают и это нам нравится. Отлично, давайте теперь ломать весь оставшийся код! По очереди немного поменяем каждую строку в проекте. Например, так. ```diff --- if oversize > 0: +++ if oversize > 1: print('{0} exceeds {1} limit by {2}'.format( arguments.image, arguments.size, format_size(oversize, binary=True), )) ``` Хорошие тесты должны упасть в этом месте. А что если поменять формат принта? ```diff if oversize > 0: --- print('{0} exceeds {1} limit by {2}'.format( +++ print('XX{0} xx {1} xxx by {2}XX'.format( arguments.image, arguments.size, format_size(oversize, binary=True), )) ``` А если поменять `True` на `False`? ```diff if oversize > 0: print('{0} exceeds {1} limit by {2}'.format( arguments.image, arguments.size, --- format_size(oversize, binary=True), +++ format_size(oversize, binary=False), )) ``` После каждой мутации мы прогоняем тесты. Вот что может случиться: * тесты упадут и убьют мутанта * таймаут * WTF * тесты пропустят мутанта и не упадут # Технология мутации Не регулярками же менять код. Давайте как-нибудь по-умному это делать. Берём абстрактное синтаксическое дерево (AST). Конкретные кусочки меняем на похожие, например так: ``` + —> - True —> False x —> not x 'a' —> 'X' and —> or > —> >= ``` Вообще, стратегий очень много. Алгоритм мутационного тестирования такой: * Мутируем строчку кода * Запускаем тесты * Собираем статистику: упало или нет * Повторяем # Инструменты | | Интеграция с pytest | Отчёты | Работает | |-----------|---------------------|--------------------|---------------------| | CosmicRay | :x: | :heavy_check_mark: | :heavy_check_mark: | | MutPy | :x: | :heavy_check_mark: | :x:[*](#why) | | mutmut | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | *MutPy у Никиты вообще не завёлся. # Какие ошибки можно найти ## Плохие данные ```python def add(first: float, second: float): """Simple function to show the problem.""" return first + second def test_add(): assert add(0, 0) == 0 assert add(2, 2) == 4 ``` Тут всё очевидно, а в реальной жизни мы не замечаем плохие тестовые данные, потому что они сложные. ## Плохие тесты Плохие тесты — такие, которые ничего не тестируют. ```python app = Flask(__name__) @app.route('/') def hello(index: int): return 'Hello, world! {0} faith in you.'.format( 1 * index, ) @app.errorhandler(Exception) def log_to_sentry_and_show_sorry_page(exception): # попросили сделать статус 200 ради SEO return 'S0rry, world :(', 200 def test_hello_view(flask_client): """This test does nothing.""" response = flask_client.get('/0') assert response.status_code == 200 assert b'world' in response.data assert b'0' in response.data ``` А `1 * index` — это вообще бизнес-логика. Её нужно вынести в отдельную функцию и тестировать юнит-тестами. Вот так надо: ```python @app.route('/') def hello(index: int): return 'Hello, world! {0} faith in you.'.format( calculate_faith(index), ) ``` ## Связанные данные ```diff WRONG_LETTERS = [ --- 'a', +++ 'X', ] def is_wrong_letter(letter:str) -> bool: return letter in WRONG_LETTERS ``` А вот наш тест, который использует те же данные, что и метод: ```python from source import WRONG_LETTERS, is_wrong_letter @pytest.mark.parametrize('letter', WRONG_LETTERS) def test_is_wrong_letter(letter): assert is_wrong_letter(letter) is True ``` Правильно — задублировать данные: ```python @pytest.mark.parametrize('letter', ['a']) def test_is_wrong_letter(letter): assert is_wrong_letter(letter) is True ``` ## Частичные тесты ```python def test_save_subscription(form): instance = save_subscription(form) assert instance.id > 0 assert instance.name == form.data['name'] ``` А функция такая. Она не только сохраняет подписку, но ещё и отправляет рассылку. И мы это не тестируем, а должны. ```diff def save_subscription(form): subscription = form.save() --- queue_welcome_email.delay(subscription.id) +++ queue_welcome_email.delay(None) return subscription ``` Тестируйте сайд-эффекты! ```diff def test_save_subscription(form): instance = save_subscription(form) assert instance.id > 0 assert instance.name == form.data['name'] +++ assert redis.get(queue(instance)) ``` ## Медленные и бесконечные тесты Ставьте таймаут. Тесты с таймаутом помогут вам не уронить прод. > pypi.org/project/pytest-timeout ```diff CELERY_BROKER_URL = 'redis://{host}:{port}'.format( --- host=config('HOST', default='localhost'), +++ host=config('HOST', default='XXlocalhostXX'), ... ) ``` # Не весь код полезно мутировать Как не создавать бесполезных мутантов? 1. Запускаем конкретный тест. 1. Собираем coverage. 1. Мутируем только нужный код: `--path-to-mutate`. Всё это очень долго. Например, если у нас 1 тест и 1000 мутаций, то они займут 16 минут. Как оптимизировать? 1. Отключаем плагины: coverage, random ordering, дополнительные проверки. Стало 15 минут. 2. Ничего не пишем: `--tb=no --quiet`. 10 минут. 3. Падаем на первом тесте: `--exitfirst`. 6 минут. 4. А теперь проверяем только тот код, который покрыт тестами: `--use-coverage`. Тут мы запускаем тесты 1 раз, чтобы посчитать coverage, а потом используем его для мутации. Стало 5 минут. 5. Плагин `pytest.testmon`: `--testmon`. Когда мы поменяли кусочек кода, надо запустить именно тот тест, который за него отвечает. Это тоже определяется с помощью coverage. Теперь 4 минуты. # Как настроить и запустить mutmut Настроить: ```ini [mutmut] paths_to_mutate=src/ backup=False runner=pytest -x -q --tb=no --testmon -o addopts="" tests_dir=tests/ ``` Запустить: ```bash mutmut run --use-coverage -s ``` # Результаты Вспомним, что мы хотели, чтобы тестов было меньше и они были лучше. Теперь мы можем найти лишние тесты (которые не падают) и убрать их. У mutmut есть хук `--post-mutation`. Мы можем им записать тесты, которые не упали ни разу. Всё это отлично работает с TDD. Пишем код и сразу тесты. Мутируем код, мутируем тесты, всё проверяем. Теперь наши тесты сразу хорошие. ## Property-based тесты Если код поменяли, а тесты проходят — значит данные плохие. Мутационное тестирование поможет найти места, где нужны такие тесты, и подобрать для них хорошие данные. # Когда не нужно использовать мутационное тестирование Есть другие способы улучшать проект. Их проще внедрять и они дешевле обходятся. Вот когда у вас уже есть линтеры, проверка типов, юнит- и интеграционные тесты, property-based тесты и даже тесты на документацию, и вы хотите сделать что-то ещё — вот тогда занимайтесь мутационным тестированием. # Выводы * Мы напишем больше тестов! **Нет, лучше мы удалим лишние тесты.** * Мы повысим покрытие! **Не просто повысим, но и проверим, что тесты что-то тестируют.** * Будем строже ревьюить! **Наоборот, упростим процесс ревью.** * Автоматизируем всё! **Да.** # Ссылки * [github.com/boxed/mutmut](https://github.com/boxed/mutmut) * [github.com/sobolevn/heisenbug-2019](https://github.com/sobolevn/heisenbug-2019) * Вопросы сюда: [github.com/sobolevn](https://github.com/sobolevn) * Читайте [sobolevn.me](https://sobolevn.me/) ================================================ FILE: content/moscowpython/19/yandex-python.md ================================================ --- title: "Как развивался Python в Яндексе" author: "Александр Кóшелев, Яндекс" tags: ["Moscow Python Conf", "2019", "Яндекс", "Python"] summary: | Александр в Яндексе с 2008 года, писал Афишу и другие сервисы, потом ушёл во внутренние сервисы. Сейчас руководит отрядом из 30 питонистов. Важно: Яндекс — большая компания, потому сложно сказать про всех сразу. Доклад Александра — в первую очередь про его опыт в Яндексе, его интерпретация событий. --- Александр в Яндексе с 2008 года, писал Афишу и другие сервисы, потом ушёл во внутренние сервисы. Сейчас руководит отрядом из 30 питонистов. Важно: Яндекс — большая компания, потому сложно сказать про всех сразу. Доклад Александра — в первую очередь про его опыт в Яндексе, его интерпретация событий. # Введение Эволюцию Python в Яндексе можно разделить на эпохи. Их границы — это переход к новым инструментам и подходам. 1. Железо 1. Железо + venv 1. Контейнеры 1. Бинарная сборка Вот что важно рассказать про каждую эпоху: * Инфраструктура * Фреймворки * Работа с зависимостями * Общий код * Среда разработки * Плюсы и минусы # Эпоха 1: железо, 2008-2011 «Куда все идут» — часть Афиши и первый сервис на Django. Следом шла сама Афиша, Погода, Телепрограмма. ## Инфраструктура Приложения работают просто на железных машинах, объединенных в большие общие кластера. ОС – Debian/Ubuntu. Приложения запускаются `initd`, общаются с веб-сервером через FastCGI (flup). ## Фреймворки Django, CherryPy, Web.py ## Зависимости Работа с зависимостями была устроена так: * Собираем deb-пакет с кодом проекта; * Для каждой зависимости тоже свой пакет; * Дополняем своими пакетами системный репозиторий. ## Общий код В компании появляется много собственного кода, который используют все команды. Такой внутренний опенсорс. Все библиотеки — в отдельных репозиториях, каждая заворачивается в deb-пакет. Типичный сервер выглядит так: ![yandex-python-01](../../../images/static/yandex-python-01.png) Следствие: на одном сервере все приложения должны иметь одинаковые зависимости. Чем больше приложений на сервере, тем сложнее всё это поддерживать. ## Среда разработки * Для всех — удаленно на дев-сервере. * Если сотрудник работает на линуксе, то локально на своей машине * Если работает на Windows, то в виртуальной машине. ## Плюсы и минусы * :x: Приложениям тесно на общем кластере. * :x: У всех приложений должны быть одинаковые зависимости. * :x: Приложения с общими зависимостями нужно релизить ОДНОВРЕМЕННО. Разумеется, это ведёт к многократным откатам на прошлый релиз и прочему веселью. * :x: Сильная зависимость от инфраструктуры Debian. ## Почему вообще стали использовать Django Автор уже рассказывал об этом на одной конференции 11 лет назад. С тех пор всё ещё любит Django, и вот почему: * низкий порог входа * большая экосистема * много специалистов на рынке труда * есть всё необходимое для работы * достаточная гибкость # Эпоха 2: железо + venv, 2012-2015 ## Инфраструктура В инфраструктуре появились «виртуалки»: OpenVZ, LXC и другие. Но их только пробовали, технология была слабо развита, всё равно все жили в общих кластерах. Запуск приложений теперь через upstart или systems. Отказались от FastCGI в пользу WSGI (uwsgi) или HTTP (unicorn). Перешли на nginx в качестве основного вебсервера. ## Фреймворки Tornado, Flask, Celery для распределённых задач. ## Зависимости Работа с зависимостями: начали собирать виртуальное окружение. Ура, можно не ставить библиотеки в систему, а держать сколько нужно виртуальных окружений. Теперь пакуем venv вместе с кодом проекта в deb-пакет. Теперь на сервере есть раздельные питоновые зависимости и общие системные: ![yandex-python-02](../../../images/static/yandex-python-02.png) ## Общий код К этому моменту частично отказались от инфраструктуры Debian, да и deb-пакеты с зависимостями не подходят для venv. Поэтому подняли свой PyPI на базе [Localshop](https://github.com/mvantellingen/localshop). Сейчас в нём более тысячи внутренних пакетов. ## Среда разработки Поменялась к лучшему. Работаем в виртуальном окружении на любой ОС: Windows, Linux, macOS ## Плюсы и минусы * :heavy_check_mark: с venv стало проще жить на кластерах-общежитиях. * :x: всё ещё есть общие системные зависимости * :x: не все команды переехали на venv, некоторым проектам ещё нужны конкретные системные библиотеки Python. ## Почему выбрали Tornado Потому что это (был) современный асинхронный фреймворк. Альтернативы не понравились: * gevent — внутри хак * twisted — морально устарел * asyncio — только в Python3, а на него ещё переехать надо. ## Почему выбрали Celery Потому что это хороший фреймворк для очередей задач. Используют до сих пор (2019 год). Поддерживает множество брокеров очередей: SQS, RabbitMQ, MongoDB, Redis. Наконец, просто чаще работает, чем не работает. # Эпоха 3: контейнеры, 2016-2018 Инфраструктура — внутреннее docker-совместимое облако. То есть там не docker, но стандартные образы можно туда пушить. Запуск приложений с помощью supervisord или uwsgi. Оказалось, что uwsgi хорошо справляется с задачей запуска процессов. И его же используют для HTTP. ![yandex-python-03](../../../images/static/yandex-python-03.png) ## Фреймворки * появился Falcon. Например, Алису переписали с Django на Falcon. * asyncio (наконец переехали на Python3) ## Работа с зависимостями * Всё внутри докер-образа. При сборке просто устанавливаем всё с помощью pip. * Все системные зависимости тоже изолированы. Но теперь стало сложнее внедрять общие подходы к сборке и обновлять общие зависимости. ## Среда разработки * Локально на любой ОС * Разработка тоже через Docker * Docker-compose помогает поднять сервисы на локальной машине и потестить, даже несмотря на то, что целевое облако — не докер. ## Плюсы и минусы * :heavy_check_mark: полная изоляция * :heavy_check_mark: удобный toolchain * :heavy_check_mark: поддержка IDE * :x: на не-Linux машинах с докером всё непросто, есть ограничения. ## Почему Docker * поддерживает большинство платформ * эффективно * хорошая экосистема * де-факто стандарт, все умеют с ним работать # Эпоха 4: бинарная сборка, 2019… Раньше весь Яндекс был на Debian-инфраструктуре. А теперь весь Яндекс идёт к большому монорепозиторию. Вокруг него есть механизм сборки, распределённого тестирования и куча других инструментов. В первую очередь это для кода на C++ и Go, но Python тоже подтягивается. Мы собираем бинарь и оно просто работает на любой совместимой архитектуре. Чудо! ![yandex-python-04](../../../images/static/yandex-python-04.png) ## Плюсы и минусы * :heavy_check_mark: Единый принцип сборки периложений во всей компании. * :heavy_check_mark: Единообразная сборка с зависимостями. * :heavy_check_mark: Если есть чекаут репозитория локально, то его достаточно, чтобы собрать проект. * :heavy_check_mark: Удобство дистрибуции. * :x: Порог входа: новому сотруднику нужно время, чтобы это освоить. # Выводы * Эволюция неизбежна! * Не бойтесь изменений * Идите в ногу с внешними трендами * Не отказывайтесь от проверенных решений * Развивайте внутреннюю python-экосистему в компании # Вопросы Q: Не было ли проблем с пакетами, которые работают глубоко в драйверах? A: Иногда бывает, когда пакет завязан на системные зависимости и может, например, не работать в venv. Тогда просто собираем deb-пакеты. Q: Что насчёт CI? A: Раньше использовали Teamcity, сейчас внутреннюю разработку. Вообще в компании много разных CI используют. Q: Были ли проблемы с ресурсами, например с модельками для машинного обучения? Как храните их? A: Храним по-разному. Q: Есть ли на одних и тех же серверах проекты из разных эпох? A: В облаке только третья эпоха, а на кластерах бывают разные. Пробовали выселять проекты из первой эпохи на отдельные серверы. ================================================ FILE: content/qualityconf/19/blameless.md ================================================ --- title: "Blameless environment: никто не должен писать качественный код" author: "Никита Соболев, wemake.services" tags: ["QualityConf", "2019"] summary: | Бывает, что всё очень плохо: * Плохой код, никто не думает о качестве кода. * Плохие процессы, аутсорс и бардак. * Плохие клиенты и вообще всё плохо. Наверное, это люди виноваты! А вот когда люди изменятся, всё станет иначе. Ещё наверное, в других местах работают другие люди, и те люди лучше, и там работать лучше. Но нет, это неправда. --- ## Бывает, что всё очень плохо * Плохой код, никто не думает о качестве кода. * Плохие процессы, аутсорс и бардак. * Плохие клиенты и вообще всё плохо. Наверное, это люди виноваты! А вот когда люди изменятся, всё станет иначе. Ещё наверное, в других местах работают другие люди, и те люди лучше, и там работать лучше. Но нет, это неправда. Хочется это поменять, создать новый порядок. Совершенно непонятно, как его создать. В книжках не написано и в университете не учили. ## Постановка задачи Начнём с постановки задачи. Бывают задачи из одной строки. Человек делает такую задачу и у него получается не то. Проще обвинить человека, но на самом деле задача плохо поставлена. Хорошие постановки задач: * Короткие и понятные. * Упорядоченные: ясно, в каком порядке их лучше делать. * Индивидуальные: кому-то принадлежат. Если постановка хорошая, то люди, внезапно, делают хорошо. ## Чего на самом деле хочет заказчик Есть требования: что должно быть сделано в целом. Но по требованиям нельзя работать. Нужна декомпозиция задач в документации. Требования — что нужно сделать, документация — как. Из требований можно генерировать документацию. Следующий шаг — сделать тесты, а потом написать код. Получается, чтобы заказчик и разработчик встретились, нужно выстроить цепочку от требований к коду. ## Общение Люди хотят общаться, и на работе это может быть проблемой. Например, они разговаривают и вырывают друг друга из состояния потока. А ещё есть митинги, на которых люди тратят время друг друга. Люди конфликтны. Особенно, когда они находятся в тесном помещении и ситуация сталкивает их. Бывает также, что люди пропадают, особенно если они работали удалённо. Просто больше не отвечают на звонки. Как структурировать общение? 1. Удалить соцсети. Тогда люди не могут тебе написать куда угодно. 2. Выбрать один канал для общения, который удобен для работы. В wemake.services для общения выбрали GitLab. Всё там, даже вопрос по работе задают там. Обсудить новую технологию? Создай тикет. Обсудить Игру Престолов? Нет, спасибо, с этим к друзьям. ## Все пишут плохой код Мы созданы не для того, чтобы писать код. Код вообще сложный. Нормально, что нам сложно писать код. Все пишут плохой код. Чтобы облегчить написание кода, нужна **строгость**. Строгость нам даст CI. Он должен быть **неотвратимым** и обязательным для всех. Если кто-то может коммитить в мастер, будет бардак. Всё это вместе ведёт к **развитию**. Если есть строгий CI, каждый кусочек кода делает проект лучше. Но люди всё равно будут делать ошибки и это нормально. Можно возвращать ошибки людям, вместе с обвинениями. «Ты сделал плохой код, иди и поправь». Но это плохо работает. ## Blameless environment Если в проекте есть баг, чья это проблема? Это проблема проекта и больше ничья. Баг нужно исправить так, чтобы он больше не случился. * Если он в коде, написать регрессионный тест. * Если в инфраструктуре — использовать инструмент, который его предотвратит. Когда исправляешь баги на системном уровне, появляется развитие. Следующий шаг после CI — ревью кода. И каждый шаг имеет смысл, только если правильно выполнен предыдущий. Если код не прошёл CI, незачем его ревьюить. Если задача неправильно поставлена, то никакой CI этого не обнаружит, и ревью тоже не всегда. ## Баги — это хорошо Бывает культура, в которой баги — это плохо. А если человек не тестировщик и зарепортил баг — он плохой, срывает процесс и суёт палки в колёса. Зарепортить баг — это как будто сказать «код твой плохой и ты сам плохой». В blameless environment баги — это благо. Баги помогают развиваться. Поэтому нужно поощрять и уважать людей, которые репортят баги. Как этого добиться? ## Виноваты не люди, виновата система система, которая поощряет: * писать плохой код, * тратить время на встречи, * и делать всё остальное, что плохо. Исправляйте систему. ## Имплементация Вот принципы работы в wemake.services: * Полная свобода действий. Хочешь — работаешь. Не хочешь — не работаешь. * Нет общения. В том числе нет системы информирования о том, будет человек сегодня работать или нет. * Поэтому нет команды. * Боты управляют людьми. * Всё код: код, тесты, требования, документация. * Оплата за результат, тикеты и ревью. * Всё проверяется: тикеты, ревью, код. ================================================ FILE: content/qualityconf/19/libfuzzer.md ================================================ --- title: "Фаззинг или тестирование мусорными данными" author: "Максим Бакиров, 2ГИС" tags: ["QualityConf", "2019"] summary: "" --- # Зачем? В качестве примера — поисковый запрос в 2ГИС, для которого используется не только сам текстовый ввод, но и параметры пользователя: предпочтения, город, текущий участок карты. Ручное тестирование подобных вещей из-за количества комбинаций практически нереально. # Фаззинг Фаззинг — это тестирование случайными входными данными. Пример из реальной жизни: это Heartbleed из OpenSSL; уязвимость, которая позволяет читать память на сервере или клиенте, которая затронула гигантское количество устройств и серверов и была обнаружена только спустя два года # libFuzzer Библиотека, которая подходит для тестирования: - парсеров - компрессии - криптографии - регулярных выражений Нужно понимать, что он хорошо подходит для приложений на C++, т.к. имеет расширяеемое C-API для интеграции и входит в поставку с компилятором Clang. В документации, например, есть пример поиска ошибки в той самой уязвимой версии OpenSSL с помощью libFuzzer. Фаззинг помогает найти нетривиальные баги в сложно-связанном коде. # Как это устроено? Тестовый корпус данных -> Вызов функции -> Оценка сценариев -> Мутация данных -> 🔄 -> Артефакты бага Однако libfuzzer работает с набором байт, а наше приложение чаще всего работает с более сложными структурированными данными, и если на него натравить libfuzzer, то мы получим множество исключений о неправильном формате, но не найдёт реальные баги. Для того чтобы это исправить, можно воспользоваться C-API и дополнить фаззинг необходимой функциональностью, например использовать более сложные структуры и даже подсовывать тестовые данные из баз. В случае с поиском 2ГИС libFuzzer после тюнинга начал использовать реальные данные организаций, комбинировать и мутировать их, и находить реальные баги в продукте. # Что получилось у 2ГИС - нашли 10 потенциальных крашей - внедрили в пайплайн разработки - оцениваем регрессию (тестовый корпус сохраняется между запусками) - отслеживать аномально медленные запросы к поиску ================================================ FILE: content/siberian-community-orgs/documenting-meetings.md ================================================ --- title: "Документирование встреч" author: "Siberian Community Orgs" tags: ["siberian-community-orgs", "2020"] summary: | На митапе организаторов сибирских ИТ-сообществ обсудили документирование встреч. --- Мы собрались, чтобы обсудить документирвование встреч: как внутренних митингов в компании, так и митапов в сообществах и на конференциях. ## Знакомство и ожидания *(Встречу начинает конспектировать Коля. Мы прикатили большой телевизор и выводим конспект на него.)* Ира: True Engineering. Понять, как документировать встречи и как из встречи сделать статью. Алина: JB, образовательный центр. Жду нетвокинга. Коля: Plesk и KnowledgeConf. Вроде умею документировать встречи, делал это сколько-то раз. Сейчас расскажу вам, что умею, и сам пойму заодно. Костя: фриланс, Siberian Game Jam. Хочу нетворкинга. Аня: HR в IceRock Development. Организовывала мероприятие по Kotlin. Хочу советов по организации мероприятий. Саня: Билайн, big data. Организую мероприятия для айтишников в НГТУ. Андрей: Plesk, делал пару митапов. Ничего не жду, рад всех видеть. ## Опыт Коли Схема такая: два ведущих, один модерирует и докладывает, второй конспектирует. Конспект выводится в реалтайме на большой монитор или телевизор, так, чтобы всем было видно. Это удобно: * Участинкам проще следить за ходом встречи * Можно сразу попросить что-то порправить и дописать * Проще оставаться в рамках темы, возвращаться к предыдущим пунктам * Можно сразу на ходу структурировать информацию (при линейном обсуждении) * Проще подводить итоги встречи ## Опыт Сани *(Дальше встречу конспектирует Алина.)* Документировали с помощью mind map требования к новой системе при обучении общению с заказчиком. Рисовали в специальной проге FreePlane. Вопрос: mind map просто составлять, если уже оринтируешься в теме. Как быть с новой темой? Ответ от Сани: mind map рисовал опытный человек :) Есть программы, которые превращают markdown в mind map. Есть прога Resonate: каждый, кто участвует во встрече запускает её на телефоне и включает запись диктофона. Потом получается текстовая запись, где все реплики подписаны автором. Что делать с паразитами? ## Опыт Андрея Заказали ручную расшифровку видео с митапа. Там как раз были проблемы со словами паразитами и с профессиональными терминами. Коля когда-то занимался редактурой расшифрованного доклада. На сложных технических моментах были видны ошибки расшифровщика общего назначения. Кажется, что лучше, чтобы сразу доклад расшифровывал технический писатель. Если докладчик что-то вспоминает и договаривает позже, это нужно редактировать, чтобы была последовательная структура повествования. Иногда в технических статьях врываются маркетологические вещи, это тоже нужно редактировать. Но для этого нужны отдельные договорённости с докдладчиком, что он готов на недословную расшифровку и адаптацию его речи. По опыту Коли докладчики хорошо реагируют. Проще ли самостоятельно с видео? Зависит от качества расшифровки. ## Опыт от Кости Вопрос: нужно ли такое онлайн документирование? Или проще записать видео или сделать фото доски? Текст хорош тем, что он индексируется. Картинки не индексируются. Это касается не только митапов, но и встреч-обсуждений. Даже по нашей встрече во всероссийском чате деврелов сразу спросили про материалы. Если у рабочих встреч есть саммари, можно отправлять сотрудников, которых не было на встрече, читать это. Но важно поддерживать порядок в этих записях, это отдельная работа. Обычно пользуются Confluence в компаниях, по митапам Notion используют (Конвеерум, например), Коля использует GitHub. Митапы про управления знаниями оказываются популярны. Проводили митап на HighLoad Siberia — в пике было 50 человек, а на конфе всего было около 600. Это очень хороший результат. ## Опыт Алины *(Алина все это время записывала диалог. Теперь конспект переходит к Ире.)* Сложно - отвлекаешься, потому что пытаешься вспомнить как кого зовут, чтобы записать их мнение, на это отвлекалась и теряла нить обсуждения. обсуждение неструктурированное, и пробовала на ходу структурировать - это сложно Можно писать в гугл доке и тогда модератор может отматать и смотреть, доступ у всех. Но опыта использования этого кейса нет. Иногда модератор просил отматать вверх. Аня: в IceRock документирование встреч - это видеозапись - вопрос как документировать доклады на конференциях? Получилось ли бы задукоментировать доклад, а не обсуждение в ходе митапа (когда диалог, а не монолог). Коля: видео гарантирует, что ничего не потеряется. В Плеске часто проходят митапы - либо техтолк Что делать чтобы сохранялось? нужно писать в редакторе, который автосохраняет, например, NotePud++ Что делать когда пишешь набор цитат? Останавливать процесс и задавать вопрос, чтобы Видео не гарантирует, что ничего не потеряется: может кончиться память, может кто-то наступить на провод или положить диктофон поближе к докладчику Костя: нужно останавливать процесс и фиксировать важные моменты, другой формат - когда много людей участвует во встрече есть несколько степеней заморочи 0. просто использовать видео или диктофон 1. есть тот, кто записывает в процессе 2. записать видео и потом с нуля переписать в статью ## опыт Андрея Записывал митап на видео где спикеры говорили по-английски и нужно было сделать так, чтобы было видно и презентацию, и спикера и тд. Нашел инфо как настроить видео так, чтобы было видно и спикера, и обсуждение. Софт OBS (использовался на FrontendConf). Можно загружать картинки (лайфхак - привлекать дизайнеров!), главное следить что записывается звук, а то в тот раз звук был чужой (работал другой звукооператор) и он потерялся. Две камеры - это идеально, можно делать монтаж, можно делать трансляцию vk и в другие источники. Важно так настроить оборудование, чтобы если что-то случилось, презентация продолжала транслироваться на экраны Если что-то сломалось, чтобы страдали только те, кто смотрит трансляцию, но не докладчик и не аудитория. Важна вторая степень бэкапа - хорошо, если камера еще пишет себе на карточку. ## Итоги (ожидание - реальность) Ира: Поняла как документировать встречи более структурированно и попробовала. (!) Алина: Тоже попробовала документировать встречу — есть две заметки, про софт, на который есть смысл перейти, и про то, как не терять черновики писем. Коля: запустил процесс, два человека кроме меня писали конспект и два помодерировали. Кажется, это ценнее, чем просто рассказывать — получился воркшоп. Этот документ отредактируем и опубликуем (вы читаете результат). Костя: нетворкинг — done. Есть запрос скинуть примеры подобных документов своих и других (есть совместные). Аня: поняла для каких мероприятий нужно документирование и запомнила про факапы на будущее Саня: понял, что документирование нужно и зря этим раньше не пользовался Андрей: посмотрел на формат - формат интересный, но подходит не для всех мероприятиях (для нашего подходит). Еще подходит, когда готовишь спикера к выступлению или студента для защиты диплома и во время прогона — записываешь номер слайда и свои вопросы в режиме онлайн-кодинга. ================================================ FILE: content/teamleadconf/20/documentation_challenges.md ================================================ --- title: "Как сделать так, чтобы документация не болела?" author: "Семён Факторович, Константин Валеев" tags: ["TeamLeadConf", "2020"] summary: | * Проблемы с документацией. * Как можно решить. * Инструменты. * Контакты. --- # Проблемы с документацией 0. Её нет. 1. Устаревает, не актуальная. 2. Сложно и дорого обновлять. 3. Непонятна нужная детальность. 4. Непонятен процесс документирования и как он встроен в разработку. 5. Её никто не читает, она непонятная, она сложная, получать информацию из неё дорого и долго, проще спросить устно. 6. Её никто не пишет (в том числе потому что её никто не читает). 7. Бизнес не очень понимает зачем нужна документация и не видят её ценность. # Как можно решить 0. Выделить роль и, при небходимости, отдельного человека. Documentation Champion. Выделенный технический писатель в команде. Отлично работает для небольших компаний. Сервисный отдел технических писателей. Для больших компаний, когда уже выстроены процессы написания документации, есть шаблоны и практики внутри компании. 1. Не описывать детали, которые часто меняются (см. п. 3). Хранить рядом с кодом. Сделать обновление документации частью критериев приёмки ревью кода. Поддерживать трассируемость между артефактами документации кода и тикетов. 3. Не нужно документировать часто меняющиеся детали. Документировать не код, а что над ним. Документировать мотивацию — зачем нужен это код, а не что он делает. *Документировать только то, что не очевидно из кода.* 4. Есть стандарты и их много. В них можно подглядывать: - IEEE 26511 Requirements for managers of information for users of systems, software, and services - IEEE 1016 Software Design Description - IEEE 42010 Architecture description - [C4 Model](https://c4model.com/) - [Arc42](https://arc42.org/) - [Architecture Decision Records](https://adr.github.io/) - 5. Определить целевую аудиторию и задачу документации — писать документацию ради документацию бессмысленно. Выбрать паттерн из двух: одна база знаний и множество вариантов доступа к ней или одна точка входа через агрегатор ко множеству источников. По опыту documentat.io, одна структурированная база знаний получается более жизнеспособной. Подумать над точками входа в базу знаний и методах поиска информации. Чем больше вариантов найти документ - тем лучше. Используйте теги, структуру, списки документов и так далее. Продумать структуру документации, чтобы в ней было удобно найти нужное. Писать несколько документов (или разделов документов) для разной целевой аудитории. Принять стайлгайд на тексты, писать просто и понятно. Собрать шаблоны, чтобы документация была единообразная. Примеры: [redpolitika.ru](http://redpolitika.ru). Линтинг качества текстов, например [vale](https://errata-ai.gitbook.io/vale) 6. См. 0. 7. Считать потери на отсутствие документации (например на долгий онбординг пользователей или новых сотрудников). Зафиксировать онбординг в терминах времени/денег. Опосредованно посчитать нагрузку на саппорт для пользовательской документации. Популяризировать профессию и роль технического писателя. # Инструменты - Rst + Sphinx - Markdown + куча статик-сайт генераторов + pandoc - foliant.org - Asciidoc + Asciidoctor + Antora - Confluence + плагины - Специализированные вещи: - OpenAPI (+ AsyncAPI) - RAML - - PlantUML / Mermaid / Graphviz - C4-PlantUML - DITA - JavaDoc / Docbook / Sphinx # Минутка рекламы - [documentat.io](http://documentat.io) - [foliant.org](http://foliant.org) # Контакты: - [Семён Факторович](mailto:sam@documentat.io) - [Константин Валеев](mailto:kvaleev@gmail.com) - [Чатик DocOps](https://t.me/docsascode) - [Канал DocOps](https://t.me/docops) - [Чатик Techwriters Russia](https://t.me/technicalwriters) ================================================ FILE: content/teamleadconf/21/how_to_create_selforganizing_team.md ================================================ --- title: "Пошаговый алгоритм создания самоорганизующейся команды" author: "Андрей Булов" tags: ["TeamLeadConf", "2021"] summary: | * найти ваши ограничения и создать модель команды; * создать общение внутри и вовне команды (обратная связь, заказчик, менеджмент); * построить процесс разработки и вписать его в Agile; * как не фрустрировать и не разрушить команду при этом. --- # Зачем доклад если есть Scrum Рандомные техники и практики сами по себе не приводят к достижению самоорганинизации 🤷‍♂️ При этом если применить какой-то уверенный алгоритм и осознанный подход, то это может помочь. Самоорганизующаяся команда нужна чтобы: - У лида было время на личную жизнь, отпуск, свои задачи - Было эффективно # Общая схема из пяти шагов Анализ и подготовка: - Цель - Ограничения - Дизайн Имплементация: - Люди и планы - Запуск/вход # Анализ и подготовка ## Цель Без цели не собрать самоорганизацию — логично, ведь нужно понимать куда двигаться и что является путеводным маяком. Без цели люди работают работу на работе. Как найти цель: - Спросить у заказчика (или менеджера) - Подумать Критерии хорошей цели: - SMART/OKR - Должна зажигать **вас** - Согласована с заказчиками, стейкхолдерами, .... Одна из самых главных задач на этом уровне — это не просто услышать и зафиксировать цель, но и раскопать настоящие критерии успешности. Очень важно иметь возможность в любой момент сказать идём ли мы в правильную сторону. ## Ограничения То, что мешает или ограничивает ваши действия для достижения цели. Например: - Корпоративные (договоренности, ююрократия) - Проектные (бюджеты) - Человеческие (команда, менеджер, заказчик) - Технические (стек, инфраструктура) Как находить ограничения? - Говорить ртом с менеджементом, заказчиком, стейкхолдерами - Читаем все документы: от контракта до требований - Листаем уже существующий беклог Даже при одной и той же цели ограничения могут активно влиять на достижение цели: - Одно дело переводить legacy-проект на микросервисы с сильной командой и неограниченным бюджетом; - И совсем другое, если бюджета нет, а текучка два человека в месяц. Можно ли достичь цели Можно ли убрать ограничение Нужна ли вообще такая цель? # Дизайн команды Если расписать цель, критерии и ограничения, то дальше можно пойти дизайн команды ## Фреймворк Например: Scrum, Kanban, Command and Control Берём в кучку все наши ограничения, критерии цели и копаем какой из фреймворков подходит лучше. ## Структура команды Например, плоская, иерархичная, Leadership Team Та же тема — смотрим, изучаем, дописываем ограничения, исключаем неподходящие структуры, выбираем. ## Люди и планы На этом этапе нужно понять какие люди вам нужны, кто сможет двигать команду в сторону цели. Возможно поможет собрать "профиль специалиста". Обязательно открыто коммуницировать на этапе собеседований про существующие ограничения и ожидания от команды — без этого не собрать самоорганизацию. ## Этапы развития Собрать план развития команды, какие этапы, какие действия и когда. ## Итого Наличие такого дизайна очерчивает границы допустимого, явные цели и планы. Очень полезно, чтобы не собирать на удачу. # Имплементация ## Запуск/вход Нужно: - Явно транслировать цель и ограничения, подсвечивать, что некоторые вещи нельзя поменять - Объяснить правила и следующие шаги - Создать доверие Самый простой способ — просто собрать серию встреч, где честно поговорить, объяснить всю штуку выше и ответить на вопросы. ## Делаем Херши-Бланшар или "модель обучения ребёнка". 1. Показываем на своём примере: 1. Сначала нужно решить, что делать-то... 2. Проговариваете, что именно вы делаете; 3. Зовёте посмотреть команду на результат. 2. Продаём и даём попробовать: 1. На основе дизайна команды мы можем выделить конкретных людей и задачи; 2. Предлагаем взять сложную задачу и обещаем помощь и обучение; 3. Помогаем и обучаем, рассказываем все детали, передаём весь опыт; 4. Даём ещё пару таких задач, постепенно снижая уровень помощи. 3. Отдаём кусок работы, но встаём за спину: 1. Урезаем количество конкретных инструкций, увеличиваем описание проблемы; 2. Нужно быть всегда доступным для вопросов, но пытаться вывести людей на подумать самих; 3. Нужно дать возможность продолбаться и решить проблему самому. 4. Делегируем полностью: 1. Ха-ха, теперь у тебя такое же право голоса, как и у всех 2. Нельзя пытаться продавливать авторитетом, это рассыпает всю самоорганизацию 3. При изменении целей и ограничений нужно максимально оповещать команду, чтобы команда могла сама меняться ================================================ FILE: content/teamleadconf/21/learn_the_hard_way.md ================================================ --- title: "Как команде учиться на своих ошибках?" author: "Денис Сильверс" tags: ["TeamLeadConf", "2021"] summary: | Как добиться того, чтобы люди учились на своих ошибках и не повторяли их в будущем, а также — как соблюсти баланс между требовательностью к результату и открытостью к экспериментированию. --- # Что будет в докладе? Четыре вопроса: - Ошибки — это хорошо или плохо? - Как учатся люди и как учатся команды? - Какие принципы можно использовать, чтобы помогать команде учиться на своих ошибках? - Итог # Почему мы _думаем_ что ошибки — это плохо? **Страх Наказания**: «Если я ошибся, значит меня уволят / оштрафуют / отругают» Такой страх идёт из школ, из производства на заводах. **Страх Потери Лица**: «Если я ошибся, значит я плохой специалист и меня перестанут уважать» Такой страх идёт из социальных норм. # Почему ошибки — это _действительно_ плохо? **Можно Подобрать Оправдания**: «Мне поздно прислали данные» и всякое такое **Неправильный Вывод**: «Мы все время ошибаемся в оценке, давайте будем закладывать больше времени!» Такие последствия тормозят развитие и тогда ошибки — это плохо # Ошибки — это хорошо (Но только в том случае, если они не фатальные и мы на них учимся) Если составить графи от «Готовность совершать ошибки» до «Готовность учиться», то всех людей можно распределить на четыре квадранта. Доклад про то, как перетянуть людей из квадранта только «один нет» — или не готовы учиться, или не готовы совершать ошибки в квадрант «оба да». # Как люди учатся (в теории) В одном бесконечном цикле: 1. Составить план 2. Сделать 3. Собрать данные 4. Сделать выводы 5. Снова составить план 6. ... Например на примере Scrum: - Спланировали спринт - Сделали спринт - Обсудили, что сделали не так - Придумали что изменить - Спланировали спринт # И на практике Ментальные модели не дают на основе собранных данных сделать верные выводы. То есть ломается переход между третьим и четвёртым пунктом в теории. Например, даже если у команды не хватает ресурсов, и она договорилась больше не брать новых проектов — то новый, очень вкусный, проект, обязательно будет взят в работу 🤷‍♂️ Нам мешают наши _ментальные модели_, наше представление о мире, наши привычки. # Что делать? Признать, что есть проблема и перестать смиряться. ## Принцип эффективности Если команда не стремится к эффективности, то анализ своих провалов превратится в утомительное обсуждение мелких трудностей, имеющих тривиальное решение. Это значит, что команда не может делать задачи и двигаться к цели, **пока она не стремится быть эффективной**. Что можно сделать самостоятельно: - Уделять внимание планированию и риск-менеджементу. Что можно сделать на 1:1: - Знает ли ваш коллега цели компании? - Почему у компании именно такие цели? Что можно сделать вместе с командой: - Поставить адекватные цели для команды. ## Принцип ответственности Команда должна знать и понимать цену ошибку. Для этого важно, чтобы люди не только имели смелость открыто говорить об ошибках, но и чтобы они испытывали на себе последствия. Задача менеджера не экранировать команду от последствий ошибок, а давать место для внутренней взаимопомощи. Что можно сделать самостоятельно: - Не делать задачи за коллег, а помогать им научиться выполнять их. Что можно сделать на 1:1: - Не говорите коллеге, что делать, а спросить что он или она предпологает нужным сделать. Волшебные вопросы: «А как ты думаешь как это сделать?», «А что мешает это сделать?» Что можно сделать вместе с командой: - Поощрять участников команды помогать друг другу. ## Принцип обучения (желательно с первого раза) Настоящая проблема возникает не тогда, когда люди совершают ошибки, а тогда, когда они на них не учатся. Что можно сделать самостоятельно: - Показывать пример и признавать свои ошибки. Важно себя пересилить и сознаться, что вы тоже совершаете ошибки. Что можно сделать на 1:1: - Говорить о том, что вас растраивает (но при этом не обвинять никого). Очень сложно учиться, если не знаешь, что ты делаешь что-то не так. - Не стесняться расставаться с сотрудниками. Не превращайте свою работу и работу своего сотрудника в ад. Что можно сделать вместе с командой: - Не обвинять коллег и убедиться, что они не обвиняют друг друга. Невозможно учиться в защитной позиции, когда «это не моя вина» - Проводить ретроспективы. Можно почитать книжку ### Дополнительное чтение - Норм Керт «Ретроспектива Проекта» - Пятая дисциплина - Измеряйте самое важное # Финальные выводы Для компании важно не обучение на ошибках, а эффективность. Если трудность можно предвидеть — её нужно предвидеть. Если команда не учится на ошибках, то это потери, это не Agile / Teal / Holo. Ошибки есть не для ошибок, а для обучения на них. Если люди не знают цену ошибки, они не будут стремиться к предвидению и к обучению. Не экранируйте людей от опыта Думайте, что вы можете сделать _самостоятельно_, _1:1_ и _с командой_ ================================================ FILE: content/teamleadconf/21/process-smell.md ================================================ --- title: "Ваши процессы попахивают. Что с этим делать" author: "Филипп Дельгядо" tags: ["TeamLeadConf", "2021"] summary: | Подобно тому, как может пахнуть код, могут пахнуть и процессы. Доклад о конкретных признаках того, что в рабочих процессах что-то не так. --- # Что может быть не так в команде * Нерадивые сотрудники (как нам кажется). А на самом деле сотрудникам может быть неудобно работать. * Формальные отношения. «Пока не заведете формальную заявку, не сделаем вам задачу». А на самом деле на сотрудника падает ответственность, которую он не готов нести, так что приходится огораживать себя так. * Лишний труд: много встреч, неоправданно долгие встречи, ревью кучей людей. * Сплошная дребедень: много задач одновременно на одном человеке, постоянные переключения и многозадачность. * «Я в домике». Люди через тимлида общаются с другими людьми. Команды изобретают свои велосипеды и друг другу не показывают. К простой задаче куча комментариев. # Запахи на этапе работы ## Ритуал Главная причина плохого процесса — это **ритуал**. Процесс есть, а смысл его потеряли, забыли или не донесли до сотрудников. Чиним тем, что вспоминаем и рассказываем смысл процесса. ## Ложь Например, говорим что отмечаем посещаемость для требований закона, а на деле это используется для поощрений и увольнений. Говорим, что ОКР не влияет на бонусы, а на самом деле прямо влияет. Когда это выяснится, люди больше ничему не поверят. ## Коммуникации Можно использовать разные языки: исполнителя и менеджера. «Я сделаю это за неделю» может означать: * Я сделаю это не раньше, чем через неделю. * Через неделю это уже будет на проде. ## Неудобство Процесс/инструмент неудобный, поэтому этого и не делают. «Сначала посмотрите, где люди ходят, а потом асфальтируйте дорожки». # Запахи на этапе внедрения ## Очевидность > Любая сложная задача имеет простое, легкое для понимания неправильное решение.
> Артур Блох. Упала производительность на удаленке — давайте вернем всех в офис. Проще искать там, где светло, а не там, где потеряли. ## Безальтернативность Выбрали скрам, потому что. Альтернатив не рассматривали. ## Так делает Google Так делают в большой компании, поэтому и мы так будем. Есть убеждение, что если компания большая и успешная, то там идеальные процессы. Это ошибка. ## Так сказал Kent Beck Когда аргументом в споре является цитата из книги или доклада на конференции. Не верьте этому докладу на слово, не применяйте слепо. Пробуйте и проверяйте. ## Я так сказал! Когда что-то внедряется по приказу сверху. ## Карго-культ У кого-то А привело к Б, значит и у нас приведёт. Точно-точно! Например, история с самоорганизующимися командами применима к очень специфическим компаниям с их культурой. # Примеры ## Ревью кода в пулл-реквестах Придумано для мейнтейнеров опенсорса, когда контрибьюторы — случайные люди, которые могут быть некомпетентны или враждебны проекту. ## Системные аналитики Люди, которые придумывают описания системных экранов и прочие штуки. Человек должен одновременно разбираться в предметной области, технологических процессах, внутреннем устройстве кода, юзабилити и других вещах. И всё это за зарплату мидла. Это сложно, люди не справляются. ## Scrum Прекрасная практика, но внедряют обычно как попало. # Как сделать хорошо Идея из ТРИЗа: идеальная система — та, которой нет, но её функция выполняется. Идеальный процесс должен быть таким же. Вторая идея из ТРИЗа: выделение и разрешение противоречий. Фил рекомендует книгу «Месяц под звездами фантазии». ## Измерения Попытка что-то измерить, чтобы это потом менять, часто всё портит. Читать про закон Гудхарта. Смотреть доклад [Виталия Шароватова](https://t.me/vitaly19842) на CodeFest. ## Помощь клуба Есть, например, чат «Боль тимлида». Если там задать вопрос, ответ может вам не понравиться своей *конструктивной токсичностью*. В ответ на вопрос будут задавать другие неудобные вопросы про задачу и что вы делали для ее решения. Тут ценны не столько прямые ответы, сколько дискуссия, которая разворачивается вокруг вопроса. ## Философия * Метод радикального сомнения Декарта * СМД-методология Щедровицкого * Гегель, Энгельс, Платон, Витгенштейн, Богданов ================================================ FILE: content/teamleadconf/21/right_of_fail.md ================================================ --- title: "Контринтуитивная роль тимлида: дать право на ошибку и возможность быть человеком" author: "Сандра Урядова" tags: ["TeamLeadConf", "2021"] summary: | Если дать команде и себе право на уязвимость, то жить и работать станет проще. --- # Стресс тимлида Топ 3 трудностей у тимлидов: - «Я подозреваю, что есть инструменты, но я про них не знаю» - «Эмпатия, софтскиллы — это всё очень сложно» - «Ван-он-ваны это тоже сложно» Эти трудности были получены в результате исследование, но оно ещё не закончилось и опрос можно пройти [здесь](https://docs.google.com/forms/d/e/1FAIpQLSehoG3z_OgCuFLOoR-KRWYEQRlk31Cgm_toW6Apk47YzwKGuw/viewform). Это всё вызывает стресс у тимлида, из-за чего, например, тимлид может начать гиперответственно делать всё и за всех, а другие люди могут начать этим пользоваться 🤷‍♂️ Стресс тимлида переносится на команду — у команды растёт недовольство, незащищенность, одиночество. # Решение: стать уязвимым Это контринтуитивно, непривычно и страшно — потому что в момент максимального стресса очень не хочется признавать, что этот стресс и вообще какие-то проблемы есть. Но для того чтобы так делать, нужно быть человечным, уязвимым, и тогда команда это сможет увидеть # Софты vs Менеджерские навыки ## Софты В развитии софтом может помочь атмосфера и цели, которые поддерживают открытость. Например, через обучение и любовь к экспериментам. Ещё один важный навык — разделять «человека-персону» и «человека-коллегу», тогда можно факапить на работе, но оставаться всё ещё хорошим человеком. И наоборот. Без этого факап == плохой человек. Обязательно нужно рефлексировать и своё ощущение, свою открытость. Там же где-то рядом и идеи о собственной мотивации — легко идти за человеком, который верит в свою работу. Какие инструменты есть, чтобы разивать софты: - Когнитивно-поведенческий дневник (КПТ). Простая практика, которая требует минимальной дисциплины — каждый день записывать своё ощущение в конце дня и причины что «не так». Это позволит подсветить не просто ощущение, но и реальные причины, на которые можно будет повлиять; - Регулярная самодиагностика: таблица чувств / колесо эмоций. Если не видеть в себе каких-то чувств или эмоций, то легко сделать что-то, продиктованное не разумом, а чувствами; - Выделение смысла работы, что меня в работе драйвит: mindmap, думание, терапия; - Типологии: 16 personalities test, типы личностей из «Кругом одни идиоты». Сама по себе типология никак не можем помочь решить проблемы, но можно покопаться в окружающих и придумать разные подходы к разным людям. ## Менеджерские навыки Один из важнейших навыков — это делегирование, но делегирование гораздо более высокого уровня чем мы привыкли вкладывать, это про доверие общему результату. Без конструктивной критики от менеджера очень сложно расти и развиваться, и её нужно уметь давать. «Конструктивная критика» это именно конструктивная, не про «быть начальником», а про «искренне помогать» Для результата команда должна ясно видеть цели и ожидания, про это все уже более-менее понимают: OKR, backlog, roadmap. Команде нужно показать, что её действия приводят не просто к закрытым задачкам, но и к продуктовому результату. Если тимлид понимает боли бизнеса, то это передастся команде и увеличит пользу. Можно затащить кайдзен — и маленькими улучшениями съедать большой и болезненный командный процесс. # И зачем это всё? Когда в команде есть открытость, настроенные процессы, фокус на результате работы, то освобождаются психологические ресурсы, становится легче дышать, общаться и в конце концов привозить больше пользы команде, продукту и бизнесу. ================================================ FILE: content/whalerider/19/investor.md ================================================ --- title: "Как посмотреть на свой продукт глазами инвестора?" author: "Аркадий Морейнис, Антистартап" tags: ["WhaleRider", "2019"] summary: | Бывает момент истины, как у разведчиков. У стартапов этот момент происходит, когда стартап встречается с инвестором. --- Бывает момент истины, как у разведчиков. У стартапов этот момент происходит, когда стартап встречается с инвестором. ## 1. We have met the enemy, and he is us Проблема в том, что мы встречаем своего врага, и оказывается что это мы. Сами себе злобные буратины. Основатели зашорены и видят только свой стартап. Они ожидают того же от инвестора. Но у инвестора есть выбор. Его задача — заработать денег. Он может сделать это вкладывая акции в будущих единорогов, покупая акции Apple или Facebook, либо инвестируя в стартап. Получается, что настоящие конкуренты стартапа — это другие способы инвестировать деньги. Стартапер — первый инвестор своего стартапа. Он тоже хочет заработать денег и может выбирать. Необязательно хвататься за первую попавшуюся идею. В проекте на миллион и на сто миллионов одинаковое количество проблем. Поэтому стартапер должен считать себя инвестором и делать выбор. Это и есть его момент истины. ## 2. Парадокс гантели Талеба Мы должны уметь поднимать гантель Талеба — соблюдать гантельный принцип инвестиций: * Часть денег — в низкодоходные и низкорискованные активы. Например, банковский вклад. * Ещё часть денег — в потенциальные единороги, которые могут окупиться стократно. * А посередине гантели — ручка, туда вкладываться не надо. Там высокие риски и низкая доходность. Большинство стартапов — в этой категории. Стартапер, смотря на свой проект, должен понять: * Мы один из блинов? Низкодоходные и надёжные или потенциальный единорог? * Или мы ручка? ## 3. Выше стропила, плотники Предположим, за 5 лет наш проект заработает $1 000 000. Инвестор получит 10%, это $100 000. Но инвестор вкладывает во много стартапов и из них выстреливает примерно каждый десятый. Поэтому чтобы выйти в ноль, нужно получить х10. Значит, в такой проект инвестор вложит не более $10 000. ## 4. Все дураки, а я д'Артаньян На старом рынке есть старая проблема, которую мы собираемся решать старыми средствами. Например, «сделать маркетплейс, на котором есть вся мебель России». Здесь нет ничего нового. Что, за все эти годы никто не попробовал? Это либо никому не нужно, либо не проходит по деньгам. Нужны изменения в технологиях, на рынке или в поведении людей, позволяющие решить старую проблему новым способом. Например, Uber стал возможным, потому что появился рынок смартфонов с GPS. Когда устройства с GPS появились почти у всех водителей и почти у всех пассажиров, стал возможным Uber. Выросло поколение людей, для которых уровень доверия не зависит от наличия людей в офисе. А куда-то идти и общаться с людьми им сложнее, чем общаться с телефоном. Так появился банк Тинькофф — банк без отделений. Стартап — это капитализация произошедших изменений. ## 5. Проект, не имеющий аналогов У людей есть ограниченный бюджет времени и денег. Они уже тратят их на важные для себя вещи. Поэтому есть важный вопрос: «Чем люди перестанут пользоваться, когда начнут пользоваться нами?» Других вариантов нет. Самые страшные конкуренты — непрямые. * Заменители: те, кто решает ту же задачу, но другим способом. Например, можно сделать онлайн-курс по подготовке с ЕГЭ. Его настоящие конкуренты — обычные оффлайновые школы и репетиторы. * Вытеснители. Например, мы сделали отличный курс по истории исскуств. По времени ученика он конкурирует с ЕГЭ и другими предметами. По деньгам родителей он конкурирует с другими более важными расходами. * Канальные конкуренты. Например, онлайн-гид по стилю и магазин одежды. У магазина маржа выше, поэтому он просто перекупит всю рекламу. * «Привычный способ делать это». Убер конкурировал с привычкой взять телефон и позвонить в таксопарк. ## 6. Натягивать сову на глобус Есть термин product/market fit. Суть: сделать продукт и найти, куда его воткнуть. Это подходит, только если мы делаем маленькую фигню. Но в таком случае мы наверняка находимся в ручке гантели Талеба. Да здравствует market/product fill. Берём огромный рынок такси и заполняем его своим продуктом. Примеры: Uber, AirBnB. Новый рынок — это старый спрос. Нельзя создать новый рынок. Появляется новый продукт, удовлетворяющий старый спрос за счёт изменений в технологиях, на рынке или в поведении людей. Продавать одно под видом другого. Люди не любят покупать старые вещи и не любят покупать новые вещи. Зато любят старые, в которых есть что-то новое, либо новые, в которых есть что-то старое. Принцип MAYA: Most Advanced Yet Acceptable. iPhone — это персональный компьютер под видом смартфона. ## 7. Где драйвер, чувак Как мы будем заполнять рынок? Качесто и функциональность не драйвят рост. Это фильтр для отсечения. Чему пропорционален рост выручки? Всегда есть драйвер роста — счетный и непрерывный показатель. ## 8. Не посадить, а вырастить Минимальный жизнеспособный продукт — это не технический прототип и не лендинг. Это прототип воронки продаж. Инвестору важно, чтобы было на чём тестировать воронку продаж. «Пользователи приходят сами, а мы не потратили ни копейки на маркетинг.» Это не достоинство, а не достаток. Мало иметь клиентов и тестировать продажи. Нужно тестировать возможности роста. ## 9. Одной картинкой Вот, что нужно: 1. Большой рынок: большой спрос и старый способ делать что-то 2. И мы должны иметь большие амбиции 3. Найти изменения, которые делают возможным новый продукт 4. С его помощью мы будем вытеснять старый способ делать это 5. Минимальный жизнеспособный продукт — тестирование возможности роста и вытеснения старого способа. ## 10. Что дальше * Посмотреть на себя и на свой стартап и сказать: «Я первый инвестор своего стартапа». * Оценить стартап взглядом инвестора. * В любом случае сохранять большие амбиции. ================================================ FILE: layouts/index.html ================================================ {{ define "main" }}
{{ partial "index/introduction.html" . }}
{{ range (.Paginate .Site.RegularPages).Pages }} {{ .Render "summary" }} {{ end }}
{{ end }} ================================================ FILE: layouts/table.html ================================================ {{ .Inner }}
================================================ FILE: readme.md ================================================ ![Deploy to GitHub Pages](https://github.com/docops-hq/conf/workflows/Deploy%20to%20GitHub%20Pages/badge.svg) # Конспекты IT-конференций Конспекты докладов с IT-конференций: * [Highload++ 2018](https://highload.ru). * [Moscow Python Conf++ 2019](https://conf.python.ru) * [Saint Highload++ 2019](https://www.highload.ru/spb/2019) * [KnowledgeConf 2019](https://knowledgeconf.ru/) * [РИТ 2019](https://ritfest.ru/2019) Проект [Николая Волынкина](https://t.me/nick_volynkin). Отправляйте пуллреквесты с дополнениями и новыми конспектами. Подписывайтесь на канал [@docops](https://t.me/docops) в Telegram. ================================================ FILE: static/.nojekyll ================================================ ================================================ FILE: static/custom.css ================================================ p{ font-family: "Times New Roman"; } .catalogue-tags { background-color: #e2e2e2; padding-left: 0.8rem; padding-right: 0.8rem; padding-bottom: 0.4rem; padding-top: 0.4rem; margin-right: 0.8rem; border-radius: 4px; } .tags { color: #2f2f2f; font-size: 1rem; font-family: "Times New Roman"; } table { width: 100%; } tr { background-color: #e8e8e8; } td { horiz-align: left; padding-right: 8px; padding-left: 8px } th { padding: 8px; text: 16px } h2 { font-weight: normal; } .single__header { margin-bottom: 20px; } .tag-block { display: flex; justify-content: center; }