2014-12-16 3 views
5

Мы хотим передать огромное количество данных между Oracle 11g R2 & SQL Server 2014 за небольшое количество времени ... мы говорим о 20+ Tb, тысячах таблицы и миллиарды записей (это 5 лет Datawarehouse)Многопоточная передача данных между Oracle и SQL Server - Производительность сети

SSIS это не вариант, так как количество таблиц & разделов, которые мы должны передать огромный, около 40к столы & перегородки .. у нас есть некоторые маркетинговые приложения, Менеджеры кампаний, Модели интеллектуального анализа и другие, работающие в разных схемах ... некоторые из них ежедневно создают около 150 новых таблиц, а «скорость снижения таблицы» составляет около 100 в день ... некоторые из этих таблиц имеют индексы, а некоторые нет. .. эти схемы являются причиной почему мы не можем просто использовать SSIS, потому что мы должны передать их тоже ... Изменить, чтобы включить больше информации о том, почему SSIS не выглядит жизнеспособным вариантом

Таким образом, мы разработали приложение в C# 2013 с .Net 4.5.1, и он многопоточен ... каждый поток читает таблицу/раздел в oracle, создает ту же таблицу/схему раздела в sql-сервере и переходит к выбору данных в oracle, а объем вставляется в sql-сервер и наконец, создать каждое ожидающее ограничение и индекс ...

Одной из основных проблем, с которыми мы сталкиваемся, является скорость передачи данных ... Сравнение производительности SSIS с передачей 1 таблицы фактов с 30 разделами (ежемесячный факт, ежедневный раздел, около 30 миллион строк на раздел, 60 +) против нашего приложения C#, мы обнаружили, что приложение никогда не использует полную скорость сети, в то время как SSIS использует 100% (мы используем соединители SSIS Attunity для Oracle ... и, вероятно, одно из преимуществ передачи скорости здесь, я не знаю) и мы хотим, чтобы улучшить это, если мы можем ...

Это блок кода, отвечающие за запись

//private static async Task saveDataBlock(IDataReader reader, string destinationTable, int batchSize) 
private static void saveDataBlock(IDataReader reader, string destinationTable, int batchSize) 
{ 
    //System.Data.SqlClient.SqlBulkCopy bc = new System.Data.SqlClient.SqlBulkCopy(getConnString(destinationCS)); 
    //System.Data.SqlClient.SqlBulkCopy bc = new System.Data.SqlClient.SqlBulkCopy(getConnString(destinationCS), System.Data.SqlClient.SqlBulkCopyOptions.KeepIdentity & System.Data.SqlClient.SqlBulkCopyOptions.KeepNulls & System.Data.SqlClient.SqlBulkCopyOptions.TableLock); 
    using (SqlBulkCopy bc = new SqlBulkCopy(getConnString(destinationCS))) 
    { 
     bc.BulkCopyTimeout = 0; 
     bc.DestinationTableName = destinationTable; 
     bc.BatchSize = batchSize; //2500,5000,10000.. best so far, 5000 
     //bc.BatchSize = 0; 
     bc.NotifyAfter = batchSize; 
     bc.SqlRowsCopied += new SqlRowsCopiedEventHandler(s_SqlRowsCopied); 
     //bc.EnableStreaming = true;    

     bc.ColumnMappings.Clear(); 
     for (int i = 0; i < reader.FieldCount; i++) 
     { 
      bc.ColumnMappings.Add(reader.GetName(i), reader.GetName(i)); 
     } 

     bc.WriteToServer(reader); 
     //await bc.WriteToServerAsync(reader); 
     //bc.Close(); 
    } 

    //System.Data.SqlClient.SqlBulkCopy bc = new System.Data.SqlClient.SqlBulkCopy(getConnString(destinationCS), SqlBulkCopyOptions.UseInternalTransaction);    

} 

Кто-нибудь есть какие-либо предложения по поводу любого варианта мы можем проверить в конфигурировании (комментируемые разделы код из предыдущих тестируемых опций), в SQL Server или в объекте SQLBulkCopy в приложении C#?

