На работе поручили написать некий сервис, который будет общаться по api с другим, более крупным сервисом и делать какую-то работу.
стек php8.2 + laravel10 + mysql + redis
Сказано что разрабатываю MVP, но есть определенные требования.
а именно спроектировать так, чтобы система держала обработку 1.000 пользователей.
Вообще суть сервиса такая: клиент заполняет какие-то данные, далее сервис раз в 3 минуты ползает куда-то, что-то проверяет, перезаписывает и сохранят историю, где, что и как он поменял. все.
Так вот, я начал считать, и выяснил, что для 1000 пользователей мне понадобится обрабатывать 445 задач за 1 секунду.
Математика такая: 1000 пользователей у каждого по 80 заданий, каждое из который нужно раз в 3 минуты обрабатывать (1000 * 80) / (3 * 60) = 444.444, округляем и получаем 445 бизнес транзакций.
а каждая из такой транзакции включает ряд действий: сходи в текущую базу, данные забери оттуда, потом постучись в это апи, потом в другое, все обработай, отправь еще один удаленный запрос, сохрани себе результаты.
В поем понимании это хайлоад, не сталкивался с таким, прошу помощи, подскажите как мне встроить такой процесс, какие технологии и для чего использовать. Какие проблемы ожидать.
Я пока не приложу ума как писать в mysql 445+ данных в секунду..
Сейчас я на локалке запрограммировал бизнес-логику, поднял в докере редис, настроил очередь на работу с редисом (ларавел из коробки), поднял супервизор. Какие-то копеечные данных, которые "пушу" в очередь руками обрабатываются корректно, быстро, но это совсем не 445 в секунду, у меня оперативки столько нет на компе,..
Не могу понять что будет в боевом режиме и как это мониторить, прогнозировать?
Разделил базы на 2, первая для бизнес-моделей (для юзеров, их настроек) вторая для истории, как раз во вторую в максимальной нагрузке ожидается 445 записей в секунду.
В общем, дайте пожалуйста совет, может статьи, ютуб, технологии, как встраивать такую систему на приведенном выше стеке?
вопрос нужны результаты сразу же. если нет - кладете в очередь и обрабатываете постепенно. при таком варианте вы можете принимать от пользователя можно хоть миллион задач на обработку.
если вариант человек дает задачу и сразу должен получить ответ - тут сложнее. сильное подозрение что сторонний апи вас пошлет нахрен быстрее чем вы упретесь в базу.
Дмитрий, на счет «апи большого брата»то кстати да, но в теории «на словах» все должно работать и пока не думаем, что сторонний сервис как-то откажет.
Когда нужны данные:
Да нет, я бы не сказал что сразу, 90 процентов действий это задачи из очереди, выполняются в фоне, клиент заходит и видит только лишь графики, те результаты по факту, ну иногда уведомления получает, когда данные с этих графиков уже какие-то странные, но это детали бизнес-логики.
Нет, данные сразу не нужны, я пока н понимаю может ли MySQL писать 445 записей в секунду, по ним строить индекс и еще изредка отдавать ответы на select..
Александр Панков, ну и в чем проблемы тогда? Получили запрос от пользователя - создали Job отправили в очередь. Какой нибудь rabbitmq эти задачи будет жрать как не в себя. Другое дело что разбираться эти задачи будут со скоростью которую позволят ресурсы. Но ваш сервис всегда будет принимать задачи от пользователя
может ли MySQL писать 445 записей в секунду,
Вы же понимаете что это дурацкий вопрос, и дурацкая постановка? У вас в 1 записи может быть одна колонка со статусом true/false, а может быть 100 колонок с текстом, каждая из которых содержит Войну и Мир Льва Толстого.
Смотрят на обьемы записи/чтения на диск а не на количество попыток этих записей
Александр Панков, и вам кажется что стало понятнее?
У диска есть скорость на чтение/запись - в идеальной ситуации именно с такой скорость он может писать ваши кортежи на диск - скорость записи диска разделить на размер одного кортежа. Идеала вы конечно не получите никогда - особенно если у вас с этим же диском возится nginx, php и вагон всего. Но прикинуть можно.
Но дать точный ответ на ваш вопрос вам дать никто не сможет. Потому что вы играете в анекдот про сферического коня в вакууме. При наличии мозгов и хорошего знания инструментов которые вы собираетесь использовать - MySQL, Laravel, PHP, нормальной скорости api - можно писать в миллион раз больше записей, но как бы при всем уважении никто не может быть увереным в хорошем знании инструментов. Не говоря о том что что вы вообще делать будете на этом сервере - может там какие нибудь шизанутые расчеты, которые сожрут всю память, весь диск на своп, и мускул там будет курить в сторонке.
Просто опыта мало, нагуглил сегодня что MySQL может вставлять 40.000 записей в секунду, простым инсертом (массовым конечно)
И даже может вставить 247.000 в секунду если через батч файл
Эти цифры даже близко не мои 445 строк в секунду, поэтому проблема меньше, чем мне показалось.
Скорее всего телодвижений потребуется минимум.
Просто буду как-нибудь писать данные в tsv файлы и например раз в минуту персистить эти данные в базу, реалтайм не обязателен.
А я уже нагородил себе какие-то сервисы на go, какой то master-slave и тд и тп
Тут главное минимизировать количество подключений, потому что 445 +1 подключений для MySQL вроде бы многовато, по дефолту 100 стоит
Так разрабатывайте. Смысл MVP не столько в том, чтобы показать, что что-то работает. а в том, чтобы посмотреть самому разработчику, как оно может работать и где именно на практике появляются узкие места. То, что у вас для проекта, требующего MVP, на старте нет понимания, во что вы упираетесь - это совершенно естественно ;)
А грубая математика про 445 - это ни о чем. В идеальном варианте обработка 445 задач - это один запрос 445 записей из БД, одно обращение к внешнему API со списком из 445 идентификаторов и один цикл обработки результатов на 445 итераций.
Очевидно обработку делать в фоне, используем очереди (queue), можно в том же redis.
Дальше простая математика, например:
Если одна задача из очереди обрабатывается в среднем за 0.5 секунд то вам понадобится минимум 222 обработчика очереди чтобы успевать обрабатывать 445 задач в секунду
Каждый обработчик требует ресурсы сервера (CPU, RAM) и исходя из этого уже можно обозначить требования к машине где это будет крутиться
Желательно БД сервер и redis сервер запускать на отдельных машинах чтобы нагрузка от них не мешала работе приложения.
Более точные замеры можно провести сделав нагрузочное тестирование.
То есть эмулируем 445 запросов в секунду чтобы получить поток записей и дальше мониторим нагрузку, на базу, на диск, на процессор.