Slide 1

Slide 1 text

Иван Осадчий Senior Engineer Москва — 2021 ОТ 50 ДО 5000

Slide 2

Slide 2 text

О чем? ● Реальный кейс ● Нюансы работы pgx и PgBouncer ● Простой, легко применимый вывод

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

Зачем переделывать? ● 98% создаваемость :( ● масштабирование ● тарифное API

Slide 5

Slide 5 text

Тарифное API для служб доставки Как было:

Slide 6

Slide 6 text

Тарифное API для служб доставки Как хотелось:

Slide 7

Slide 7 text

Пропустим: ● как хранить тарифы и пункты выдачи ● какую технологию выбрать

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

Тест “в лоб”

Slide 11

Slide 11 text

Оптимизация: шаги 1. Цели и метрики 2. Тестовые данные 3. Найти узкое место 4. Устранить

Slide 12

Slide 12 text

Цели и метрики RPS:

Slide 13

Slide 13 text

Цели и метрики Задержка, мс:

Slide 14

Slide 14 text

Лента в 20 тысяч запросов

Slide 15

Slide 15 text

Лента 150 тысяч

Slide 16

Slide 16 text

Почему тормозит?

Slide 17

Slide 17 text

LSR-1223: лёг item-storage. Куча 500-х ошибок. Из-за уменьшения кэша пошёл трафик в базу, из-за нагрузки база стала медленнее отвечать, из-за медленных ответов сервис стал килить коннекты к базе. Килл происходит через отдельные соединения, и из-за этого все коннекты в баунсере заполнились и новые перестали проходить. В item-storage обновили pgx на четвёртую версию, где нельзя отключить cancelContext.

Slide 18

Slide 18 text

Отмена запроса

Slide 19

Slide 19 text

Отмена запроса при наличии pgbouncer

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

No content

Slide 22

Slide 22 text

No content

Slide 23

Slide 23 text

Отключили отмены запросов

Slide 24

Slide 24 text

PgBouncer: активные соединения

Slide 25

Slide 25 text

130 RPS

Slide 26

Slide 26 text

БД: нагрузка на диск

Slide 27

Slide 27 text

Отменяем квоту на диск

Slide 28

Slide 28 text

Съели весь диск на сервере Не повторять!

Slide 29

Slide 29 text

Втиснуть данные в память ● данные + индексы = 27 Гб

Slide 30

Slide 30 text

Данные в памяти: 5440 RPS

Slide 31

Slide 31 text

No content

Slide 32

Slide 32 text

Открытый тест: 4000 RPS

Slide 33

Slide 33 text

PgBouncer: sv_active vs cl_waiting ● размер пула в сервисе: 24 ● в базе: 12

Slide 34

Slide 34 text

Исправили конфигурацию БД: 5000 RPS

Slide 35

Slide 35 text

Переключение между соединениями - дорого

Slide 36

Slide 36 text

Почему не влияет на закрытый тест? “Планировщик” PgBouncer: ● нет лимита активное использование соединения ● под нагрузкой активное соединение все время загружено ● шансы получить серверное соединение низкие ○ когда параллельных запросов мало — это ок ○ когда много — некоторые не успевают

Slide 37

Slide 37 text

Нет мультиплексированию соединений

Slide 38

Slide 38 text

Размер пула в сервисе ● <= пула на стороне БД Оговорочки: ● медленные транзакции ● разнесенная по времени нагрузка

Slide 39

Slide 39 text

Чего добились ● запас по производительности ● победили 500ки ● открыли дорогу к API

Slide 40

Slide 40 text

Takeaway ● знать свой процесс (оптимизации или еще чего) ● следить за пулом соединений

Slide 41

Slide 41 text

Спасибо за внимание GitHub, Habr: @iosadchiy