Облако в Badoo год спустя - работа над ошибками, Юрий...
-
Upload
badoo-development -
Category
Internet
-
view
15.654 -
download
3
Transcript of Облако в Badoo год спустя - работа над ошибками, Юрий...
![Page 1: Облако в Badoo год спустя - работа над ошибками, Юрий Насретдинов (Badoo)](https://reader031.fdocuments.net/reader031/viewer/2022020106/55a77b4b1a28ab5f4e8b4722/html5/thumbnails/1.jpg)
«Облако» в Badoo год спустя
Юрий Насретдинов
![Page 2: Облако в Badoo год спустя - работа над ошибками, Юрий Насретдинов (Badoo)](https://reader031.fdocuments.net/reader031/viewer/2022020106/55a77b4b1a28ab5f4e8b4722/html5/thumbnails/2.jpg)
О компании
225M пользователей
160K регистраций в сутки
2K серверов40K RPS на PHP-FPM
4M загрузок фото в день
50 языков интерфейса
![Page 3: Облако в Badoo год спустя - работа над ошибками, Юрий Насретдинов (Badoo)](https://reader031.fdocuments.net/reader031/viewer/2022020106/55a77b4b1a28ab5f4e8b4722/html5/thumbnails/3.jpg)
О чём доклад• Общая архитектура: история создания, распределение нагрузки, отказоустойчивость.
• Логи скриптов: сбор, индексация, различные виды просмотра.
• Влияние Google App Engine — «облачный» разборщик очередей.
• Планы на будущее
• Как мы бы реализовали «облако» сейчас
![Page 4: Облако в Badoo год спустя - работа над ошибками, Юрий Насретдинов (Badoo)](https://reader031.fdocuments.net/reader031/viewer/2022020106/55a77b4b1a28ab5f4e8b4722/html5/thumbnails/4.jpg)
Стек технологий• OS — SLES (SUSE Linux Enterprise Server)
• ЯП — PHP 5.5, C/C++, Go, Java
• Базы данных — MySQL, Tarantool, SQLite
• Кеширование — Memcached
• Веб-сервер — Nginx
![Page 5: Облако в Badoo год спустя - работа над ошибками, Юрий Насретдинов (Badoo)](https://reader031.fdocuments.net/reader031/viewer/2022020106/55a77b4b1a28ab5f4e8b4722/html5/thumbnails/5.jpg)
Общая архитектура
• «Старая система»: mcron — утилита для раскладки crontab по машинам
• Общая архитектура новой системы («облака»)
• Распределение нагрузки по машинам, «попугаи»
• Способы обеспечения отказоустойчивости
![Page 6: Облако в Badoo год спустя - работа над ошибками, Юрий Насретдинов (Badoo)](https://reader031.fdocuments.net/reader031/viewer/2022020106/55a77b4b1a28ab5f4e8b4722/html5/thumbnails/6.jpg)
mcron
sendSMS.phpanonChat.php #1moderation.php
config
scripts1 scripts2
facebook.phpanonChat.php #2
errorlogs.php
translate.phpanonChat.php #9
cleanup.php
scripts50
…
![Page 7: Облако в Badoo год спустя - работа над ошибками, Юрий Насретдинов (Badoo)](https://reader031.fdocuments.net/reader031/viewer/2022020106/55a77b4b1a28ab5f4e8b4722/html5/thumbnails/7.jpg)
mcron
sendSMS.phpanonChat.php #1moderation.php
config
scripts1 scripts2
facebook.phpanonChat.php #2
errorlogs.php
translate.phpanonChat.php #9
cleanup.php
scripts50
…
![Page 8: Облако в Badoo год спустя - работа над ошибками, Юрий Насретдинов (Badoo)](https://reader031.fdocuments.net/reader031/viewer/2022020106/55a77b4b1a28ab5f4e8b4722/html5/thumbnails/8.jpg)
mcron
sendSMS.phpfacebook.php
anonChat.php #1moderation.php
config
scripts1 scripts3
google.phpanonChat.php #2anonChat.php #3
migration.php
translate.phperrorlogs.php
anonChat.php #9cleanup.php
scripts50
…
![Page 9: Облако в Badoo год спустя - работа над ошибками, Юрий Насретдинов (Badoo)](https://reader031.fdocuments.net/reader031/viewer/2022020106/55a77b4b1a28ab5f4e8b4722/html5/thumbnails/9.jpg)
Недостатки старой системы
• Ручное распределение нагрузки по серверам
• Ручной перенос скриптов с «упавших» машин — очень большой downtime
• Наличие «особенных» машин, на которых установлен дополнительный софт
![Page 10: Облако в Badoo год спустя - работа над ошибками, Юрий Насретдинов (Badoo)](https://reader031.fdocuments.net/reader031/viewer/2022020106/55a77b4b1a28ab5f4e8b4722/html5/thumbnails/10.jpg)
«Облако»• Запуск заданий по расписанию / через API
• Автоматическая балансировка нагрузки
• Отсутствие «особенных» машин (на всех машинах стоит весь необходимый софт)
• Отказоустойчивость к «падению» машин — автоматический перезапуск после таймаута
![Page 11: Облако в Badoo год спустя - работа над ошибками, Юрий Насретдинов (Badoo)](https://reader031.fdocuments.net/reader031/viewer/2022020106/55a77b4b1a28ab5f4e8b4722/html5/thumbnails/11.jpg)
«Облако» (для разработчика)
![Page 12: Облако в Badoo год спустя - работа над ошибками, Юрий Насретдинов (Badoo)](https://reader031.fdocuments.net/reader031/viewer/2022020106/55a77b4b1a28ab5f4e8b4722/html5/thumbnails/12.jpg)
![Page 13: Облако в Badoo год спустя - работа над ошибками, Юрий Насретдинов (Badoo)](https://reader031.fdocuments.net/reader031/viewer/2022020106/55a77b4b1a28ab5f4e8b4722/html5/thumbnails/13.jpg)
«Облако» (для разработчика)
script
job #1
job #2 job #3
job #4job #5
![Page 14: Облако в Badoo год спустя - работа над ошибками, Юрий Насретдинов (Badoo)](https://reader031.fdocuments.net/reader031/viewer/2022020106/55a77b4b1a28ab5f4e8b4722/html5/thumbnails/14.jpg)
Архитектура
MySQL
MySQL
cloudsys1
cloudsys2
cloud1
cloudN
• • •
replication
heartbeat
mysql
Легенда:
master
phproxyd
![Page 15: Облако в Badoo год спустя - работа над ошибками, Юрий Насретдинов (Badoo)](https://reader031.fdocuments.net/reader031/viewer/2022020106/55a77b4b1a28ab5f4e8b4722/html5/thumbnails/15.jpg)
«Облако»• Около 1 000 машин*
• 15K SQL RPS (50/50 read/write)
• 1 000 запусков скриптов в секунду
• «Запускалка» на PHP, 16 процессов
• Планировщик на go
* Цифры приведены для 1 ДЦ, у нас их 2
![Page 16: Облако в Badoo год спустя - работа над ошибками, Юрий Насретдинов (Badoo)](https://reader031.fdocuments.net/reader031/viewer/2022020106/55a77b4b1a28ab5f4e8b4722/html5/thumbnails/16.jpg)
Планировщик
PHP
Go
![Page 17: Облако в Badoo год спустя - работа над ошибками, Юрий Насретдинов (Badoo)](https://reader031.fdocuments.net/reader031/viewer/2022020106/55a77b4b1a28ab5f4e8b4722/html5/thumbnails/17.jpg)
Балансировка нагрузки
1000300
600250
2000230
1000200
2000180
weighted round-robin
![Page 18: Облако в Badoo год спустя - работа над ошибками, Юрий Насретдинов (Badoo)](https://reader031.fdocuments.net/reader031/viewer/2022020106/55a77b4b1a28ab5f4e8b4722/html5/thumbnails/18.jpg)
Балансировка нагрузки
![Page 19: Облако в Badoo год спустя - работа над ошибками, Юрий Насретдинов (Badoo)](https://reader031.fdocuments.net/reader031/viewer/2022020106/55a77b4b1a28ab5f4e8b4722/html5/thumbnails/19.jpg)
Отказоустойчивость• MySQL — ручное (!) переключение на slave в случае аварии
• Управляющая логика работает «циклами» — перед началом цикла берется лок в базе, по окончании цикла лок отпускается
• Если машина «упала» в середине цикла, то через wait_timeout на сервере соединение будет разорвано и, соответственно, отпущен лок, давая возможность работать логике другой машине
![Page 20: Облако в Badoo год спустя - работа над ошибками, Юрий Насретдинов (Badoo)](https://reader031.fdocuments.net/reader031/viewer/2022020106/55a77b4b1a28ab5f4e8b4722/html5/thumbnails/20.jpg)
Отказоустойчивость• По умолчанию wait_timeout составляет 8 часов…
• Мы выставили wait_timeout = 60 сек
• Cпецифичная для Percona настройка innodb_kill_idle_transaction = 60 сек
• Таким образом, при любых проблемах с сетью или с машинами, максимальный простой управляющей логики составляет 1 минуту
![Page 21: Облако в Badoo год спустя - работа над ошибками, Юрий Насретдинов (Badoo)](https://reader031.fdocuments.net/reader031/viewer/2022020106/55a77b4b1a28ab5f4e8b4722/html5/thumbnails/21.jpg)
Отказоустойчивость• «Задания» запускаются с лимитом на максимальное время их работы, который задает пользователь
• При наступлении лимита скриптами присылается SIGTERM
• Если машина не отвечает — скрипт сам «погибает» от SIGALRM, поскольку при запуске скрипта мы вызываем alarm(макс.время работы + 3 секунды)
• Часы на всех машинах идут с точностью до 1 секунды
![Page 22: Облако в Badoo год спустя - работа над ошибками, Юрий Насретдинов (Badoo)](https://reader031.fdocuments.net/reader031/viewer/2022020106/55a77b4b1a28ab5f4e8b4722/html5/thumbnails/22.jpg)
Сбор логов• Каждое задание получает уникальный id
• Задание — запуск скрипта, с перенаправлением вывода в файлы «logs/phproxyd.<id>.(out|err).log»
• С помощью inotify слушаем изменения в директории с логами и отправляем новые строки в scribe
• С задержкой доставки scribe (несколько секунд) логи скапливаются на отдельной logs-машине
![Page 23: Облако в Badoo год спустя - работа над ошибками, Юрий Насретдинов (Badoo)](https://reader031.fdocuments.net/reader031/viewer/2022020106/55a77b4b1a28ab5f4e8b4722/html5/thumbnails/23.jpg)
Просмотр логов• Логи для каждого скрипта складываются в отдельный файл
• Файлы «ротируются» (с использованием logrotate) раз в неделю
• Каждая строчка в логе содержит id запуска и hostname, где скрипт запускался
• Логи «индексируются» в MyISAM-таблички для быстрого просмотра истории по конкретному id
![Page 24: Облако в Badoo год спустя - работа над ошибками, Юрий Насретдинов (Badoo)](https://reader031.fdocuments.net/reader031/viewer/2022020106/55a77b4b1a28ab5f4e8b4722/html5/thumbnails/24.jpg)
Разборщик очередей
• У нас все «важные» очереди хранятся в MySQL, для сохранности и транзакционности посылки событий
• В MySQL довольно тяжело «правильно» разбирать очереди во много потоков
![Page 25: Облако в Badoo год спустя - работа над ошибками, Юрий Насретдинов (Badoo)](https://reader031.fdocuments.net/reader031/viewer/2022020106/55a77b4b1a28ab5f4e8b4722/html5/thumbnails/25.jpg)
Разборщик очередей• Существует много стратегий «разбора очереди» в MySQL:
• 1) SELECT … WHERE id % N = M
• 2) UPDATE … SET instance_id = N WHERE instance_id IS NULL
• 3) SELECT … WHERE shard_id = N
![Page 26: Облако в Badoo год спустя - работа над ошибками, Юрий Насретдинов (Badoo)](https://reader031.fdocuments.net/reader031/viewer/2022020106/55a77b4b1a28ab5f4e8b4722/html5/thumbnails/26.jpg)
Разборщик очередей• Почти все стратегии плохо масштабируются при увеличении числа воркеров
• Подход с shard_id масштабируется, но нужно следить за равномерностью распределения + требуется решардинг при смене числа воркеров
• Решили написать обработчик очереди, используя API по добавлению заданий в «облако»
![Page 27: Облако в Badoo год спустя - работа над ошибками, Юрий Насретдинов (Badoo)](https://reader031.fdocuments.net/reader031/viewer/2022020106/55a77b4b1a28ab5f4e8b4722/html5/thumbnails/27.jpg)
Разборщик очередей• Реализация: На каждую очередь создается 2 «скрипта»:
• 1) мастер, который выбирает id новых событий из очереди (однопоточный)
• 2) воркеры, которые обрабатывают пачки заданий (получают набор id заданий, которые нужно обработать)
• Мастер «помнит» все id, которые он уже выдал и выбирает из очереди с помощью SELECT id … NOT IN(…)
![Page 28: Облако в Badoo год спустя - работа над ошибками, Юрий Насретдинов (Badoo)](https://reader031.fdocuments.net/reader031/viewer/2022020106/55a77b4b1a28ab5f4e8b4722/html5/thumbnails/28.jpg)
Разборщик очередей• Мастер группирует события в «пачки» для большей эффективности обработки
• Равномерное распределение по воркерам
• Динамическое число воркеров (on demand)
• Можно сделать такой разборщик без API, через fork(), со всеми воркерами на одной машине
![Page 29: Облако в Badoo год спустя - работа над ошибками, Юрий Насретдинов (Badoo)](https://reader031.fdocuments.net/reader031/viewer/2022020106/55a77b4b1a28ab5f4e8b4722/html5/thumbnails/29.jpg)
Причины «падений»• Суммарный downtime системы составил 3 часа за год эксплуатации, что дает uptime 99,97%:
• 1 час — Duplicate key в MySQL :)
• 1 час — «кривой» merge (неправильно разрешены конфликты) — забыли прогнать тесты
• 30 минут — «сломанный» cron на машинах (баг в одной из версий vixie cron) — не отправлялся heartbeat
![Page 30: Облако в Badoo год спустя - работа над ошибками, Юрий Насретдинов (Badoo)](https://reader031.fdocuments.net/reader031/viewer/2022020106/55a77b4b1a28ab5f4e8b4722/html5/thumbnails/30.jpg)
Проблемы MySQL• Основные проблемы возникают из-за глобальных mutex’ов или однопоточных подсистем:
• Медленный DROP TABLE больших таблиц — перед unlink() берется глобальный metadata lock и «висят» все транзакции
![Page 31: Облако в Badoo год спустя - работа над ошибками, Юрий Насретдинов (Badoo)](https://reader031.fdocuments.net/reader031/viewer/2022020106/55a77b4b1a28ab5f4e8b4722/html5/thumbnails/31.jpg)
Проблемы MySQL• Медленный (однопоточный) purge thread — из-за
MVCC «удаленные» записи могут очень медленно «пуржиться» из таблиц — в InnoDB возможна ситуация, когда SELECT COUNT(*) из «пустой» таблицы идет минуты и возвращает 0
• Однопоточная репликация (до MySQL 5.6) — изменения могут не успевать применяться на реплике
![Page 32: Облако в Badoo год спустя - работа над ошибками, Юрий Насретдинов (Badoo)](https://reader031.fdocuments.net/reader031/viewer/2022020106/55a77b4b1a28ab5f4e8b4722/html5/thumbnails/32.jpg)
Проблемы MySQL
• Высокие накладные расходы на подключение — MySQL плохо «держит» больше N подключений, где N составляет 2-3 тысячи
• В новых версиях MySQL и в MariaDB есть «connection pooling», причём для MySQL эта возможность отсутствует в Community Edition
![Page 33: Облако в Badoo год спустя - работа над ошибками, Юрий Насретдинов (Badoo)](https://reader031.fdocuments.net/reader031/viewer/2022020106/55a77b4b1a28ab5f4e8b4722/html5/thumbnails/33.jpg)
Проблемы ядра Linux• Баг с выводом ps и «[migration/N]», который якобы
«ест 100% CPU» (на самом деле не ест)
• Очень медленный unlink() больших файлов, даже с ext4 (возникает из-за высокой фрагментации)
• «Плохая» реализация inotify — если в директории активно создают файлы и у вас много «свободной» ОЗУ, inotify_add_watch() будет занимать секунды (!) и полностью блокировать запись в эту директорию
![Page 34: Облако в Badoo год спустя - работа над ошибками, Юрий Насретдинов (Badoo)](https://reader031.fdocuments.net/reader031/viewer/2022020106/55a77b4b1a28ab5f4e8b4722/html5/thumbnails/34.jpg)
Планы на будущее• Полностью перевести управляющую логику на Go: иметь по одной goroutine на машину «облака» — одна «затупившая» машина не будет тормозить обработку остальных заданий
• Перевести phproxyd на PHP (уже написан, нужно запустить в production) — экономия на запуске интерпретатора
• Возможно, открыть исходные тексты системы
![Page 35: Облако в Badoo год спустя - работа над ошибками, Юрий Насретдинов (Badoo)](https://reader031.fdocuments.net/reader031/viewer/2022020106/55a77b4b1a28ab5f4e8b4722/html5/thumbnails/35.jpg)
Как бы мы реализовывали сейчас
• Управляющая логика на Go — отличный выбор, если вы почему-то не любите Erlang
• Хранение текущего состояния заданий — Tarantool + Lua процедуры
• Сразу написать новый демон для запуска заданий вместо существующего (на PHP, конечно же)