Я использую postgreSQL для научного приложения (неконтролируемая кластеризация). Программа python является многопоточной, поэтому каждый поток управляет своим собственным процессом postmaster (по одному на ядро). Следовательно, у них много параллелизма.
Каждый цикл поток-процесс бесконечно через два SQL-запроса. Первый - для чтения, второй - для записи. Операция чтения учитывает 500 раз количество строк, учитываемых операцией записи.
Вот результат dstat:
----total-cpu-usage---- ------memory-usage----- -dsk/total- --paging-- --io/total-
usr sys idl wai hiq siq| used buff cach free| read writ| in out | read writ
4 0 32 64 0 0|3599M 63M 57G 1893M|1524k 16M| 0 0 | 98 2046
1 0 35 64 0 0|3599M 63M 57G 1892M|1204k 17M| 0 0 | 68 2062
2 0 32 66 0 0|3599M 63M 57G 1890M|1132k 17M| 0 0 | 62 2033
2 1 32 65 0 0|3599M 63M 57G 1904M|1236k 18M| 0 0 | 80 1994
2 0 31 67 0 0|3599M 63M 57G 1903M|1312k 16M| 0 0 | 70 1900
2 0 37 60 0 0|3599M 63M 57G 1899M|1116k 15M| 0 0 | 71 1594
2 1 37 60 0 0|3599M 63M 57G 1898M| 448k 17M| 0 0 | 39 2001
2 0 25 72 0 0|3599M 63M 57G 1896M|1192k 17M| 0 0 | 78 1946
1 0 40 58 0 0|3599M 63M 57G 1895M| 432k 15M| 0 0 | 38 1937
Я почти уверен, что мог бы писать чаще, потому что я видел, как он записывал до 110–140 МБ на dstat. Как я могу оптимизировать этот процесс?
Я автор dstat и системный инженер. Я заметил, что среднее время ожидания составляет 60%. Учитывая ваши результаты, я бы сказал, что ваши диски довольно заняты. Вы можете попробовать новую опцию плагина --disk-util в последних версиях dstat.
Это покажет вам степень использования вашего диска (ов), и я ожидаю, что она будет близка к 100% для диска (ов), который вы используете. Итак, учитывая ваш конкретный шаблон ввода-вывода, ваш диск достаточно занят обработкой запросов на чтение или запись.
Почему это ниже контрольных цифр? Потому что часто, когда вы тестируете пропускную способность диска, вы нагружаете свой диск по определенному шаблону, который оптимален для вашего диска / кешей (например, линейное чтение или запись с большими размерами блоков с одним потоком), в то время как в вашей текущей рабочей нагрузке определенные шаблоны могут быть менее оптимальным (случайное чтение или запись с небольшими или различными размерами блоков с несколькими потоками, запрашивающими ресурсы).
Эта разница в схеме может иметь огромное значение для пропускной способности. А повышение пропускной способности во время реальной рабочей нагрузки означает, что вам придется провести сравнительный анализ с рабочей нагрузкой, которая больше соответствует вашей реальной рабочей нагрузке, чтобы увидеть, какой максимум вы можете достичь в этих условиях. Или вы можете повлиять на реальную рабочую нагрузку, изменив свой дизайн (например, выровняв размеры блоков в вашем приложении с файловой системой / дисковой подсистемой) или улучшив кэширование и / или упреждающее чтение.
Нет простого способа исправить это, не проанализировав, как выглядит ваша рабочая нагрузка.
На самом деле это вполне может быть уровень кода Python. Python использует глобальную блокировку интерпретатора для обработки потоков, и вы можете столкнуться с блокировкой. В StackOverflow есть сообщение о GIL и многоядерные системы.
Я бы рассмотрел возможность использования процесса для каждого почтмейстера и «главного мастера», если это необходимо для управления этим процессом, или, возможно, Twisted, чтобы обойти GIL.
Я бы сказал, что это очень сильно зависит от кода программы, возможно, он ожидает повторной синхронизации рабочего потока перед запуском следующей операции.
Включает ли операция чтения те же данные, которые записываются, если да, вы можете получить условия параллелизма / гонки, если остановите его от ожидания, пока другие потоки наверстают упущенное.
Вероятно, лучше всего переместить это на переполнение стека.