Я хотел бы воспользоваться вашим опытом, чтобы узнать, как масштабировать наше аппаратное обеспечение.
Вот наши ключевые данные:
2,2 миллиона постов, текущий рост — около 80 тысяч в месяц.
35 тысяч пользователей, текущий рост — около 1,5 тысячи в месяц.
Сейчас мы работаем на виртуальной машине Hetzner с 8 выделенными ядрами и 32 ГБ ОЗУ. В декабре мы начали сталкиваться с ограничениями: сначала количество соединений рабочих процессов Nginx достигло предела, поэтому мы увеличили его с 768 (значение по умолчанию) до 1536. Вчера мы снова уперлись в этот предел и подняли значение до 3072. После этих изменений система снова работает стабильно, но мы приближаемся к 100% использованию сервера.
Параметр db_work_mem установлен на 80 МБ, db_shared_buffers — на 8192 МБ. Мы совсем не используем доступную память, но я не уверен, есть ли смысл задействовать её больше и получить от этого выгоду. Что вы думаете?
#~> free -m
total used free shared buff/cache available
Mem: 31360 6105 1241 8423 24013 16412
Следующий простой вариант масштабирования в Hetzner — это 16 ядер и 64 ГБ ОЗУ, что для нас приемлемо по стоимости, но я сомневаюсь, имеет ли смысл продолжать вертикальное масштабирование. Я подумываю, не будет ли гораздо разумнее разделить приложение и базу данных на разные сервера, или это создаст слишком много сложностей.
Кто-нибудь уже делал так? Поделитесь своим опытом.
Потому что я планирую заранее. Возможно, нам сейчас не нужно масштабироваться, но, учитывая наблюдаемый рост и растущую потребность в ресурсах, которую мы видели в прошлом, я просто заранее обдумываю возможные следующие шаги.
В основном CPU — после сегодняшнего обновления пиковая нагрузка снизилась с ~8–9 до ~6.
12 млн в месяц, по сравнению с 6,5 млн в месяц год назад.
Вернусь к выводу sar позже, сейчас он не был запущен.
Да, я работаю, но пиковые часы ещё не наступили. Они начнутся завтра.
Загрузка процессора определённо снизилась после того, как я вчера увеличил количество соединений воркеров, хотя точно не знаю, насколько.
12:00:01 AM CPU %user %nice %system %iowait %steal %idle
08:45:01 AM all 40.22 2.21 7.44 0.27 0.00 49.86
08:55:01 AM all 42.84 2.89 8.02 0.16 0.00 46.09
09:05:01 AM all 38.81 0.86 7.68 0.12 0.00 52.53
09:15:01 AM all 38.80 0.70 7.66 0.10 0.00 52.73
09:25:01 AM all 38.71 2.14 7.88 0.12 0.00 51.16
09:35:01 AM all 38.74 0.84 7.86 0.09 0.00 52.47
09:45:01 AM all 40.31 1.07 7.95 0.10 0.00 50.57
09:55:01 AM all 40.03 1.37 7.90 0.08 0.00 50.62
10:05:01 AM all 39.00 1.29 7.90 0.09 0.00 51.72
10:15:01 AM all 40.26 2.68 8.07 0.09 0.00 48.91
10:25:01 AM all 41.59 0.93 8.31 0.08 0.00 49.09
10:35:01 AM all 40.39 1.55 8.25 0.07 0.00 49.73
10:45:01 AM all 45.44 2.37 9.08 0.08 0.00 43.03
10:55:01 AM all 50.56 2.20 9.23 0.06 0.00 37.95
11:05:01 AM all 41.82 1.54 8.55 0.08 0.00 48.02
11:15:01 AM all 38.74 1.54 8.11 0.10 0.00 51.50
11:25:01 AM all 45.41 1.59 9.27 0.19 0.00 43.55
11:35:01 AM all 38.45 1.78 8.20 0.11 0.00 51.45
11:45:01 AM all 41.03 1.60 8.48 0.14 0.00 48.75
11:55:01 AM all 40.65 1.17 8.36 0.15 0.00 49.67
12:05:01 PM all 40.03 1.29 8.40 0.13 0.00 50.15
12:15:01 PM all 40.47 1.10 8.19 0.11 0.00 50.13
Я подозревал, что Postgres не получал достаточно памяти, что приводило к высокому значению %iowait.
Но поскольку приведенный выше вывод sar не указывает на перегрузку системы, нам придется подождать новых статистических данных.
Я пытаюсь помочь кому-то с проблемами производительности. Мы увеличили размер буфера PostgreSQL. Думаю, это немного помогло, но MiniProfiler всё ещё показывает более 300 мс. Использование ЦП составляет около 30% для 16 ядер.
Похоже, это не изменится. Я наблюдал за этим в течение двух вечеров, и использование процессора не превысило предыдущих значений. Ваше предположение относительно Postgres, возможно, верно.
Что касается мини-профилировщика: на какие показатели нам стоит ориентироваться? Сейчас у нас около 300 мс. Ранее было около 500 мс.
Я считаю, что если мы достигнем ниже 50 мс во всех случаях, независимо от часов пиковой нагрузки, это будет называться быстрым временем отклика сервера. Остальная часть сайта станет быстрее, так как всё зависит от первоначального времени отклика сервера.
Идеально было бы, если бы время отклика оставалось ниже 50 мс для пользователей из всех географических регионов и было стабильным. На данный момент оно постоянно скачет и чаще всего выше, что, по-видимому, является основной причиной медленной работы.
Краткий обзор последних дней: всё шло гладко, за исключением примерно получаса сегодня днем. Сам я в то время на сервере не был, но в логах nginx были зафиксированы таймауты от бэкенда. Утилита sar показывает немного повышенную системную загрузку, но общей высокой нагрузки на CPU не наблюдается. Не совсем понятно, что именно произошло, но это явно мешало корректной работе Unicorn, Redis и PostgreSQL.
03:55:01 PM all 34.99 1.87 6.67 0.12 0.00 56.35
04:05:01 PM all 33.99 0.35 6.52 0.31 0.00 58.82
04:15:01 PM all 35.24 1.17 7.14 0.13 0.00 56.31
04:25:02 PM all 36.45 0.63 7.15 0.13 0.00 55.65
> 04:35:01 PM all 39.09 0.71 16.78 0.11 0.00 43.32
> 04:45:01 PM all 35.53 0.95 20.16 0.08 0.00 43.27
> 04:55:01 PM all 41.64 4.29 15.44 0.24 0.00 38.39
05:05:01 PM all 36.75 2.47 7.78 0.13 0.00 52.87
05:15:01 PM all 35.96 1.29 7.81 0.10 0.00 54.85
05:25:01 PM all 38.69 1.35 8.00 0.09 0.00 51.87
05:35:01 PM all 37.01 4.53 7.92 0.07 0.00 50.46
Это строки, помеченные символом >.
В это время я не наблюдаю никакого всплеска трафика, поэтому пока не могу понять, что именно произошло, но проблема проявлялась только в течение этого получаса.
В целом, если смотреть на время процессора, Redis вышел на первое место и в целом потребляет значительную часть CPU. Не уверен, можно ли что-то с этим сделать. Обычно его загрузка составляет около 20–25%, иногда достигая пиков в 35%.
1721566 uuidd 20 0 2035M 1458M 1952 S 16.1 4.6 16h22:37 /usr/bin/redis-server *:6379
1721578 www-data 20 0 108M 69100 12516 S 6.7 0.2 6h32:27 nginx: worker process
2853756 1000 20 0 1355M 444M 19356 R 63.7 1.4 2h38:10 unicorn worker[0] -E production -c config/unicorn.conf.rb
2854380 1000 20 0 1267M 409M 18768 S 41.6 1.3 2h19:45 unicorn worker[4] -E production -c config/unicorn.conf.rb
1721598 1000 20 0 592M 285M 5192 S 1.3 0.9 2h08:53 unicorn master -E production -c config/unicorn.conf.rb
575 root 20 0 1747M 20468 5040 S 0.7 0.1 2h01:02 /usr/bin/containerd
2854731 1000 20 0 1280M 399M 17880 S 36.9 1.3 1h57:52 unicorn worker[7] -E production -c config/unicorn.conf.rb
1721841 1000 20 0 592M 285M 5192 S 0.7 0.9 1h49:49 unicorn master -E production -c config/unicorn.conf.rb
2855284 1000 20 0 1287M 425M 18396 S 18.8 1.4 1h35:02 unicorn worker[3] -E production -c config/unicorn.conf.rb
2856414 1000 20 0 1223M 391M 19268 S 13.4 1.2 1h14:50 unicorn worker[2] -E production -c config/unicorn.conf.rb
2856478 1000 20 0 1207M 401M 21120 S 5.4 1.3 58:42.50 unicorn worker[5] -E production -c config/unicorn.conf.rb
2856503 1000 20 0 1215M 389M 18980 S 4.7 1.2 47:22.95 unicorn worker[1] -E production -c config/unicorn.conf.rb
1721581 www-data 20 0 69888 28636 13368 S 0.0 0.1 44:49.50 nginx: worker process
2857467 1000 20 0 1199M 385M 18112 S 4.0 1.2 39:23.87 unicorn worker[6] -E production -c config/unicorn.conf.rb
1721594 _apt 20 0 8479M 20036 18128 S 1.3 0.1 32:55.29 postgres: 13/main: walwriter
580 root 20 0 1747M 20468 5040 S 0.0 0.1 32:15.27 /usr/bin/containerd
Общая нагрузка в долгосрочной перспективе в среднем составляет 5, но я всё ещё наблюдаю периодические всплески до 8 или 9.
Что касается мини-профилировщика. Я говорил об общем времени загрузки. Время ответа сервера (первоначальный запрос) у нас обычно составляет менее 10 мс. Иногда немного больше, но в моих последних проверках я не видел значений выше 20 мс. Общее время загрузки иногда достигает 800 мс, очень редко — выше 1000 мс.
Рассматриваем только один географический регион, так как у нас нет значительного числа пользователей за его пределами.