最快,最具可扩展性的文本导入方法 –大数据量加载最佳实践

来源:互联网 发布:淘宝店铺首页图片更换 编辑:程序博客网 时间:2024/05/18 14:27

       Oracle上的技术,其实是相当开放的,这里提到的这种文本导入方法,其实在官方文档中已经做了很好的论述和说明。只不过本着独乐乐不如众乐乐的想法,在这里再推广一把罢了。

       首先明确一点,文本导入到数据库中,或者把数据从数据库中导出为文本格式,这都是极其消耗CPU的操作。所以,对于一个配置均衡的系统而言,导出速度首先取决于系统CPU的运算能力。基于大数据量处理的系统一般都是多节点的RAC系统,于是,文本导入的一个主要议题就是:如何利用起所有RAC节点的所有CPU的运算能力。

       Oracle的Data Pump其实就达到了这个目标,在RAC系统中运行Data Pump,通过设置parallel参数,导入作业会在所有RAC节点运行,从而利用起系统可能存在的空闲的CPU资源。不过,Data Pump没有提供导入文本文件的方法。

      如果自己实现这种并行机制呢?那也未尝不可,SQL*Loader是Oracle的一个导入文本文件工具,叫做sqlldr,这是一个单进程的工具,不过我们可以在系统中启动多个sqlldr实例,通过指定不同的实例加载不同的文本文件,从而实现并行加载。这里有几点说明一下:

  • 通过把一个表的数据分割成多个文件,可以实现对一个表的并行加载
  • 通过在RAC的多个节点上启动多个sqlldr,可以实现跨节点的并行加载
  • 必须加上parallel=true参数,在每个sqlldr 的参数文件中。

     这个方法显而易见的有两个缺点

  • 必须用户自己协调多个sqlldr的运行
  • 如果只有一个数据文件,无法利用多个sqlldr实现并行加载

      如果能利用起Oracle本身的并行机制,那应该是一件高效并且简单的实现。只要想想Oracle投入了多少人力开发设计并行这个技术,想想并行技术在Oracle版本中的悠久历史,我们会毫不怀疑地相信并行技术的高效性,可扩展性与稳定性。

      并行技术的首要设计目标就是把所有可能空闲的系统资源利用起来。例如对于下面一个简单的查询

select *From big_table

      如果现在的系统有8个节点,每个节点有8个CPU,那么这时Oracle会启动8*8*parallel_threads_per_cpu =128个并行进程。每个进程负责扫描表big_table的1/128了。与串行执行相比,扫描时间理论上会缩小为1/128,“理论上”背后主要的潜台词就是系统没有IO瓶颈了。

       设想一下,如果这128个进程在扫描表的同时,把这些数据同时写到目标表中,这不就是我们所想要的并行文本导入功能吗?关键是找到一个途径,告诉这些并行进程在扫描的时候去扫描文本文件,而不是一个实实在在的内部表。

      这个途径,Oracle中以External Table的形式提供。这是把文本文件映射成Table的一种技术。利用这种技术,我们可以实现把对文本文件的读取操作,转换为对数据表的select操作。

     上面提到的就是利用Oracle本身的并行机制实现并行多节点导入数据的主要思路。至于具体的实现,可以直接参考官方文档The ORACLE_LOADER Access Driver,这一章详细解释了外部表的定义与使用。具体的例子可以参考Example: Creating and Loading an External Table Using ORACLE_LOADER。

     我们再深入一步,到目前为止,我们应该能够穷尽整个RAC系统所有节点的CPU处理能力,仅仅是“应该”而已。想像一种情况,如果导入文件系统的IO性能很差,不能足够快地提供上面提到的128个并行进程的读取操作,那么瓶颈就会出现在磁盘IO上了。按照我们的经验,128个进程甚至可以提供接近4GB/s的加载速度。要找到一个文件服务器提供这么高的带宽对于很多数据中心而言还是不现实的。

     解决方法在于减少对磁盘的IO量,一个马上想到的方法就是对并行进程读出的数据进行压缩。11g中,外部表定义引入了一个新的特性,叫做PREPROCESSOR,它可以实现对外部文件的预先处理,再把处理后得到的数据传送给Oracle内部进行加载。利用这个特性,我们可以实现对压缩文本文件的加载。具体而言,下面是官方文档中提到的一个例子:

Example 14-1 Specifying the PREPROCESSOR Clause

SQL> CREATE TABLE xtab (recno varchar2(2000))     2    ORGANIZATION EXTERNAL (     3    TYPE ORACLE_LOADER     4    DEFAULT DIRECTORY data_dir     5    ACCESS PARAMETERS (     6    RECORDS DELIMITED BY NEWLINE     7    PREPROCESSOR execdir:'zcat'     8    FIELDS (recno char(2000)))     9    LOCATION ('foo.dat.gz'))   10    REJECT LIMIT UNLIMITED;Table created.

假设gzip的压缩率为1:10,于是我们实现了把4GB/s的读取速度下降到400MB/s,另一方面,由于解压缩需要消耗一定的CPU,我们实现了用CPU换取IO的曲线救国。

 

可以看出,文本导入与文本导出其实存在着很多共性。实现高性能导入/导出的原则是一样的:

  • 充分利用起系统中的CPU与IO资源,直至其中一方成为瓶颈
  • 利用压缩技术消除可能存在的IO瓶颈

另一方面,关于并行技术,它不仅包括大家喜闻乐见的并行Query,并行DML;并行import,并行export其实也是并行技术用于数据仓库场合的重要方面。并行import和并行export,我想会在企业中的ODS系统中发挥重要作用

原创粉丝点击