Showing preview only (409K chars total). Download the full file or copy to clipboard to get everything.
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, то гораздо меньше.

Ещё все знают, что много слоёв — это плохо, а хорошо делать так:

Однако, попробуйте-ка подебажить такую сборку.
Где оно упало внутри этого шага? Никто не знает.
Приходится вручную выполнять по одной строке.
Ещё код приложения меняется часто, а зависимости редко.
Поэтому приходится сначала добавлять `requirements.txt`, потом `pip install -r requirements.txt`,
и только потом добавлять оставшийся код приложения.

Ещё нередко из одного репозитория мы можем собирать много образов.
Мы можем сделать много докерфайлов или один докерфайл со stage'ами,
и потом запускать сборку через shell-cкрипт.
И всё это только вершина айсберга!
* Есть ещё история с монтированием.
* Например, мы хотим закешировать результат работы какого-то менеджера зависимостей.
* Или мы хотим ssh и нам нужно пробросить сокет ssh-агента.
* Или мы хотим собирать образы без shell, а хотим использовать Ansible.
* Наконец, можно хотеть собирать образы вообще без Docker.
Так нам для сборки понадобится виртуальная машина, но у нас же уже есть k8s.
Однако, в нём докер, а в докере собирать докер-образы — это плохо.
* Параллельная сборка. Тут параллельность можно понять кучей способов.
* Распределенная сборка. Поды теряют кеши, с этим нужно что-то делать.
* Автомагия!
Чем решаются эти проблемы:
* moby/buildkit
* Kaniko
* Buildpacks.io
* buildah
* genuinetools/img
Параллельно развивается куча альтернативных сборщиков.
Каждый из них решает часть задачи, а целиком — ни один.
Werf делают пять лет.
Сделанное отмечено синим, план к концу этого лета — жёлтым.

# Публикация в registry (push)
Вопрос: как тегировать образ?
Нужно гарантировать воспроизводимость.
У нас есть коммит в гите, он иммутабельный.
Мы хотим из него собрать образ и сохранить связь между ними.
Когда на проде работает приложение, мы хотим узнавать, из какого коммита оно собрано.
## git tag
Обычный путь такой:
1. Поставили тег в гите
2. Собрали образ и поставили тот же тег на него
3. Протестировали
4. Выкатили на прод
Тут есть проблемы:
* Порядок контринтуитивный. Мы сначала тегировали, а только потом тестируем.
* Плохо сочетается с git flow.
## git commit + tag
Собираем и тестируем образы из коммитов.
Когда очередной коммит/образ прошёл все тесты и мы готовы выкатывать его на прод, ставим тег на уже собранный образ.
Ограничение: только fast-forward merging, не поддерживает мерж-коммиты.
## Content addressable
Берём хеши исходных докер-образов, текст всех команд и хеши скопированных файлов.
Делаем из этого один хеш.
Он становится сигнатурой образа.
В список файлов можно не включать то, что не влияет на приложение, например changelog.
Плюс: сигнатура не меняется от мерж-коммитов.
Минус: нельзя точно восстановить, из какого коммита собран образ.
Это решается слоем с метаданными.
# Очистка registry
Рано или поздно место в registry заканчивается.
Если мы пушим новый образ с тем же тегом, какие-то слои устаревают, и registry с этим справляется.
Но есть и тегированные образы, которые больше не нужны.
Давайте будем их удалять.

Стратегии очистки:
* Не чистить.
* Сделать полный сброс.
А после удаления нажать везде 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.

Можно делать иначе: между старой и новой версией смотреть, что удалено,
а между боевой и новой — что добавлено и изменено.

Вывод: декларативный подход не так прост.
Даже с декларативным описанием есть магия.
Но без декларативного подхода всё сильно хуже.
## Применено ≠ выкачено
Представим, что у нас есть CI-система.
Она получает ивент и запускает деплой:
1. Берёт шаблоны в YAML или JSON
1. Отдаёт их движку шаблонов
1. Получает отрендеренную конфигурацию
1. Применяет к ней изменения из боевой конфигурации k8s через 3-way merge.
1. Применяет результат обратно к k8s через API
1. K8s отвечает успехом CI-системе, а она отвечает пользователю.
Применена новая конфигурация? Да. Выкачена? Нет.

K8s отвечает OK, когда получил новую конфигурацию.
Но применяется она не моментально.
Так работают Helm и kubectl.
А если pod не сможет рестартануть с новой конфигурацией?
«Пуля вылетела, проблемы на вашей стороне».

Поэтому нужен трекер, который следит за состоянием 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 месяцев, не сработало.
Похоже, что не получилось до каждого сотрудника донести процедуру.
А сотрудникам не хватает команды в написании статьи.
Добавили в схему детали:
* Прежде чем писать драфт, можно обсудить тему с пиарщиком и провести исследование.
* Когда драфт написан, дальше обсуждаем его с пиарщиком и командой.
* Когда статья готова, пиарщик её вычитывает и редактирует.
* И когда статья опубликована, пиарщик будет её пиарить!

