博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【高级内部资料】.NET数据批量写入性能分析 第一篇
阅读量:5258 次
发布时间:2019-06-14

本文共 2371 字,大约阅读时间需要 7 分钟。

【高级内部资料】.NET数据批量写入性能分析 第一篇

 

       说起数据的批量写入,相信大家应该不陌生了,那么我们本系列的文章不准备讲述如何来进行数据的批量写入,而是介绍常用的数据批量写入方法的性能分析。

 

       同时,本篇问题的目的不是告诉大家,何种方式最好(很多人喜欢问“什么是最好的”,在技术中没有所谓的最好的技术,一切都要情况而定),而是给大家一些数据,让大家知道各种不同的情况对性能的影响,从而帮助大家更好地进行抉择。

 

       在.NET环境中,数据批量写入的方式有很多,大家随便上面找一下就可以找到一大堆。在众多的数据批量写入方式中,SqlBulkCopy与SSIS是用的比较多,也是相对而言比较成熟的方案。     

 

也许大家认为SqlBulkCopy我用过,那么,这里就有几个问题大家可以在心里想一想是否可以明确的回答:

    1. 如何设置SqlBulkCopy的各个属性的,是否确切的直到每一个属性对写入性能的影响,而不是凭感觉。
    2. 写入的数据量是多少?到底何为批量?1000?100万?还是?
    3. 不同级别的数据写入对CPU,网络,磁盘的影响?
    4. 写入的时候,数据库的性能如何?是否被写死了?还是我们以为“数据库会管理好这一切的”

……

       还有更多的问题,这里就不在罗列了。那么,我们本系列将会对它们进行深入的对比,如果大家对它们不是很熟悉,可以借此机会学习一下,批量数据的写入操作是每个.NET技术人员都要掌握的技能之一。

 

       SqlBulkCopy是随着.NET Framework 2.0而发布的类,其实SqlBulkCopy就是一个.NET与数据库BULK Insert命令的一个接口。

       当我们调用SqlBulkCopy的方法和设置相关的属性的时候,这些都会以BULK Insert命令发送给数据库去执行。SqlBulkCopy有很多的属性,而这些属性的设置可以在不同的程度上面影响数据写入的性能。我们本系列文章不会详细的讲述如何使用SqlBulkCopy类,而是讲述一些我们关心的属性设置(不会把所以的属性设置全部讲完)。

 

学习本系列文章,因为不是初级的文章,希望大家有一下的技术背景:

    1. 对.NET知识有比较扎实的理解
    2. 掌握.NET的并行编程相关的知识
    3. 如果对SQL Server的内核有一定的认识那就更好了

 

下面,我们就进入正题。

 

       在把数据从一个地方加载到另外的一个地方的时候,常常会用到Producer/Consumer模式,流程如下(中文理解为:生产与消费模式,这个中文的理解有点怪,以后我们直接就用英文称呼):

    1. Producer(生产者)从指定的数据源中获取数据(数据源可以是任何的形式,例如文本,XML,数据库,甚至是其他提供数据的服务接口等)
    2. 如果有需要,Producer对数据进行相关的操作
    3. Producer将数据传递给Consumer,然后Consumer将数据写入到指定的目标源中。

简单的理解就是:Producer提供数据,Consumer使用数据。

 

       如果大家对SSIS有所了解的话,应该很好理解上面的这种模式。很多的时候,当我们对数据进行传输,转换等操作的时候,SSIS倒是一个非常不多的工具(SSIS在实际中也是非常常用的,可能在国内用的少一点)。当然,除此之外,我们还可以写.NET的代码来进行上述的操作,特别是当数据转换的操作和逻辑特别复杂的时候。

 

       另外,在使用Producer/Consumer模式的时候,我们可以充分的利用多核计算机的能力,使用并行编程来提升性能:使用多个Producer来并行的加载数据,然后将数据传递给多个Consumer,从而使得数据的读取,转换,写入的负载分担在多个核上面。

 

       注意:Producer与Consumer不是一一对应的关系,即不是每个Producer,非得有一个Consumer

用下面的一个图就可以说明这个问题:

 

 

 

 

      对于SqlBulkCopy而言,不是非常适合提到的上面提到的“Producer/Consumer模式” ,因为我们在用SqlBulkCopy将数据写入的时候,直接调用的是WriteToServer方法将数据以一定的形式(DataTable或者DataReader等)写入到了数据库,没有一个明确的Consumer,如果真有,那也是目标数据源了,这个时候Producer就和Consumer是个一一对应的关系了。在这种情况下,如果我们要产生了10个Producer,之后要使用一个Consumer将数据写入(或者少于10的Consumer),那么,我们就需要做更多的事情来克服SqlBulkCopy的限制了。

 

      在我们接下来的性能分析中,我们将会克服上面说的那个限制:我们自己来实现一个继承了IDataReader接口的缓冲对象,这个对象可以用来进行很多的复杂的数据操作,而SqlBulkCopy将会把我们自己实现的缓冲对象当成是DataReader来获取数据。实现如图所示:

 

采用了上面的实现之后,我们就可以实现这样的方式:

    1. 使用多个Producer将数据发送给多个Consumer
    2. 一个Producer将数据发送给多个Consumer
    3. 多个Producer将数据发送给一个Consumer

       同时有一点需要注意的就是:如果数据的Producer和Consumer同时运行,那么会使用很多的内存,并且Producer和Consumer越多,内存使用的越多,因为数据都是在处理的时候都放在内存中的,一直到最后将数据写入到数据库等地方,此时内存就会被释放。

 

由于时间的限制,我们暂时就唠叨到这里!下一篇,我们就来看看如何进行性能的分析!

 

系列文章链接:

  

  

 

 

      
 
 

 

转载于:https://www.cnblogs.com/yanyangtian/archive/2012/04/05/2433018.html

你可能感兴趣的文章
nginx修改内核参数
查看>>
C 筛选法找素数
查看>>
TCP为什么需要3次握手与4次挥手(转载)
查看>>
IOC容器
查看>>
Windows 2003全面优化
查看>>
URAL 1002 Phone Numbers(KMP+最短路orDP)
查看>>
web_day4_css_宽度
查看>>
electron入门心得
查看>>
格而知之2:UIView的autoresizingMask属性探究
查看>>
我的Hook学习笔记
查看>>
js中的try/catch
查看>>
寄Android开发Gradle你需要知道的知识
查看>>
简述spring中常有的几种advice?
查看>>
整理推荐的CSS属性书写顺序
查看>>
ServerSocket和Socket通信
查看>>
css & input type & search icon
查看>>
源代码的下载和编译读后感
查看>>
Kafka学习笔记
查看>>
Octotree Chrome安装与使用方法
查看>>
Windows 环境下基于 Redis 的 Celery 任务调度模块的实现
查看>>