170 похожих чатов

Можете посоветовать, как лучше всего (эффективнее, оптимальнее по ресурсам, etc.)

решить данный кейс. В данный момент он решён, но меня не покидает ощущение, что сделано это плохо и мозги набекрень уже. Смотришь всякие конференции по питону, high load, у всех rps чуть ли не 200к, а у тебя 20 машин еле-еле выдают 1000 rps 🥴. Такое чувство, что фреймворки работают у всех, но не у меня (утрирую конечно, 100% я делаю что-то плохо, но тем не менее хотелось бы разобраться)
Итак. Представим, что у вас есть .csv файл с двумя колонками uuid и url_array, где uuid — уникальный идентификатор (не повторяется), url_array — список ссылок количеством от 0 до n, n < 100 (верхняя граница в принципе не важна, но условно пусть будет 100; могут повторяться для разных uuid). Строк в .csv ~30 млн. Необходимо для каждой ссылки получить status code, title и response time и связать ссылку с uuid. Я выбрал следущую схему (БД выбрал Postgres): url из url_array будет pk в таблице urls, там же будут колонки status_code, title, response_time, вторая таблица pages будет содержать uuid (который из .csv), третья таблица ассоциативная — первое поле uuid, а второе url.
Задача, вроде бы, самая базовая — аля недоскрапинг, но почему-то с ней возникают проблемы в плане перформанса.
Я выбрал dramatiq (https://dramatiq.io/) (¯\_(ツ)_/¯), ибо с помощью него началось моё знакомство с обработкой фоновых задач. Там из коробки и Rabbitmq, и Redis, и Prometheus, почему бы и да. Даже на стартовой странице фреймворка показан пример count_words, который якобы +- повторяет то что мне надо, но нет (надеюсь). Оформил actor, подключил алхимию и сидел припеваючи ждал завершения работы. Но мы же все любим большой rps, почему бы и не увеличить. Принцип работы был +- такой: проверяем url в базе, если есть, то просто создаём связь uuid-url, если нет, то делаем request и записываем в базу все вышеперечисленные поля. Поднял ещё несколько машинок — ого, скорость х2 стала, ещё машинку — ого, скорость ещё выше, продолжаю поднимать новые тачки до того момента, пока скорость не стала 0 — "Привет, я ООМ в Postgres". База не выдержала новых подключений и решила прилечь. Мы народ не гордый, пошли пытаться искать в чём проблема — вышел на pgboucner и вроде как-то стало лучше (база не падала больше), но rps был непонятным для меня.
Мои мысли по поводу того, почему это работаем медленно.
0. Актёр принимает на вход только один url, а не пачкой
1. Зависит от Rabbitmq
2. Зависит от количество тредов, созданных dramatiq
3. Что-то с базой. От ООМ избавились, добавление в базу происходит за 0.5-0.6 sec, что, вроде бы, ок?
4. ¯\_(ツ)_/¯
Помогите расставить всё точки над i, как всё-таки следует решать такие кейсы.
Всякие uvicorn'ы, tornado и т.п. — это не про вот это всё? Была идея поднять api (fast-api, flask, etc), сделать там asyncio методы для обработки всего вышеперечисленного, но это так и осталось в мыслях, поскольку dramatiq все уши прожжужал

11 ответов

17 просмотров

я не экспертный эксперт, просто для себя интересно интересный кейс. 0.5-0.6 - это что именно? база или вся апи?

Mooner- Автор вопроса
Максим
я не экспертный эксперт, просто для себя интересно...

Это commit одной транзакции, где в транзакции лежит uuid и url

Mooner
Это commit одной транзакции, где в транзакции лежи...

мне кажется не норм. хотя опыта не так много чтоб быть уверенным. а отправлять пачками в базу юзкейс не позволяет?

Mooner- Автор вопроса
Максим
мне кажется не норм. хотя опыта не так много чтоб ...

Скорее нет, чем да. Но это видимо из-за того, как именно я начал решать. Вариантов естественно куча должна быть

Mooner
Скорее нет, чем да. Но это видимо из-за того, как ...

судя по тому что количество воркеров ускоряет работу, балк инсерт ещё круче будет. можешь предварительно потестить в консольке

Mooner- Автор вопроса
Максим
судя по тому что количество воркеров ускоряет рабо...

С bulk-insert прокатит тогда и только тогда, когда один актёр будет обрабатывать несколько url, не так ли? Сейчас спроектировано так, что воркер выполняет задачу для одной пары url-uuid

Mooner
С bulk-insert прокатит тогда и только тогда, когда...

да, верно. но я думаю если после тестов окажется что это будет намного быстрее, можно и переписать код, как по мне

Звучит как будто ты коннекты не закрываешь

Mooner- Автор вопроса
Tishka17
Звучит как будто ты коннекты не закрываешь

Коннекты к чему именно? Алихимия работает через сессии и в конце session.close(), requests через with работает Redis не используется

Mooner
Коннекты к чему именно? Алихимия работает через се...

Коннекты к БД. Если они постепенно кончились, значит они текут. Либо ты сделал слишком много и в БД не хватило памяти, как ты предположил. Ограничь размер пула, чо

Похожие вопросы

Обсуждают сегодня

Господа, а что сейчас вообще с рынком труда на делфи происходит? Какова ситуация?
Rꙮman Yankꙮvsky
29
А вообще, что может смущать в самой Julia - бы сказал, что нет единого стандартного подхода по многим моментам, поэтому многое выглядит как "хаки" и произвол. Короче говоря, с...
Viktor G.
2
30500 за редактор? )
Владимир
47
а через ESC-код ?
Alexey Kulakov
29
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
14
Добрый день! Скажите пожалуйста, а какие программы вы бы рекомендовали написать для того, чтобы научиться управлять памятью? Можно написать динамический массив, можно связный ...
Филипп
7
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
Ребят в СИ можно реализовать ООП?
Николай
33
https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_h_common.erl#L174 https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_olp.erl#L76 15 лет назад...
Maksim Lapshin
20
Карта сайта