Прошло ещё 6 месяцев, выпустили первую статью.
## План номер четыре: ghostwriter
Определение от Марии Кругловой:
Ghostwriter — человек, влияющий на создание статьи с момента зарождения идеи,
в течение всего процесса её написания и защиты, активный модератор статьи, корректор и психолог.
Задача — сформировать у разработчика уверенность, что статью написал именно он.
Процесс
1. Ищем автора. Вот признаки, что человек может:
* человек выступал на внутреннем девклубе,
* читал лекцию на стажировках или курсах,
* вёл практические занятия,
* выступал на конференциях или митапах,
* или просто обсуждал что-то в курилке.
2. Создаём основу статьи.
Берём что угодно, что осталось от первого опыта:
* презентацию от доклада,
* инструкции во внутренней доке,
* конспект для себя перед лекцией,
* видеозапись выступления;
* с конференций куча материалов остаётся.
1. Обрабатываем основу:
* Проверяем «на bullshit»: насколько это уникально и что нового автор открыл миру.
* Наполняем словом. (Сейчас этот этап чаще делает пиарщик.)
* Делаем авторский стиль.
* Добавляем комментарии.
В тех местах, где ghostwriter'y непонятно, уточняем подробности.
1. Смотри, какую статью ты написал!
* Проверям, что восприятие в статье верное.
* Дополняем и работаем с комментариями.
* Подключаем техлида к ревью (впервые в этом процессе).
Техлид даёт верные комментарии.
* Добавляем лоска тексту.
1. В продакшен
* Публикуем статью
* Автор в течение нескольких дней отвечает на комментарии
* Автор сам публикует куда-нибудь ссылки на свою статью, тренирует способность делиться и самопиариться.
1. Через несколько недель после статьи предлагаем написать ещё.
# Результаты
* Повышаем уверенность сотрудников в себе.
* Показываем сотрудникам основные ошибки в тексте.
* Убираем синдром самозванца
* Выпускаем статьи, на это есть KPI
* Иногда разработчики сами приходят.
# Как наладить бесперебойный процесс производства статей
Обучение:
* Лекции в отделах
* Тренинги по написанию статей
* Проверяем идеи статей на жизнеспособность
* Личные встречи с разработчиками.
Мотивация — штука сложная и спорная.
Что сделать, чтобы была мотивация?
* Статья включается в KPI сотрудника.
Выделяем процентов 20 рабочего времени на написание статьи.
* Те, кто пишут статьи, перыми едут на конференцию.
* Людей мотивирует отклик аудитории и клиентов.
Из приятного: заработало сарафанное радио.
Люди на собеседованиях вспоминают, что в этой компании ещё и статьи пишут.
А ещё все удивляются, что в Калининграде не только военные и корабли есть.
# Итоговый процесс
выглядит так:

# Правила 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-проекты, вот такие:
> 
На самом деле проектов было немного больше:
> 
## Реальность
* Стать популярным через опенсорс — плохой способ.
Гораздо полезнее писать статьи и выступать на конференциях.
* Отличный проект не обязательно получит звездочки.
Более эффективно будет вложить усилия в небольшой PR в популярный проект:
исправить документацию или починить баг.
* Хороший смысл заниматься опенсорсом — изменить мир.
Доклады и статьи вдохновляют, но ничего не меняют.
А код — меняет.
Например, Autoprefixer вытеснил Compass.
Вот анонс Autoprefixer.
Основная ошибка — нет английского языка.
<blockquote class="twitter-tweet" data-lang="en"><p lang="ru" dir="ltr">Сделал Autoprefixer — он парсит ваш CSS (или Sass) и по базе с Can I Use добавляет нужные (и только нужные) префиксы <a href="https://t.co/2N4JICHhDq">https://t.co/2N4JICHhDq</a></p>— Андрей Ситник (@andrey_sitnik) <a href="https://twitter.com/andrey_sitnik/status/321655851565850624?ref_src=twsrc%5Etfw">April 9, 2013</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
## Формула успеха проекта
Популярность проекта =
ваша популярность +
продвижение +
преимущества для пользователей +
удача.
Популярность проекта зависит от вашей, а ваша — от популярности проекта.
Создайте англоязычный твиттер!
Старый проект набирает подписчиков, их можно использовать для
Неважно, как пользователь узнает о вашем проекте.
Рано или поздно ему потребуется документация.
Когда и как люди читают документацию.
Спокойно и с чашечкой кофе? Нет!
Они в огне, у них нет времени и сил.
Объясните, зачем людям читать вашу документацию, иначе они не будут читать.
Плохо:
> :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 предложений.
Люди читают не весь текст.
Примерно вот столько:
> 
Что с этим делать?
* **Добавляйте иллюстрации** и примеры кода.
* **Выделяйте главное** в начале пункта списка.
## Как люди выбирают фреймворки?
Кажется, что они делают этот выбор рационально.
На самом деле нет.
Люди выбирают то, про что говорят лидеры мнений.
Важно писать, кто использует проект.
Чтобы кто-то его использовать, можно прийти в любой проект и предложить заменить зависимость.
После первого проекта становится проще: «а Х уже перешли на наш инструмент».
Раз в месяц нужно что-то писать и говорить о проекте.
Статьи, доклады, твиттер.
Получается, что всё держится на хайпе, и чтобы конкурировать, нужно только подливать масла в огонь хайпа.
Всё это грустно.
Поэтому доклад закончился и теперь будет другой доклад.
---
# Как мы убиваем инновации во фронтенде
Андрей Ситник, Злые Марсиане
Однажды Испания профинансировала стартап Колумба и он открыл Америку.
Это произошло по ошибке.
В Америке испанцы нашли серебро, обогатились на нём, но всё потратили на войны и прочую ерунду.
В развитии технологии есть три стадии:
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: <font>abc</font>
- JSSS: tags.H1.color
- CSS Expressions: expression(a+b)
- CSS!
У CSS есть множество проблем: отсутствие реиспользования, неявность, неинтерактивность, сложность чтения.
Потом начали появляться решения, которые пытались пофиксить CSS -- например, БЭМ, который вводил новые сущности и
абстракции, упрощающие стилизацию приложения. А потом bootstrap, shadow dom, webpack, component, css modules, ...
И проснулось дублирование!
```html
<button type="button" class="btn-cls">Button</button>
```
Хотя 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
Авито: много сервисов и очень много связей между ними.
Вот основные проблемы от количества:
* Много разных репозиториев. Сложно менять код одновременно везде.
* Много команд пишут код, не пересекаясь с другими. Знания инкапсулируются и плохо передаются между командами. Нет единой картины. Нет человека, который бы всё знал.
* Данные фрагментарны.
<!--more-->
Проблемы с инфраструктурой: слишком много элементов:
* Логирование
* Мониторинг
* Сборка
* Общение
* Трекер задач
* Документация
* Аааааа
Слои: 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-задач в графике
Учителем выступает что-то “свыше” – либо из реальной жизни, либо что-то нарендеренное из движка:
* Создание правдоподобных анимаций
* Постобработка отрендеренных изображений
* Интерполяция кадров
* Генерация материалов
Учителем выступает какой-то алгоритм из вычислительной математики:
* Рендеринг сложных объектов: например, облаков
* Физические симуляции
### Главная идея
Если у вас есть вычислительно сложная задача, которую вы решаете некоторым классическим вычислительным способом, попробуйте найти в этой задаче самое времязатратное место и найти решение с помощью нейронной сети или любого другого алгоритма машинного обучения.
\- *общий рецепт как еще можно найти применение для машинного обучения*
### Постановка проблемы
Нужно нарисовать физически корректно облако, которое представлено как плотность капелек жидкости в пространстве.

