У меня есть ежедневный процесс ETL в SSIS, который строит мой склад, чтобы мы могли предоставлять ежедневные отчеты.
У меня есть два сервера - один для SSIS, а другой для базы данных SQL Server. Сервер SSIS (SSIS-Server01) представляет собой блок на 8 ЦП, 32 ГБ ОЗУ. База данных SQL Server (DB-Server) - это еще один 8CPU, 32 ГБ RAM. Оба являются виртуальными машинами VMWare.
В своей упрощенной форме SSIS считывает 17 миллионов строк (около 9 ГБ) из одной таблицы на сервере DB, разворачивает их до 408 миллионов строк, выполняет несколько поисков и тонну вычислений, а затем объединяет их обратно примерно до 8 миллионов строк. которые каждый раз записываются в новую таблицу на том же сервере БД (затем эта таблица будет перемещена в раздел для предоставления ежедневных отчетов).
У меня есть цикл, который обрабатывает данные за 18 месяцев за раз - всего за 10 лет. Я выбрал 18 месяцев на основании своих наблюдений за использованием ОЗУ на SSIS-Server - в 18 месяцев он потребляет 27 ГБ ОЗУ. Если значение выше, SSIS начинает буферизацию на диск, и производительность падает.
Вот мой поток данных http://img207.imageshack.us/img207/4105/dataflow.jpg
Я использую Распространитель сбалансированных данных Microsoft для отправки данных по 8 параллельным путям для максимального использования ресурсов. Я создаю профсоюз перед тем, как начать работу над своими агрегациями.
Вот график диспетчера задач с сервера SSIS
Вот еще один график, показывающий 8 отдельных процессоров.
Как вы можете видеть из этих изображений, использование памяти постепенно увеличивается примерно до 27 ГБ по мере чтения и обработки все большего количества строк. Однако загрузка ЦП постоянно составляет около 40%.
Второй график показывает, что мы используем только 4 (иногда 5) ЦП из 8.
Я пытаюсь ускорить процесс (он использует только 40% доступного процессора).
Как мне сделать этот процесс более эффективным (минимум времени, больше ресурсов)?
После хороших предложений, сделанных bilinkc, и не зная, где находится узкое место, я бы попробовал еще несколько вещей.
Как вы уже отметили, вам следует работать над параллелизмом, а не обрабатывать больше данных (месяцев) в одном потоке данных. Вы уже выполнили параллельное выполнение преобразований, но источник и место назначения (а также агрегирование) не выполняются параллельно! Так что читайте до конца и имейте в виду, что вы должны заставить их работать параллельно, чтобы использовать мощность вашего процессора. И не забывай, что ты ограниченный объем памяти (невозможно объединить бесконечное количество месяцев в одном пакете), поэтому путь («горизонтальное масштабирование») - получить фрагмент данных, обработать его и как можно скорее поместить в целевую базу данных. Это требует исключения общих компонентов (один источник, одно объединение всех), потому что каждый блок данных ограничен скоростью этих общих компонентов.
Оптимизация по источнику:
Оптимизация, связанная с преобразованиями:
Оптимизация по направлению:
Похоже, я оставался неясным, какой путь использовать с параллелизмом. Можешь попробовать:
Прежде чем делать что-либо еще, вы можете провести быструю проверку: получить исходный пакет, изменить его на использование 1 месяца, сделать точную копию, которая обрабатывает еще один месяц, и запустить эти пакеты параллельно. Сравните это с вашим исходным пакетом обработки 2 месяца. Сделайте то же самое для двух отдельных пакетов на 6 месяцев и одного пакета на 12 месяцев одновременно. Он должен запустить ваш сервер с полной загрузкой ЦП.
Старайтесь не переупараллеливать, потому что у вас будет несколько операций записи в место назначения, поэтому вы не хотите запускать 18 параллельных ежемесячных пакетов, а скорее для начала 3 или 4.
И, наконец, я твердо верю, что необходимо устранить нагрузку на память и выделение ввода-вывода.
Сообщите нам о своем прогрессе.
(репост мой первоначальный ответ, без учета BDD)
В конце концов, вся обработка связана с одним из четырех факторов.
Первый шаг - определить, что является ограничивающим фактором, а затем определить, можете ли вы повлиять на него (получить больше или уменьшить использование)
Причина, по которой память вашего сервера заканчивается, когда вы делаете более 18 месяцев, связана с тем, почему для ее обработки требуется так много времени. В Сводные и агрегированные преобразования являются асинхронными компонентами. Каждой строке, поступающей от исходного компонента, выделено N байтов памяти. Та же самая корзина данных посещает все преобразования, применяет их операции и очищается в месте назначения. Это ведро памяти используется снова и снова.
Когда на арену выходит асинхронный компонент, конвейер разделяется. Корзина, в которой передавалась эта строка данных, теперь должна быть опустошена в новую корзину, чтобы завершить конвейер. Копирование данных между деревьями выполнения - дорогостоящая операция с точки зрения времени выполнения и памяти (может удвоиться). Это также уменьшает возможность для движка распараллелить некоторые возможности выполнения, поскольку он ожидает завершения асинхронных операций. Дальнейшее замедление операций связано с характером преобразований. Агрегат - это полностью блокирующий компонент, поэтому все данные должны быть доставлены и обработаны до того, как преобразование предоставит одну строку для последующих преобразований.
Если возможно, можете ли вы разместить сводную таблицу и / или агрегат на сервере? Это должно уменьшить время, затрачиваемое на поток данных, а также потребляемые ресурсы.
Вы можете попробовать увеличить количество параллельных операций, которые может выбрать движок. Статья Джейми, Статья SQL CAT
Если вы действительно хотите знать, где ваше время тратится в потоке данных, зарегистрируйте OnPipelineRowsSent для выполнения. Тогда вы можете использовать это запрос чтобы разорвать его (после замены sysssislog на sysdtslog90)
Судя по вашим графикам, ни ЦП, ни память не облагаются налогом ни в одной из коробок. Я полагаю, вы указали, что исходный и целевой сервер находятся в одном ящике, но пакет SSIS размещен и обрабатывается в другом ящике. Вы платите немалую плату за передачу этих данных по сети и обратно. Можно ли обрабатывать данные на исходном сервере? Вам нужно будет выделить больше ресурсов для этой коробки, и я скрещиваю пальцы, это большая мускулистая виртуальная машина, и это не проблема.
Если это не вариант, попробуйте настроить Размер пакета свойство диспетчера подключений к 32767 и обсудить с операторами сети, подходят ли вам кадры jumbo. Оба эти совета находятся в разделе "Настройте свою сеть".
Я отстой на счетчиках дисков, но вы должны увидеть, связаны ли типы ожидания с дисками.
Использовать Обозреватель процессов чтобы выявить использование дополнительных ресурсов (память и ввод-вывод). Обратите внимание, что график Disk-IO может немного вводить в заблуждение, поскольку пики на графике часто связаны с возможностями кэширования жестких дисков, поэтому, когда дисковый ввод-вывод является узким местом, он не всегда сразу проявляется на графике.
В некоторых случаях вам может быть полезно установить RAM-диск и поместить туда временные каталоги. Я успешно использовал вот этот чтобы сократить время, которое наша машина сборки использовала для полной ночной сборки и запуска тестов. Я не уверен, что SSIS принесет пользу.