Какие-либо конкретные проблемы с запуском (linux) BCP в "слишком многих" потоках? - PullRequest
0 голосов
/ 09 октября 2018

Существуют ли какие-либо конкретные проблемы с запуском служебной программы Microsoft BCP (в CentOS 7, https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-migrate-bcp?view=sql-server-2017) в нескольких потоках? Google не может найти много, но я смотрю на проблему, которая, похоже, связана именно с этим.

Копирование набора больших файлов TSV из HDFS на удаленный MSSQL-сервер с некоторым кодом вида

bcpexport() {
    filename=$1
    TO_SERVER_ODBCDSN=$2
    DB=$3 
    TABLE=$4 
    USER=$5
    PASSWORD=$6
    RECOMMEDED_IMPORT_MODE=$7 
    DELIMITER=$8 

    echo -e "\nRemoving header from TSV file $filename"
    echo -e "Current head:\n"
    echo $(head -n 1 $filename)
    echo "$(tail -n +2 $filename)" > $filename
    echo "First line of file is now..."    
    echo $(head -n 1 $filename)

    # temp. workaround safeguard for NFS latency
    #sleep 5 #FIXME: appears to sometimes cause script to hang, workaround implemented below, throws error if timeout reached 
    timeout 30 sleep 5

    echo -e "\nReplacing null literal values with empty chars"
    NULL_WITH_TAB="null\t" # WARN: assumes the first field is prime-key so never null
    TAB="\t"
    sed -i -e "s/$NULL_WITH_TAB/$TAB/g" $filename
    echo -e "Lines containing null (expect zero): $(grep -c "\tnull\t" $filename)"

    # temp. workaround safeguard for NFS latency
    #sleep 5 #FIXME: appears to sometimes cause script to hang, workaround implemented below 
    timeout 30 sleep 5

    /opt/mssql-tools/bin/bcp "$TABLE" in "$filename" \
        $TO_SERVER_ODBCDSN \
        -U $USER -P $PASSWORD \
        -d $DB \
        $RECOMMEDED_IMPORT_MODE \
        -t "\t" \
        -e ${filename}.bcperror.log
}

export -f bcpexport
parallel -q -j 7 bcpexport {} "$TO_SERVER_ODBCDSN" $DB $TABLE $USER $PASSWORD $RECOMMEDED_IMPORT_MODE $DELIMITER \
    ::: $DATAFILES/$TARGET_GLOB 

, где $DATAFILES/$TARGET_GLOB создает глобальный список, который перечисляет набор файлов в каталоге.

При запуске этого кода для набора файлов TSV обнаруживается, что иногда некоторые (но не все) параллельных потоков BCP перестают работать, т. Е. Некоторые файлы успешно копируются на MSSQL Server

Начальное копирование ...

5397376 скопированных строк.

Размер сетевого пакета (в байтах): 4096

Время часов (мс.) Всего: 154902 Среднее: (34843,8 строк в секунду)

, в то время как другие выводят сообщение об ошибке

Начальная копия ...

Ошибка копирования BCP

Обычно, смотрите этот шаблон: несколько успешных копий BCP-in операции в первых нескольких потоках возвращаются, затем группа неисправных потоков возвращает свои выходные данные до тех пор, пока не закончатся файлы (GNU Parallel возвращает выходные данные только тогда, когда весь поток выполнен таким же образом, как если бы он был последовательным).