Физически сложный объект:
* Не твердый объект, нельзя наложить текстуру и рендерить
* Капельки воды почти не поглощают свет
* Они его переотражают, делают это анизотропно
Рендеринг облака может занимать много часов, дни.
Художнику хочется как можно быстрее получать ответ (отрендеренное облако), чтобы иметь возможность экспериментировать с освещением сцены, топологией облака и т.п.
Нужно ускорить.
### Классическое решение
Сложное уравнение:

Второй терм уравнения – прямое освещение (Direct Light). Свет, который приходит от солнца, попадает на точку выхода, по вектору, который выпущен из камеры, приходит в камеру, при этом он как-то затухает, т.е. интенсивность теряется.
Первый терм – интегрирование по отрезку луча, проходящего внутри облака – опосредованное освещение (Indirect Light). Моделирует переотражение каплями света внутри облака. Интеграл I1 – это интеграл по сфере, которая окружает точку на луче. В классическом алгоритме считается с помощью Монте-Карло интегрирования.
Это самая долгая часть во всем алгоритме и самая сложная.
### Рецепт для ML алгоритма
Самое тяжелое – посчитать Монте-Карло оценку. Она дает какое-то число, которое обозначает опосредованное освещение в точке.

Будем предсказывать Монте-Карло оценку освещения в точке – выход для ML алгоритма.
Вход:
* Топология плотности вокруг точки
* Направление на источник
* Направление на камеру (так как капли переотражают свет не изотропно)
### Обучение
Нужно сконструировать вход в нейронную сеть.
Первое – описать локальную плотность. Вокруг точки на отрезке луча возьмем трехмерную сетку с шагом равным длине свободного пробега в облаке. В узлах сетки – плотность облака. Увеличим шаг между узлами сетки в два раза, возьмем новую сетку, измерим плотности в её узлах. Так сделаем несколько раз.
В результате этой процедуры имеем несколько сеток, охватывающих все большую и большую окрестность вокруг точки. Такое представление оправдано, потому что мы хотим максимально подробно описывать маленькую область, и чем мы дальше от точки тем менее подробное мы хотим описание.

Обучать будем так: нагенерим разных облаков, будем применять классический алгоритм, записывать что он получает как ответы Монте-Карло интегрирования и фичи, на которых эти ответы были получены. Получили датасет, на котором можно обучаться.
### Архитектура сети
Не является ключевой в этой задаче.
Каждая сетка попадает в блок из двух fully-connected слоев.

### Результаты
Повышение скорости рендеринга в несколько сотен раз.
Реализация:
* Инструмент для рендеринга произвольных сцен, в которых есть облака
* Облако задается кубом в интерфейсе Blender

================================================
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
(Пока что) не профакапленная платформа.
Сделали несколько кластеров — застраховались сами от себя. Если положат один, то только один, а не всю систему.
Архитектура:

## 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, «помнящая ткань».
База — это место, где сущности создаются и редактируются. Остальное — кеши.
К сущностям нужно как-то получать доступ, поэтому появляются команды, которым принадлежат сервисы. С сервисом без команды работать сложно. Конкретный человек, который много коммитил — не решение, потому что он может уволиться. Поэтому нужно хранить команды и людей за ними.

