Комментарии 12
И когда он это делает не оптимально (для меня) — хочется вмешаться и явно сказать что и на каком ядре запускать.Выглядит очень странно. Операционка обычно равномерно нагружает ядра. Возможно ваши воркеры никогда не завершаются, и тогда у операционки нет возможности перераспределить нагрузку. Простым решением в вашем случае должен быть запуск каждой поступающей задачи в новом потоке, и завершать поток при завершении задачи. Но это не точно.
Да, вы совершенно правы- воркеры не завершаются- это зацикленный обработчик бесконечного входящего потока данных. Программа ждет появления данных в бд, обрабатывает и кладет в другую бд и так бесконечно. Как-то не хотелось бы этот процесс прерывать, но даже если и прерывать- то я не вижу как это поможет делу.. и почему перезапущенный воркер будет работать более оптимально, если при предыдущем запуске он работал не так..
Равномерное распределение по ядрам достигается путем повышения гранулярности задач и использования архитектуры очередь-воркеры. То есть вам не нужно отдавать воркеру слишком жирную задачу, иначе когда другие воркеры освободятся, этот воркер не поделится с ними этой задачей. Нужно разбивать задачку на чанки, их скармливать в очередь, а из очереди воркерами эти чанки забирать.
В случае микросервисной архитектуры, сервисы могут забирать чанки из любого брокера сообщений (kafka, rabbit, etc). В случае питоновских потоков/процессов сгодятся встроенные очереди из стандартной библиотеки. Так же питон предоставляет сетевые очереди через Manager, к которым можно подключаться из других процессов питона.
и почему перезапущенный воркер будет работать более оптимально, если при предыдущем запуске он работал не так..
Тут конечно зависит от операционки и планировщика, но в общем самом худшем случае, новый воркер запустится на самом свободном ядре. Это поможет в том случае, если принимающий задачу воркер запущен на одном ядре с другим воркером, которое это ядро сейчас нагружает в полку, а при этом по соседству есть свободное ядро.
То что 16 программ работают на 15 логических ядрах, это не значит что они работают не оптимально. Надо понимать разницу между физическими ядрами и логическими, и как вообще происходит работа процессора. В общем случае нет особой нужды вмешиваться в работу планировщика.
Хорошо было бы добавить обзор asyncio, а ещё лучше, сравнить многопоточность и event loop для задач ввода-вывода.
Зачем, когда и как использовать multithreading и multiprocessing в Python