Примечание вв коде есть опция -e для создания файла ошибок для каждой операции копирования BCP (см. https://docs.microsoft.com/en-us/sql/tools/bcp-utility?view=sql-server-2017#e).. При проверке файлов после наблюдения за этими ошибками поведения все они пусты, сообщений об ошибках нет.

Видели это только с числом потоков> = 10 (и только для определенных наборов данных (если предположить, что что-то связано с общим количеством файлов, это размеры файлов, и все же ...)), ошибок не было, так чтодалеко при использовании ~ 7 потоков, что еще больше заставляет меня подозревать, что это как-то связано с многопоточностью.

Мониторинг системных ресурсов (через free -mh) показывает, что обычно ~ 13 ГБ или ОЗУ всегда доступно.

Может быть полезно отметить, что данные bcp пытаются скопировать, могутбыть длиной ~ 500000-1000000 записей с верхним пределом ~ 100 столбцов на запись.

Кто-нибудь знает, что здесь происходит?Обратите внимание, я довольно плохо знаком с использованием BCP, а также GNU Parallel и многопоточности.

Ответы [ 2 ]

0 голосов
/ 13 октября 2018

TLDR : добавление большего количества потоков для одновременной работы с bcp копируемыми файлами данных, по-видимому, влияет на , подавляя конечную точку MSSQL Server инструкциями по записи, вызывая bcp Потоки потерпели неудачу (может быть, истекло время ожидания) Когда число потоков становится слишком большим, кажется, зависит от размера копируемых файлов bcp (т.е. как количество записей в файле, так и ширина каждой записи (т.е. числостолбцов)).

Длинная версия (больше причин для моей теории) :

1. При запуске большего числа bcpпотоки и просмотр процессов, запущенных на компьютере (https://clustershell.readthedocs.io/en/latest/tools/clush.html)

ps -aux | grep bcp

, наблюдающих несколько спящих процессов (обратите внимание на S, см. https://askubuntu.com/a/360253/760862), как показано ниже) (добавлены новые строки дляудобочитаемость)

me 135296 14,5 0,0 77596 6940? S 00:32 0:01

/ opt / mssql-tools / bin / bcp TABLENAME в /path / to / tsv / 1_16_0.tsv -D -S MyMSSQLServer -U myusername -P -d myDB -c -t \ t -e / path / to / logfile

Эти темы отображаются в спящем режимев течение очень долгого времени. Дальнейшее выяснение того, почему эти потоки спят, предполагает, что они могут фактически выполнять свою намеченную работу (что будет способствоватьЭто означает, что проблема может исходить от самого BCP (см. https://stackoverflow.com/a/52748660/8236733)). С https://unix.stackexchange.com/a/47259/260742 и https://unix.stackexchange.com/a/36200/260742)

Процесс в состоянии S обычно находится в системе блокировкивызов, например чтение или запись в файл или сеть, или ожидание завершения другой вызываемой программы .

(например,запись в конечную точку MSSQL-сервера, указанную для bcp в ODBCDSN)

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

2. При запуске разных наборов файлов с разным количеством записей на файл (например, диапазоны 500000 - 1000000 строк / файл) и шириной записи на файл (~ 10- 100 столбцов / строка), обнаружил, что в случаях с очень большой шириной данных или объемами, запуск фиксированного набора потоков bcp завершится с ошибкой .

Например.для набора ~ 33 TSV с ~ 500000 строк каждая, каждая строка имеет ширину ~ 100 столбцов, набор из 30 потоков записал бы первые несколько OK, но затем все остальные начнут возвращать сообщения об ошибках.Включая немного из ответа @ jamie, тот факт, что возвращаемые сообщения об ошибках являются "BCP copy in failed" ошибками, не обязательно означает, что они имеют отношение к содержанию рассматриваемых данных.Из-за отсутствия реального содержимого, записанного в файлы журнала ошибок -e из моего процесса, сообщение @ jamie говорит, что это

Что касается параметра "-e", он предназначен для вывода ошибок данных. ошибки входа в систему, неверные имена таблиц ... многие другие ошибки не сообщаются в файле, созданном с параметром -e .Когда вы получите вывод, используя опцию «-e», вы увидите информацию типа «усеченное значение», и такая ... даст вам номера строк и примеры данных, которые были спорными.

Между тем, набор из ~ 33 TSV с ~ 500000 строк каждая, каждая строка имеет ширину ~ 100 и все еще использующий 30 bcp потоков, завершится быстро и без ошибок (также будет быстрее, когдауменьшение количества потоков или набора файлов). Единственным отличием здесь является общий размер данных, bcp скопированных на MSSQL-сервер.

Все это пока

free -mh 

ещепоказал, что на машине, на которой выполнялись потоки, в каждом случае оставалось ~ 15 ГБ свободной оперативной памяти (и это опять-таки, почему я подозреваю, что проблема связана с удаленной конечной точкой MSSQL-сервера, а не с кодом или локальной машиной сам).

3. При запуске некоторых тестов из (2) обнаружил, что вручную убивает процесс parallel (через CTL+C), а затем пытается удаленно обрезать таблицу тестирования, в которую записывается/opt/mssql-tools/bin/sqlcmd -Q "truncate table mytable" на локальном компьютере займет очень много времени (в отличие от ручного входа на сервер MSSQL и выполнения truncate mytable в БД).Опять же, это заставляет меня думать, что это как-то связано с тем, что MSSQL Server имеет слишком много соединений и просто перегружен.

** Любой, у кого есть опыт MSSQL Mgmt Studio, читал это (у меня естьв основном нет), если вы видите здесь что-то, что заставляет вас думать, что моя теория неверна, пожалуйста, дайте мне знать ваши мысли.

0 голосов
/ 10 октября 2018

Нет, никаких проблем, специфичных для программы BCP, выполняемой в нескольких потоках.Похоже, вы на пути к тому, что я бы сказал, ваша проблема - системные ресурсы.Вы контролировали системные ресурсы, увеличивая количество потоков?Во всяком случае, есть проблема с выполнением BCP должным образом, когда ресурсы памяти / процессора / сети невелики.Что касается опции "-e", она предназначена для вывода ошибок данных.ошибки входа в систему, неправильные имена таблиц ... многие другие ошибки не сообщаются в файле, созданном с помощью опции -e.Когда вы получите вывод, используя опцию «-e», вы увидите информацию типа «усеченное значение», и такая ... даст вам номера строк и примеры данных, которые были спорными.

...