Не нужно заполнять весь граф вручную, данные можно достать во внутренних системах.
* Команды — 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 — это <strike> клёво</strike>, удобно.
Что именно 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).

Итог
* 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
* в результате нагрузка на диск в форме пилы.

## 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 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
* инкрементальный унос «хвоста» бинлога
Эта же схема используется для создания бэкапов.

# Логи
Как собираются?
* отправка в memcached. Там кольцевой буфер (`ring-buffer: prefix.idx = line`).
* отправка в logs-engine (разработан in-house)
Хранятся в ClickHouse. Чтобы это заработало, приходится локальный rpc-proxy заменить на KittenHouse, а на движке добавлять KittenHouse reverse proxy.
А ещё есть nginx, чтобы получать логи по UDP.

# Мониторинг
Есть два типа метрик.
Системные и админские метрики:
* 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: |
БД — вещь простая, а люди сложные, поэтому советы могут не всем подойти.
Сам следовал не всем советам.
---
БД — вещь простая, а люди сложные, поэтому советы могут не всем подойти.
Сам следовал не всем советам.
# Кем мы хотим стать
Карта навыков:

Любой роли полезно иметь навыки из соседних областей.
# Надо ли оно нам
* Скучно точно не будет. БД — это интересно.
* Покуда есть данные, будут и базы. Они могут поменяться, но они будут.
* 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.

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

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

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 умеет ещё и в авторизацию.

