我们希望在Oracle 11g R2和Linux之间传输大量数据。 SQL Server 2014在一段时间内......我们谈论的是20多个Tb,数千个表和数十亿条记录(这是一个为期5年的数据仓库)
SSIS它不是一个选项,因为表的数量和&我们需要转移的分区是巨大的,大约40k桌子和分区..我们有一些营销应用程序,营销经理,挖掘模型和其他,运行在不同的模式...其中一些每天创建约150个新表,并且“丢弃表率”每天大约100个...一些这些表有索引,有些不...这个模式是我们不能简单地使用SSIS的原因,因为我们也需要传输它们... 编辑以包含有关SSIS看起来不可行的原因的更多信息
所以我们用.Net 4.5.1在C#2013开发了一个应用程序,它是多线程的...每个线程在oracle中读取一个表/分区,在sql server中创建相同的表/分区模式,然后继续选择oracle中的数据,并在sql server中插入批量,最后创建每个挂起的约束和索引......
我们面临的主要问题之一是传输速度......比较传输1个事实表的SSIS性能与30个分区(每月事实,每日分区,每个分区大约3000万行,60多列)对抗我们的C#应用程序,我们发现该应用程序永远不会使用全网速,而SSIS使用100%(我们使用适用于Oracle的Attunity SSIS连接器......可能其中一个速度传输优势在这里,我不知道),我们希望改进这个如果我们能......
这是负责写
的代码块//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);
}
任何人对我们可以测试configure的任何选项(代码的注释部分来自以前测试的选项),SQL Server或C#app中的SQLBulkCopy对象有任何建议吗?
PS:关于我们环境的一些信息...... Oracle Server Client Uplink 2 Gbps,SQL Server Downlink 1 Gbps,Oracle是32核心系统,我们的测试SQL Server是16核Win Server 2012 R2系统... SSIS Net传输速度为1 Gbps全,C#App Net传输速度大约70 mbps,有16个线程...
编辑以提供有关传输速度的更多信息
有关我们的应用测试的更多信息:
2个线程= 15-25 Mbps
4个线程= 30-40 Mbps
8个线程= 60-65 Mbps
16个线程= 65-70 Mbps
16以上(每个系统核心1个应用程序线程)将性能降低到30-50 Mbps ..
我们的SAN能够以高于500 MB / s的速度运行,并且具有高I / O数
我们最好的批量大小时间我们得到它的值为每批2500-5000行(5分钟内约有1500万行,8-16个线程)
现在我们的应用程序将数据从oracle中的一个表/分区传输到SQL Server中的其他表...我们有一些非分区表,其中包含超过100万行...对于这些表,我们测试了多个线程读取同一个表。 ..我们在读取过程中取得了成功,但在批量插入数据时失败了
每个线程读取同一个表,对数字列进行MOD操作......
select * from schema.table where MOD(NUMERIC_COLUMN, N) = 0 to N-1
N它是我们正在运行的线程数...我们尝试重新创建一些SSIS行为以最大化线程使用&amp;在Oracle / SQL中读取/写入数据。在SSIS中,我们可以在目的地设置每个带有LOCK TABLE选项的线程,并且它完美无缺......但是在我们的应用程序中执行它时,每个线程在插入期间锁定表,最后我们的并行化设计运行序列化:((这不是问题的主要原因,但如果有人对此提出建议,将不胜感激)
答案 0 :(得分:0)
您与1Gbps链路上的理论最大吞吐量相差甚远。 1Gbps最大吞吐量为125 MB / s,无任何开销。你真的在考虑实际的90 MB / s,如果你正在经历一个必须处理数据包的第3层交换机,路由器或防火墙,吞吐量将会下降。您最好的办法是让服务器位于同一网段,并在它们之间获得更高速的链接。我怀疑当线程数较高时吞吐量下降的原因是因为线程正在争夺对NIC的访问(或者由于数据包大小而导致NIC每个数据包引入延迟)并且线程正在暂停执行(睡觉)再试一次。
我认为你的问题是吞吐量。通过绑定两个1Gbps链路尝试更高速的连接。或者,如果服务器彼此靠近,请使用交叉电缆直接连接它们(无开关),以查看传输速度是否增加。如果他们这样做,您知道您有吞吐量问题。如果他们没有,你至少消除了一种可能性。