PS: информация о нашей среде ... Oracle Server Client Uplink 2 Гбит/с, SQL Server Downlink 1 Гбит/с, Oracle - 32-ядерная система, наш тестовый SQL Server - это 16-ядерная система Win Server 2012 R2. . SSIS Чистая скорость передачи данных 1 Гбит полный, C# App Чистая скорость передачи данных составляет около 70 Мбит, с 16 нитями ...

РЕДАКТИР принести больше информации о скорости передачи

Более подробную информацию о нашем приложении испытания:

2 threads = 15-25 Mbps

4 нити = 30-40 Мбит

8 потоков = 60-65 Мбит

16 потоков = 65-70 Мбит

Все выше 16 (1 приложения нити на ядро ​​системы) сбить производительность до 30-50 Мбит/с.

Наша SAN очень способен развивать скорость свыше 500 Мбайт/с, при подсчете High I/O

Наши лучшие времена размер партии мы получили его со значениями между 2500-5000 строк на партию (около 15 миллионов строк через 5 минут, с 8-16 потоками)

Прямо сейчас наше приложение передает данные из одной таблицы/раздела в oracle в другое на SQL Server ... у нас есть несколько несетевых таблиц со 100+ миллионами строк ... для в этих таблицах мы протестировали несколько потоков, читающих одну и ту же таблицу ... нам удалось выполнить процесс чтения, но не удалось выполнить объемную вставку данных

Свинец читает ту же таблицу, делая MOD операцию над числовой колонкой ...

select * from schema.table where MOD(NUMERIC_COLUMN, N) = 0 to N-1 

N этого число потоков мы бежим ... Мы попытались воссоздать некоторые виды поведения SSIS, чтобы максимально использовать нить & чтения данных/писать в Oracle/SQL .. В SSIS мы можем установить каждый поток с параметром LOCK TABLE в пункте назначения, и он работал безупречно. Но, делая это в нашем приложении, каждый поток блокирует таблицу во время вставки и, наконец, наш параллельный дизайн запускается сериализован :((Это не основная причина вопроса, но если у кого-то есть предложения по этому поводу, будет понятно)

+0

Когда вы запускаете SSIS и приложение C#, вы видите какую-либо разницу в типах/временах ожидания для записи в SQL? –

+1

Из-за порочного любопытства, не могли бы вы помочь мне понять «SSIS, это не вариант, потому что количество таблиц и разделов, которые нам нужно передать, огромно» Кажется, что он обрабатывает скорость просто отлично по сравнению с вашей доморощенной системой – billinkc

+1

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

ответ

0

Вы находитесь недалеко от теоретической максимальной пропускной способности на скорости 1 Гбит/с ссылка. Максимальная пропускная способность 1 Гбит/с составляет 125 МБ/с без каких-либо накладных расходов. Вы действительно смотрите на 90 МБ/с, и если вы проходите через коммутатор уровня 3, маршрутизатор или брандмауэр, которому приходится обрабатывать пакеты, пропускная способность будет снижаться. Лучше всего получить серверы в одном сетевом сегменте и получить более высокую скорость связи между ними. Я подозреваю, что ваша пропускная способность падает, когда количество потоков больше, потому что потоки борются за доступ к NIC (или сетевой адаптер вводит задержку на пакет из-за большого размера пакета), и потоки выполняют выполнение паузы (сон) и повторите попытку.

Я думаю, что ваша проблема - пропускная способность. Попробуйте соединение с более высокой скоростью, соединяя две линии 1 Гбит/с. Или, если серверы близки друг к другу, подключите их напрямую (без коммутатора) с помощью кроссового кабеля, чтобы узнать, увеличиваются ли скорости передачи. Если они это сделают, вы знаете, что у вас проблема пропускной способности. Если они этого не сделают, вы, по крайней мере, устранили возможность.

Смежные вопросы