Мы хотим передать огромное количество данных между 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 в пункте назначения, и он работал безупречно. Но, делая это в нашем приложении, каждый поток блокирует таблицу во время вставки и, наконец, наш параллельный дизайн запускается сериализован :((Это не основная причина вопроса, но если у кого-то есть предложения по этому поводу, будет понятно)
Когда вы запускаете SSIS и приложение C#, вы видите какую-либо разницу в типах/временах ожидания для записи в SQL? –
Из-за порочного любопытства, не могли бы вы помочь мне понять «SSIS, это не вариант, потому что количество таблиц и разделов, которые нам нужно передать, огромно» Кажется, что он обрабатывает скорость просто отлично по сравнению с вашей доморощенной системой – billinkc
, темы вы создаете? Наличие большого количества потоков, выполняемых одновременно, будет большим перфомансом. Показать больше кода. –