Sqoop源码浅析
来源:互联网 发布:新郎接亲游戏知乎 编辑:程序博客网 时间:2024/06/16 06:12
前言
Apache Sqoop应该是在hadoop与SQL间上最常用的数据导入导出工具了。最近应为面试,简单看了一下sqoop 1.4.6的源码,整理如下。
驱动类——Sqoop
org.apache.sqoop.Sqoop是sqoop工具的启动类。
主要作用:
- 解析命令行传入的参数
- 根据参数调用相应的SqoopTool
工具类——SqoopTool
org.apache.sqoop.Sqoop.SqoopTool是一个抽象类,是所有SqoopTool的父类。它的类属性TOOLS里保存了所有SqoopTool的类对象。
主要作用:
1. 解析命令行传入的参数
2. 输出帮助信息
3. 完成具体功能
子类主要通过实现抽象方法public abstract int run(SqoopOptions options);
来实现功能。
下面详细介绍一下数据库导入工具类。
数据库导入工具类——ImportTool
org.apache.sqoop.tool.ImportTool是sqoop实现数据库导入功能的工具类。
ImportTool最核心的两个属性
protected ConnManager manager;private CodeGenTool codeGenerator;
manager负责所有查询数据库的操作。
codeGenerator负责将表结构映射为java类。
ImportTool的run方法
@Override /** {@inheritDoc} */ public int run(SqoopOptions options) { HiveImport hiveImport = null; if (allTables) { // We got into this method, but we should be in a subclass. // (This method only handles a single table) // This should not be reached, but for sanity's sake, test here. LOG.error("ImportTool.run() can only handle a single table."); return 1; } if (!init(options)) { return 1; } codeGenerator.setManager(manager); try { if (options.doHiveImport()) { hiveImport = new HiveImport(options, manager, options.getConf(), false); } // Import a single table (or query) the user specified. importTable(options, options.getTableName(), hiveImport); } catch (IllegalArgumentException iea) { LOG.error("Imported Failed: " + iea.getMessage()); if (System.getProperty(Sqoop.SQOOP_RETHROW_PROPERTY) != null) { throw iea; } return 1; } catch (IOException ioe) { LOG.error("Encountered IOException running import job: " + StringUtils.stringifyException(ioe)); if (System.getProperty(Sqoop.SQOOP_RETHROW_PROPERTY) != null) { throw new RuntimeException(ioe); } else { return 1; } } catch (ImportException ie) { LOG.error("Error during import: " + ie.toString()); if (System.getProperty(Sqoop.SQOOP_RETHROW_PROPERTY) != null) { throw new RuntimeException(ie); } else { return 1; } } finally { destroy(options); } return 0; } /** 1. Import a table or query. 2. @return true if an import was performed, false otherwise. */ protected boolean importTable(SqoopOptions options, String tableName, HiveImport hiveImport) throws IOException, ImportException { String jarFile = null; // Generate the ORM code for the tables. jarFile = codeGenerator.generateORM(options, tableName); Path outputPath = getOutputPath(options, tableName); // Do the actual import. ImportJobContext context = new ImportJobContext(tableName, jarFile, options, outputPath); // If we're doing an incremental import, set up the // filtering conditions used to get the latest records. if (!initIncrementalConstraints(options, context)) { return false; } if (options.isDeleteMode()) { deleteTargetDir(context); } if (null != tableName) { manager.importTable(context); } else { manager.importQuery(context); } if (options.isAppendMode()) { AppendUtils app = new AppendUtils(context); app.append(); } else if (options.getIncrementalMode() == SqoopOptions.IncrementalMode.DateLastModified) { lastModifiedMerge(options, context); } // If the user wants this table to be in Hive, perform that post-load. if (options.doHiveImport()) { // For Parquet file, the import action will create hive table directly via // kite. So there is no need to do hive import as a post step again. if (options.getFileLayout() != SqoopOptions.FileLayout.ParquetFile) { hiveImport.importTable(tableName, options.getHiveTableName(), false); } } saveIncrementalState(options); return true; }
在run方法中执行init(options)时,会根据命令行参数,利用org.apache.sqoop.ConnFactory生成对应的ConnManager对象。
在importTable方法中,codeGenerator会将表结构对应的java类写入jar文件。这个jar文件和其他选项会构造出一个ImportJobContext对象。
如果是增量模式,initIncrementalConstraints(options, context)会把IncrementalTestColumn的最大值保存在options.incrementalLastValue属性中,作为下一次增量的起点。
manager利用ImportJobContext对象中的信息完成表数据的导入。
manager完成importTable或importQuery后,程序再根据命令行参数选择将新数据追加到老数据、将新老数据合并或者将新数据导入hive。如果是增量任务,整个ImportTool对象会被保存到metastore。
连接类——ConnManager
org.apache.sqoop.manager.ConnManager是SqoopTool导入导出数据的核心类。它有3个子类:
- DummyManager——主要用于单元测试
- MainFrameManager——连接主机,目前只支持通过FTP协议
- SqlManager——连接各种支持JDBC连接的数据库
SqlManager
SqlManager查询数据库主要有两种方式:本地模式和分布式模式
本地模式即直接在当前JVM中查询,比如查询表的结构。
分布式模式下进行数据导入导出的查询,如表的导入导出。importTable()方法是一个典型的例子。
/** * Default implementation of importTable() is to launch a MapReduce job * via DataDrivenImportJob to read the table with DataDrivenDBInputFormat. */ public void importTable(com.cloudera.sqoop.manager.ImportJobContext context) throws IOException, ImportException { String tableName = context.getTableName(); String jarFile = context.getJarFile(); SqoopOptions opts = context.getOptions(); context.setConnManager(this); ImportJobBase importer; if (opts.getHBaseTable() != null) { // Import to HBase. if (!HBaseUtil.isHBaseJarPresent()) { throw new ImportException("HBase jars are not present in " + "classpath, cannot import to HBase!"); } if (!opts.isBulkLoadEnabled()){ importer = new HBaseImportJob(opts, context); } else { importer = new HBaseBulkImportJob(opts, context); } } else if (opts.getAccumuloTable() != null) { // Import to Accumulo. if (!AccumuloUtil.isAccumuloJarPresent()) { throw new ImportException("Accumulo jars are not present in " + "classpath, cannot import to Accumulo!"); } importer = new AccumuloImportJob(opts, context); } else { // Import to HDFS. importer = new DataDrivenImportJob(opts, context.getInputFormat(), context); } checkTableImportOptions(context); String splitCol = getSplitColumn(opts, tableName); importer.runImport(tableName, jarFile, splitCol, opts.getConf()); }
根据命令行参数的选项,数据将被导入HBase、Accumulo或者HDFS。
在DataDrivenImportJob的runImport方法中,可以看到MapReduce Job的构造和提交过程。
Job的InputFormat的默认类型是DataDrivenDBInputFormat。OutputFormat默认为null,使用hadoop默认的FileOutputFormat。MapperClass根据输出文件格式的不同而不同。可能的文件格式有纯文本、avro、parquet等。
HBaseImportJob、AccumuloImportJob是DataDrivenImportJob的子类。为了将数据导入HBase 和Accumulo,它们实现了不同的MapperClass和OutputFormat。
其他工具类
其他工具类的实现方式和ImportTool差不多,大部分应该比ImportTool简单。这里就不一一罗列了。
- Sqoop源码浅析
- Sqoop generated code浅析
- sqoop源码编译
- Sqoop源码分析(一) Eclipse调试Sqoop各种异常解决
- Sqoop源码编译与分析(V1.4.6)
- SQOOP
- Sqoop
- SQOOP
- SQOOP
- sqoop
- sqoop
- Sqoop
- sqoop
- sqoop
- sqoop
- Sqoop
- Sqoop
- sqoop
- 前序加中序求二叉树后序序列
- RecyclerView添加头部和尾部
- 1.ARM汇编基础
- 一点思考
- 我的首篇文章
- Sqoop源码浅析
- python算法——字符串表达式的计算
- [学习笔记]实时SLAM的未来及深度学习与SLAM对比
- js调试控制台使用详解图解
- DHCP详解
- PHP与MYSQL学习笔记--基础篇1
- 个人渗透笔记
- 简单编码
- 在vmware上安装centos7以及网络配置