Авторизация средствами прокси: 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
## Начало работы
```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:

================================================
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 и UDP.
В них сильно отличается структура пакетов:

Главное: TCP задуман как протокол надёжной доставки данных, а UDP — нет.
Может ли оказаться, что UDP лучше решит задачу надёжной доставки?
# Цели на сегодня
* Как работает сеть
* Зачем сравнивать TCP или что с ним не так
* С чем и на чём сравнивать TCP
* Как это сделал Google
* Какое будущее сетевых протоколов нас ждёт
Теорию и математику обсуждать не будем.
Будем разбирать практические кейсы.
# Мобильный мир победил
Важно: сначала появились проводные сети, но беспроводные, которые появились позже, сейчас явно победили.
Большая доля трафика — мобильный трафик или хотя бы вайфай.
В беспроводных сетях бывают потери пакетов, смена порядка и jitter.
Протокол TCP/IP скрывает от нас эти ошибки.

Вот средние параметры соединения у пользователей мобильного интернета.

Итоги:
* \> 80% используют беспроводной интернет
* парметры беспроводных сетей постоянно меняются
* в них высокие показатели packet loss, jitter, reordering
* фиксированный асимметричный канал, возможна смена IP-адреса
Статистика показывает, что потребление мобильного видео зависит от качества канала.
Получается, что TCP не очень эффективен для доставки контента.
Пробовали распараллелить загрузку данных с клиента — использовать несколько одновременных соединений.
Получается быстрее.
Ошибки уменьшают утилизацию канала, а распараллеливание при ошибках помогает увеличить утилизацию:

# Почему нам не подходит TCP
Итого: зачем же нужно сравнивать ТCP?
* беспроводные сети победили и они нестабильны
* потребление контента зависит от скорости интернета
(а мы хотим, чтобы пользователи потребляли больше)
* TCP плохо утилизирует канл на нестабильных сетях.
Распараллеливание помогает, но не всё можно распараллелить.
Что с этим делать?
* Можно сделать свой протокол рядом с TCP и UDP.
И годами ждать, пока его поддержат все участники интернетов.
* Или сделать свой надёжный протокол поверх UDP в User Space.
получаем smUDP: self-made UDP
У разного контента разные профили потребления сети.

# HTTP 1.1 и HTTP/2
Конечно же мы должны сравнить протоколы на HTTP 1.1 и HTTP/2.
HTTP 1.1 предлагает использовать по одному соединению на каждую единицу контента.
HTTP/2 — одно мультиплексированное соединение.

При этом в HTTP 1.1 клиент (браузер) обычно использует пул соединений.
Проблема в том, что между соединениями есть конкуренция.
Картинка, которую пользователь уже пролистал и больше не увидит,
конкурирует с другой, которая впереди в ленте.
И в HTTP 1.1 сложно отменить загрузку — только закрыть сокет и отменить соединение.

HTTP/2 лучше:
* бинарный, со сжатием заголовков;
* есть мультиплексирование,
* приоритизация,
* отмена загрузки,
* и server push.
Приоритизация позволяет получить приоритетный контент раньше:

Server push: сервер может отдать контент, который точно понадобится в будущем.

Отмена загрузки: если клиенту уже не понадобится контент, клиент может отказаться от загрузки.

# Сравниваем TCP и smUDP
Итого, на чём нам сравнивать TCP и smUDP
* Профили сети: WiFi, 3G, LTE
* Профили потребления:
* стриминг
* мультиплексирвоание и приоритизация с отменой загрузки (в HTTP/2)
## Простая сеть: bandwidth + RTT
В TCP важен размер буфера отправки.
Сервер держит контент в буфере, пока не получит подтверждение (acknowledgement), что контент получен.
Но чем больше RTT, тем дольше ждать подтверждения.

Если мы увеличим размер буфера, то фактическая ширина канала вырастет.

Но всё не так просто.
Важны on-the-fly packets.
Это те, которые мы отправили, но ещё не получили подтверждения.
Если буфер слишком мал, то мы недоиспользуем сеть, как мы уже поняли.
Но если буфер слишком большой, то мы приходим к распуханию буфера (bufferbloat).
Буфер заполнен кучей on-the-fly пакетов, а скорость снова маленькая.
Казалось бы, давайте временно увеличивать буфер, когда нам нужно отправить много пакетов.
Но буфер нельзя просто так уменьшить.
А если у нас свой протокол, то мы можем:
* уменьшать буфер
* раньше отправлять более важные пакеты
* если клиент отправил cancellation, сбросить пакеты из буфера

Как это делается?
Присваиваем отправляемым пакетам сквозной sequence number.
Итак:
* размер буфера имеет значение
* mutable buffer — это хорошо
## Сложная сеть: bandwidth + RTT + packet loss
Стандартный алгоритм: если за установленное время сервер не получил acknowledgement, он повторно посылает пакет.
Давайте снова будем терять пакеты.
Разберёмся, как работает Congestion Control.
Для начала, TCP window: количество одновременно отправляемых пакетов.
Отправитель начинает с 10 и разгоняется, увеличивая количество.
Если в какой-то момент пакеты теряются, он уменьшает окно и снова разгоняется.

Congestion Control придуман для предотвращения перегрузки сети.
Вот где-то в сети есть роутер, который больше всего нагружен.
Он умный: не ждёт когда совсем перегрузится, а начинает дропать пакеты чуть раньше,
чтобы отправитель уменьшил окно.

Вся эта схема придумана давным-давно для проводных сетей.
Там потеря пакетов могла означать только одно:
где-то перегружен узел, надо снизить скорость.
Но в беспроводных сетях не так!
Там пакеты теряются просто потому что соединение беспроводное.
Получается, есть два типа потерь:
* congestion loss, от переполнения
* random loss, от плохого беспроводного соединения
## Каким бывает Congestion Control
Congestion Control эволюционирует.
Нам особенно интересны реализации Cubic и BBR.

Если скорсть растёт, BBR схлопывает окно заранее, Cubic дожидается потери пакетов и тогда схлопывает окно.

Работают они так:
* 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.

Мобильные сети асимметричны.
Обычно 70% на приём и 30% на отправку.
Стоит разделить jitter на приём и отправку.
Какой congestion control выбрать на сервере?

А на клиенте всегда Cubic и мы не можем на это повлиять.
Выводы такие:

================================================
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
<!-- https://www.tablesgenerator.com/markdown_tables -->
# Аллокации в 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-код функции
Можно вот так посмотреть:

Есть flame-graph:

Построчный вывод:

## Наконец, оптимизация
* `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: |
<span id="why"><sup>*</sup></span>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('/<int:index>')
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('/<int:index>')
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 питонистов.
Важно: Яндекс — большая компания, потому сложно сказать про всех сразу.
Доклад Александра — в первую очередь про его
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
Condensed preview — 65 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (408K chars).
[
{
"path": ".github/workflows/main.yml",
"chars": 574,
"preview": "name: Deploy to GitHub Pages\n\non:\n push:\n branches: [ master ]\n\njobs:\n deploy:\n runs-on: ubuntu-latest\n\n step"
},
{
"path": ".gitignore",
"chars": 26,
"preview": ".idea\r\npublic\r\nresources\r\n"
},
{
"path": ".gitmodules",
"chars": 108,
"preview": "[submodule \"themes/tale-hugo\"]\n\tpath = themes/tale-hugo\n\turl = git@github.com:docops-hq/conf-hugo-theme.git\n"
},
{
"path": "archetypes/default.md",
"chars": 84,
"preview": "---\ntitle: \"{{ replace .Name \"-\" \" \" | title }}\"\ndate: {{ .Date }}\ndraft: true\n---\n\n"
},
{
"path": "config.toml",
"chars": 298,
"preview": "baseURL = \"https://docops-hq.github.io/conf/\"\nlanguageCode = \"en-us\"\ntitle = \"Конспекты\"\ntheme = \"tale-hugo\"\n[taxonomies"
},
{
"path": "content/aletheia/19/assessment.md",
"chars": 3009,
"preview": "---\ntitle: \"(Почти) Объективная оценка людей в IT\"\nauthor: \"Георгий Могелашвили, Booking.com\"\ntags: [\"Aletheia Business\""
},
{
"path": "content/aletheia/19/culture-transformation.md",
"chars": 3519,
"preview": "---\ntitle: \"Трансофрмация бизнес-культуры: преодолеть сопротивление, добиться результата\"\nauthor: \"Марина Корсакова, МИР"
},
{
"path": "content/devopsconf/19/fast-releases.md",
"chars": 2335,
"preview": "---\ntitle: \"Как доставить быстро и без боли. Автоматизируем релизы\"\nauthor: \"Александр Коротков, ЦИАН\"\ntags: [\"DevOpsCon"
},
{
"path": "content/devopsconf/19/werf.md",
"chars": 8846,
"preview": "---\ntitle: \"werf — наш инструмент для CI/CD в Kubernetes\"\nauthor: \"Дмитрий Столяров, Тимофей Кириллов, Алексей Игрычев, "
},
{
"path": "content/devrelconf/5/brand-ambassador.md",
"chars": 2951,
"preview": "---\ntitle: \"Как готовить начинающих спикеров, чтобы они превратились в опытных бренд-амбассадоров\"\nauthor: \"Евгения Голе"
},
{
"path": "content/devrelconf/5/ghostwriters.md",
"chars": 5733,
"preview": "---\ntitle: \"Профессия «Ghostwriter», или Учим программистов писать статьи\"\nauthor: \"Мария Круглова, KODE\"\ntags: [\"DevRel"
},
{
"path": "content/devrelconf/5/technical-authors.md",
"chars": 3784,
"preview": "---\ntitle: \"Пишем не только код, но и статьи: как помочь разработчику стать техноавтором\"\nauthor: \"Антонина Татчук, Авит"
},
{
"path": "content/frontendconf/19/promoting-opensource.md",
"chars": 6174,
"preview": "---\ntitle: \"Продвижение опенсорс-проектов (+1 секретный доклад внутри)\"\nauthor: \"Андрей Ситник, Злые Марсиане\"\ntags: [\"F"
},
{
"path": "content/frontendconf/19/style_silver_bullet.md",
"chars": 3137,
"preview": "---\ntitle: \"В поисках Стилевого Грааля\"\nauthor: \"Артур Кенжаев, Яндекс.Маркет\"\ntags: [\"FrontendConf\", \"2019\"]\nsummary: \""
},
{
"path": "content/highload/18/1.1-microservices.md",
"chars": 4754,
"preview": "---\ntitle: \"Что мы знаем о микросервисах\"\nauthor: \"Вадим Мадисон, Avito\"\ntags: [\"Highload\", \"2018\", \"Avito\"]\nsummary: |\n"
},
{
"path": "content/highload/18/1.10-neural-nets-cgi.md",
"chars": 4326,
"preview": "---\ntitle: \"Как нейронные сети графике помогали\"\nauthor: \"Евгений Туманов (NVIDIA)\"\ntags: [\"Highload\", \"2018\"]\nsummary: "
},
{
"path": "content/highload/18/1.2-per-aspera-ad-paas.md",
"chars": 4626,
"preview": "---\ntitle: \"Тернии контейнеризированных приложений и микросервисов\"\nauthor: \"Иван Круглов, Booking.com\"\ntags: [\"Highload"
},
{
"path": "content/highload/18/1.3-data-discovery.md",
"chars": 3519,
"preview": "---\ntitle: \"Один из вариантов реализации Data Discovery в микросервисной архитектуре\"\nauthor: \"Николай Голов, Avito\"\ntag"
},
{
"path": "content/highload/18/1.4-bd-k8s.md",
"chars": 4175,
"preview": "---\ntitle: \"Базы данных и Kubernetes\"\nauthor: \"Дмитрий Столяров, Флант\"\ntags: [\"Highload\", \"2018\"]\nsummary: |\n 1. Филос"
},
{
"path": "content/highload/18/1.5-kafka-bicycle.md",
"chars": 4048,
"preview": "---\ntitle: \"Apache Kafka как основа для велосипедостроения\"\nauthor: \"Николай Сивко, okmeter.io\"\ntags: [\"Highload\", \"2018"
},
{
"path": "content/highload/18/1.6-accelerate-events.md",
"chars": 2144,
"preview": "---\ntitle: \"Разгоняем обработку событий до 1.6М/сек. Опыт Badoo\"\nauthor: \"Александр Крашенинников, Badoo\"\ntags: [\"Highlo"
},
{
"path": "content/highload/18/1.7-postgresql-errors.md",
"chars": 5656,
"preview": "---\ntitle: \"Топ ошибок со стороны разработки при работе с PostgreSQL\"\nauthor: \"Алексей Лесовский, Data Egret\"\ntags: [\"Hi"
},
{
"path": "content/highload/18/1.8-badoo-infradev.md",
"chars": 3380,
"preview": "---\ntitle: \"«Платформа» в Badoo: как мы построили инфраструктурную разработку\"\nauthor: \"Антон Поваров, Badoo\"\ntags: [\"Hi"
},
{
"path": "content/highload/18/1.9-data-engineers.md",
"chars": 5084,
"preview": "---\ntitle: \"Дата-инженеры и кому они нужны\"\nauthor: \"Валентин Гогичашвили, Zalando SE\"\ntags: [\"Highload\", \"2018\"]\nsummar"
},
{
"path": "content/highload/18/2.1-vk-architecture.md",
"chars": 5079,
"preview": "---\ntitle: \"FAQ по архитектуре и работе ВКонтакте\"\nauthor: \"Алексей Акулович, ВКонтакте\"\ntags: [\"Highload\", \"2018\", \"ВКо"
},
{
"path": "content/highload/18/2.2-testing-badoo.md",
"chars": 6348,
"preview": "---\ntitle: \"Монолит для сотен версий клиентов: как мы пишем и поддерживаем тесты\"\nauthor: \"Владимир Янц, Badoo\"\ntags: [\""
},
{
"path": "content/highload/18/2.3-such-highload.md",
"chars": 4677,
"preview": "---\ntitle: \"Как устроить хайлоад на ровном месте\"\nauthor: \"Олег Бартунов, Федор Сигаев, Postgres Professional\"\ntags: [\"H"
},
{
"path": "content/highload/18/2.4-dababase-pro.md",
"chars": 3625,
"preview": "---\ntitle: \"Как стать классным спецом по базам данных\"\nauthor: \"Илья Космодемьянский, Data Egret\"\ntags: [\"Highload\", \"20"
},
{
"path": "content/highload/18/2.5-make-your-database-dream-of-electric-sheep.md",
"chars": 5880,
"preview": "---\ntitle: \"Make Your Database Dream of Electric Sheep: Designing for Autonomous Operation\"\nauthor: \"Andy Pavlo (Carnegi"
},
{
"path": "content/highload/19/njs-nginx.md",
"chars": 7027,
"preview": "---\ntitle: \"njs ‒ родной JavaSсript-скриптинг в nginx\"\nauthor: \"Дмитрий Волынцев, Nginx, Inc.\"\ntags: [\"Highload\", \"2019\""
},
{
"path": "content/highload/19/siberia/docs.md",
"chars": 7592,
"preview": "---\ntitle: \"Как сделать так, чтобы документация не болела\"\nauthor: \"Семён Факторович, Николай Волынкин\"\ntags: [\"HighLoad"
},
{
"path": "content/highload/19/tcp-vs-udp.md",
"chars": 8396,
"preview": "---\ntitle: \"UDP против TCP, или Будущее сетевого стека\"\nauthor: \"Александр Тоболь, Одноклассники\"\ntags: [\"Highload\", \"20"
},
{
"path": "content/knowledgeconf/19/badoo-new-developers-onboarding.md",
"chars": 4811,
"preview": "---\ntitle: \"Добро пожаловать на борт: вводим в строй новых разработчиков\"\nauthor: \"Глеб Дейкало, Badoo\"\ntags: [\"Knowledg"
},
{
"path": "content/knowledgeconf/19/biocad-knowledge-base-development.md",
"chars": 1548,
"preview": "---\ntitle: \"Разработка базы знаний компании, которой действительно пользуются\"\nauthor: \"Екатерина Гудкова, Биокад\"\ntags:"
},
{
"path": "content/knowledgeconf/19/e-learning.md",
"chars": 1547,
"preview": "---\ntitle: \"Естественное развитие: как перейти от e-learning к управлению знаниями\"\nauthor: \"Елена Тихомирова, eLearning"
},
{
"path": "content/knowledgeconf/19/holistic-km.md",
"chars": 2412,
"preview": "---\ntitle: \"Холистическое управление знаниями в IТ-компании\"\nauthor: \"Алексей Сидорин, КРОК\"\ntags: [\"Knowledgeconf\", \"20"
},
{
"path": "content/knowledgeconf/19/km-efficiency.md",
"chars": 1700,
"preview": "---\ntitle: \"Проектирование показателей эффективности отдела по управлению знаниями\"\nauthor: \"Ольга Искандирова, Открытый"
},
{
"path": "content/knowledgeconf/19/km-system-and-business.md",
"chars": 1096,
"preview": "---\ntitle: \"Как внедрить систему управления знаниями в бизнес\"\nauthor: \"Владимир Лещенко, Роскосмос\"\ntags: [\"Knowledgeco"
},
{
"path": "content/knowledgeconf/19/knowledge-manger-6-10.md",
"chars": 1802,
"preview": "---\ntitle: \"10 компетенций и 6 ролей Knowledge Manager\"\nauthor: \"Мария Мариничева\"\ntags: [\"Knowledgeconf\", \"2019\"]\nsumma"
},
{
"path": "content/knowledgeconf/19/knowledge-sharing-involvement.md",
"chars": 1571,
"preview": "---\ntitle: \"Как вовлечь всех сотрудников ИТ-компании в обучение новичков и друг друга\"\nauthor: \"Анна Тарасенко, 7bits\"\nt"
},
{
"path": "content/knowledgeconf/19/manager-analyst-km.md",
"chars": 1706,
"preview": "---\ntitle: \"Как из менеджера сделать аналитика: опыт подготовки инженеров по знаниям\"\nauthor: \"Татьяна Альбертовна Гаври"
},
{
"path": "content/knowledgeconf/19/multimedia-documentation.md",
"chars": 2494,
"preview": "---\ntitle: \"How to Create Compelling Multimedia Documentation\"\nauthor: \"Alexandra White, Google\"\ntags: [\"Knowledgeconf\","
},
{
"path": "content/knowledgeconf/19/ozon-fast-growth-and-knowledge-sharing.md",
"chars": 2054,
"preview": "---\ntitle: \"Управление знаниями при быстром росте компании\"\nauthor: \"Мария Смирнова, Ozon\"\ntags: [\"Knowledgeconf\", \"2019"
},
{
"path": "content/knowledgeconf/19/tiago-forte-practices.md",
"chars": 2584,
"preview": "---\ntitle: \"Применение практик Тиаго Форте для управления своими знаниями\"\nauthor: \"Андрей Александров, Express42\"\ntags:"
},
{
"path": "content/knowledgeconf/19/trello-kb.md",
"chars": 3239,
"preview": "---\ntitle: \"Trello — эффективная система управления знаниями для небольшой IT-команды\"\nauthor: \"Роман Хорин, Atman Digit"
},
{
"path": "content/knowledgeconf/19/voluntary-forced-knowledge-sharing.md",
"chars": 3528,
"preview": "---\ntitle: \"Не хочешь мокнуть – плыви: добровольно-принудительный обмен знаниями\"\nauthor: \"Мария Палагина, Тинькофф Банк"
},
{
"path": "content/knowledgeconf/19/xi-notes-for-developer.md",
"chars": 2562,
"preview": "---\ntitle: \"Как я 15 лет делал себе персональную Wiki для программиста\"\nauthor: \"Григорий Петров\"\ntags: [\"Knowledgeconf\""
},
{
"path": "content/moscowpython/19/accelerate-python.md",
"chars": 7013,
"preview": "---\ntitle: \"Что делать, если ваш код на Python тормозит\"\nauthor: \"Григорий Бакунов, Яндекс\"\ntags: [\"Moscow Python Conf\","
},
{
"path": "content/moscowpython/19/go-vs-python.md",
"chars": 8857,
"preview": "---\ntitle: \"Go против Python\"\nauthor: \"Виталий Левченко, организатор Go-митапов в Санкт-Петербурге\"\ntags: [\"Moscow Pytho"
},
{
"path": "content/moscowpython/19/kill-mutants.md",
"chars": 10597,
"preview": "---\ntitle: \"Убивай мутантов, спаси свой код\"\nauthor: \"Никита Соболев, wemake.services\"\ntags: [\"Moscow Python Conf\", \"201"
},
{
"path": "content/moscowpython/19/yandex-python.md",
"chars": 7795,
"preview": "---\ntitle: \"Как развивался Python в Яндексе\"\nauthor: \"Александр Кóшелев, Яндекс\"\ntags: [\"Moscow Python Conf\", \"2019\", \"Я"
},
{
"path": "content/qualityconf/19/blameless.md",
"chars": 4836,
"preview": "---\ntitle: \"Blameless environment: никто не должен писать качественный код\"\nauthor: \"Никита Соболев, wemake.services\"\nta"
},
{
"path": "content/qualityconf/19/libfuzzer.md",
"chars": 2097,
"preview": "---\ntitle: \"Фаззинг или тестирование мусорными данными\"\nauthor: \"Максим Бакиров, 2ГИС\"\ntags: [\"QualityConf\", \"2019\"]\nsum"
},
{
"path": "content/siberian-community-orgs/documenting-meetings.md",
"chars": 7070,
"preview": "---\ntitle: \"Документирование встреч\"\nauthor: \"Siberian Community Orgs\"\ntags: [\"siberian-community-orgs\", \"2020\"]\n\nsummar"
},
{
"path": "content/teamleadconf/20/documentation_challenges.md",
"chars": 3894,
"preview": "---\ntitle: \"Как сделать так, чтобы документация не болела?\"\nauthor: \"Семён Факторович, Константин Валеев\"\ntags: [\"TeamLe"
},
{
"path": "content/teamleadconf/21/how_to_create_selforganizing_team.md",
"chars": 4540,
"preview": "---\ntitle: \"Пошаговый алгоритм создания самоорганизующейся команды\"\nauthor: \"Андрей Булов\"\ntags: [\"TeamLeadConf\", \"2021\""
},
{
"path": "content/teamleadconf/21/learn_the_hard_way.md",
"chars": 4916,
"preview": "---\ntitle: \"Как команде учиться на своих ошибках?\"\nauthor: \"Денис Сильверс\"\ntags: [\"TeamLeadConf\", \"2021\"]\nsummary: |\n "
},
{
"path": "content/teamleadconf/21/process-smell.md",
"chars": 4238,
"preview": "---\ntitle: \"Ваши процессы попахивают. Что с этим делать\"\nauthor: \"Филипп Дельгядо\"\ntags: [\"TeamLeadConf\", \"2021\"]\nsummar"
},
{
"path": "content/teamleadconf/21/right_of_fail.md",
"chars": 3602,
"preview": "---\ntitle: \"Контринтуитивная роль тимлида: дать право на ошибку и возможность быть человеком\"\nauthor: \"Сандра Урядова\"\nt"
},
{
"path": "content/whalerider/19/investor.md",
"chars": 5941,
"preview": "---\ntitle: \"Как посмотреть на свой продукт глазами инвестора?\"\nauthor: \"Аркадий Морейнис, Антистартап\"\ntags: [\"WhaleRide"
},
{
"path": "layouts/index.html",
"chars": 520,
"preview": "{{ define \"main\" }}\n\n<main>\n\t{{ partial \"index/introduction.html\" . }}\n\n\t<div class=\"catalogue\">\n\t\t{{ range (.Paginate ."
},
{
"path": "layouts/table.html",
"chars": 37,
"preview": "<table>\r\n {{ .Inner }}\r\n</table>\r\n"
},
{
"path": "readme.md",
"chars": 608,
"preview": "\n\n# Конспек"
},
{
"path": "static/.nojekyll",
"chars": 0,
"preview": ""
},
{
"path": "static/custom.css",
"chars": 712,
"preview": "p{\r\n font-family: \"Times New Roman\";\r\n}\r\n.catalogue-tags {\r\n background-color: #e2e2e2;\r\n padding-left: 0.8rem;"
}
]
About this extraction
This page contains the full source code of the NickVolynkin/highload-2018 GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 65 files (237.1 KB), approximately 69.5k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.