Python Sqlite Параллельный доступ - PullRequest
0 голосов
/ 07 мая 2018

У меня есть сценарий, в котором стороннее приложение сканирует папку и запускает мой скрипт на Python / сгенерированный EXE-файл для количества раз (да! Количество отдельных процессов) для количества файлов в папке. Мой скрипт / приложение записывает путь к файлу в локальную базу данных sqlite, вызывает следующее приложение и завершает работу. Мой скрипт / приложение заботится о том, чтобы он вызывал только один экземпляр следующего приложения. Но ничего не поделаешь со сторонним приложением, которое вызывает мой скрипт.

ВЫПУСК Иногда более 1000 экземпляров моего скрипта / приложения могут быть вызваны одновременно, что приводит к почти 1000 одновременных подключений к локальной базе данных sqlite. Из-за ограниченного числа одновременных подключений, возможных с sqlite, некоторые процессы получают исключение «база данных заблокирована». Это приводит к тому, что некоторые имена файлов НЕ записываются в базу данных Мы придумали работу для этого. Мы записываем в базу данных в бесконечном цикле. При обнаружении исключения мы заставляем поток спать в течение, скажем, 50 миллисекунд и повторяем попытку до тех пор, пока запись не заработает. Я знаю, что это не чистый подход.

Есть ли лучший способ сделать это? Как я могу обработать 1000, может быть 10000 или может быть больше одновременных соединений, и все же каждый сценарий успешен?

Ответы [ 2 ]

0 голосов
/ 07 мая 2018

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

Но это все равно приводит к случайному времени ожидания. SQLite не ожидает завершения транзакции одного писателя, а затем сигнализирует о следующем, потому что для этого не существует portable API. Однако в Windows вы могли бы использовать именованный объект mutex (для этого требуется некоторая хитрость для доступа к нему из Python).

0 голосов
/ 07 мая 2018

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

https://pgbouncer.github.io/

Единственный способ справиться с этим - создать пул самостоятельно и подключить к нему соединения вместо базы данных SQLITE напрямую.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...