Помогите оптимизировать код (запросы к БД)

Поддержка
  • Всем привет! Имеется блок в скрипте, который в упрощенном виде выглядит так:

    3253252.png

    Суть: скрипт ждет, пока в БД не появится нужное значение. Если появилось - выходим из цикла и продолжаем скрипт, если не появилось за 10 сек - выходим из цикла и продолжаем скрипт.

    Проблема: раньше у меня там стояло [[CYCLE_INDEX]]<10 и сон 1 сек, все работало корректно. Но так как в моем случае реакция 1 сек слишком медленная, было сделано [[CYCLE_INDEX]]<100 и сон 100 мс. Что привело к тому, что этот цикл теперь задерживается не на 10 сек, а на 10-25 сек. У меня 50 потоков, которые почти постоянно висят в этом цикле, и я связываю это с нагрузкой на БД (50 запросов каждые 100 мс).

    Вопрос: как можно оптимизировать данный участок кода? Чтобы и быстро реагировать на появление в БД нужного значения, и выжидать ровно 10 сек? Можно ли сделать в BAS колбэк, чтобы не постоянно опрашивать БД, а наоборот чтобы БД сама сообщала, когда в ней появилось нужное значение?

  • @doupiu

    А что за БД то? Встроенная mongodb?

  • @sergerdn да, стандартная BAS

  • @doupiu said in Помогите оптимизировать код (запросы к БД):

    @sergerdn да, стандартная BAS

    Для кого стандартная, а для кого и древнее legacy, которым не то, что лучше не пользоваться. А, вероятно, вообще не надо.

    В рамках встроенной mongodb эту задачу не решить. В рамках других БД варианты есть.

  • @sergerdn хорошо, пусть будет так, я не защищаю mongodb и это не является целью топика) Не могли бы вы подсказать, хотя бы в общих чертах, как данная проблема решается в других БД? Потому что если бы я это делал на другой БД - я бы сделал ту же самую логику и столкнулся бы с той же самой проблемой..

  • @doupiu said in Помогите оптимизировать код (запросы к БД):

    Не могли бы вы подсказать, хотя бы в общих чертах, как данная проблема решается в других БД?

    Проблема в том, что даже если я дам четкие инструкции, вероятно, ты делать не будешь, так как сложно.

    Так как если бы было для тебя просто, ты сам бы знал, так как имел бы такой опыт.

    Дилемма.

    https://www.postgresql.org/docs/current/sql-notify.html

  • @doupiu said in Помогите оптимизировать код (запросы к БД):

    @sergerdn хорошо, пусть будет так, я не защищаю mongodb и это не является целью топика) Не могли бы вы подсказать, хотя бы в общих чертах, как данная проблема решается в других БД? Потому что если бы я это делал на другой БД - я бы сделал ту же самую логику и столкнулся бы с той же самой проблемой..

    У многих БД есть тригеры которые срабатывают по определенным условиям. У монго то же есть, но связать это с БАС все равно будет проблематично.

  • @UserTrue said in Помогите оптимизировать код (запросы к БД):

    У многих БД есть тригеры которые срабатывают по определенным условиям. У монго то же есть, но связать это с БАС все равно будет проблематично.

    Человек где-то в соседней теме связывал BAS c https://www.rabbitmq.com/ или подобное. Не знаю насколько успешно или нет.

    Вероятно, это и нужно @doupiu.

  • @sergerdn said in Помогите оптимизировать код (запросы к БД):

    Человек где-то в соседней теме связывал BAS c https://www.rabbitmq.com/ или подобное. Не знаю насколько успешно или нет.

    Вероятно, это и нужно @doupiu.

    Если писать кодом то проблем с любой БД и менеджер очередей тут как по мне оверхэд, но если писать кубиками в БАС это будет проблема )

  • @sergerdn @UserTrue Увы, да, вы правы, но менять БД ради этой проблемы просто нецелесообразно с т.з ресурсов (хоть и возможно), потому что в остальном mongodb работает нормально.

    Но полагаю, что даже средствами BAS можно неидеально (но приемлимо) решить проблему. Поэтому и был создан данный топик, думал пообщаться с теми, кто работает с mongodb BAS-овской.

    Пришла в голову идея, что можно завести отдельный асинхронный поток, который будет дергать БД каждые 100 мс и сохранять результат в глобалку. Итого 1 запрос против 50 при той же частоте проверок. По факту тот же триггер, сделанный вручную. Вот надеялся, что кто-то уже делал что-то подобное и что-то посоветует.

  • @doupiu said in Помогите оптимизировать код (запросы к БД):

    Пришла в голову идея, что можно завести отдельный асинхронный поток, который будет дергать БД каждые 100 мс и сохранять результат в глобалку. Итого 1 запрос против 50 при той же частоте проверок. По факту тот же триггер, сделанный вручную. Вот надеялся, что кто-то уже делал что-то подобное и что-то посоветует.

    Да тогда уж проще реализовать longpolling к источнику данный которые присылает данные в БД, то есть делается запрос без таймаута и висит пока сервер не ответит

  • @doupiu said in Помогите оптимизировать код (запросы к БД):

    Поэтому и был создан данный топик, думал пообщаться с теми, кто работает с mongodb BAS-овской.

    Работают, но лучше не надо. Рано или поздно проблем огребешь.

    Другое дело, что альтернатив в BAS для тех, кто не умеет кодить, нет.

  • @UserTrue said in Помогите оптимизировать код (запросы к БД):

    Да тогда уж проще реализовать longpolling к источнику данный которые присылает данные в БД, то есть делается запроса без таймаута и висит пока сервер не ответит

    А что будет, если данные так и не появятся?

  • @sergerdn said in Помогите оптимизировать код (запросы к БД):

    @UserTrue said in Помогите оптимизировать код (запросы к БД):

    Да тогда уж проще реализовать longpolling к источнику данный которые присылает данные в БД, то есть делается запроса без таймаута и висит пока сервер не ответит

    А что будет, если данные так и не появятся?

    Можно сделать очень большой таймаут, я как понял без этих данных его скрипт все равно не может работать

  • @UserTrue said in Помогите оптимизировать код (запросы к БД):

    Можно сделать очень большой таймаут, я как понял без этих данных его скрипт все равно не может работать

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

    @doupiu поделишься, что делаешь то?

  • @sergerdn said in Помогите оптимизировать код (запросы к БД):

    @doupiu поделишься, что делаешь то?

    В принципе, в исходном сообщении все описано подробно для решения задачи, на мой взгляд, но вот еще чуть подробностей)

    Скрипт проверяет наличие товара в интернет-магазине в 50 потоков. Задержка между каждыми проверками внутри потока - 10 сек. При этом, если какой-то поток увидел, что товар есть в наличии, он записывает это в БД. С этого момента все потоки из режима "проверяем наличие" переходят в режим "покупаем товар". Именно для этого сделан цикл, который представлен в исходном сообщении. То есть каждый поток либо ждет 10 сек, чтобы сделать следующую проверку наличия, либо моментально покупает товар, так как наличие уже нашел другой поток.

    P.S. Очевидное решение - вообще исключить отсюда БД и сделать глобалку наличия, которую постоянно проверять в цикле. Но там все несколько сложнее и БД все равно нужна.

  • This post is deleted!
  • @doupiu said in Помогите оптимизировать код (запросы к БД):

    С этого момента все потоки из режима "проверяем наличие" переходят в режим "покупаем товар".

    Не проще использовать ресурс или глобальную переменную

  • @UserTrue said in Помогите оптимизировать код (запросы к БД):

    Не проще использовать ресурс или глобальную переменную

    Как и написал, решение очевидное, но не подходящее, к сожалению. Товаров не 1, а сотня. У каждого товара есть еще десяток параметров, влияющих на дальнейшую работу скрипта. Поэтому все хранится в БД.

  • @doupiu said in Помогите оптимизировать код (запросы к БД):

    @UserTrue said in Помогите оптимизировать код (запросы к БД):

    Не проще использовать ресурс или глобальную переменную

    Как и написал, решение очевидное, но не подходящее, к сожалению. Товаров не 1, а сотня. У каждого товара есть еще десяток параметров, влияющих на дальнейшую работу скрипта. Поэтому все хранится в БД.

    Если все скрипты работают на одном сервере:

    1. Стартуют потоки с поиском товара.
    2. Товар найден, данные пишутся в базу.
    3. Этот же скрипт запускает любым способом другой функционал, который покупает этот товар. Например, это может быть функция в BAS.

    Вероятно, изначально был написан скрипт с поиском товара, потом с его покупкой. И это все отдельные сущности.
    Потом между ними поставили БД для обмена информацией. Но возникли нюансы.

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

    В какой-то степени это помогает мне уложить в голову задачу и избежать части архитектурных ошибок.
    Перед тем, как писать какой-то код, я уже знаю почти все о будущем скрипте.

    Чтобы приобрести такой навык, нужен опыт. Иначе придется постоянно переделывать что-то, что бывает мучительно.

  • 0 Votes
    1 Posts
    393 Views
  • 0 Votes
    16 Posts
    1266 Views
  • 0 Votes
    2 Posts
    474 Views
  • 0 Votes
    9 Posts
    1127 Views
  • 0 Votes
    5 Posts
    3026 Views