S-JIS[2012-07-07] 変更履歴

Sqoop SQL関連ソース

Sqoop1.3.0のSQL関連ソース(内部実装)について。


import

import時にテーブル名を指定するとConnManager#importTable()、SQLを指定するとConnManager#importQuery()が呼ばれる。
ここではSqoopのSQLがどうなっているかを調べたいので、importTable()を追っていく。

  Manager ImportJob Mapper InputFormat
デフォルト SqlManager DataDrivenImportJob TextImportMapper
SequenceFileImportMapper
AvroImportMapper
DataDrivenDBInputFormat
MySQL MySQLManager      
DirectMySQLManager MySQLDumpImportJob MySQLDumpMapper MySQLDumpInputFormat
PostgreSQL PostgresqlManager      
DirectPostgresqlManager - - -
HSQLDB HsqldbManager      
Oracle OracleManager     OracleDataDrivenDBInputFormat
SQLServer SQLServerManager      
DB2 Db2Manager      

空欄は、デフォルトのクラスを使用していることを意味する。


DataDrivenDBInputFormat

importのデフォルトのInputFormat。

DataDrivenDBRecordReader

Oracle以外

SELECT カラム名,… FROM テーブル名 AS テーブル名 WHERE (条件) AND (分割カラム >= 最小値 AND 分割カラム < 最大値)

Oracle

SELECT カラム名,… FROM テーブル名 WHERE (条件) AND (分割カラム >= 最小値 AND 分割カラム < 最大値)

最小値・最大値はカラムのデータ型に応じてTextSplitterやDateSplitter等で決められる。


MySQLDumpMapper

MySQLのimportのダイレクトモード用Mapper。

データ分割方法は通常と同じだが、テーブルの読み込みは(SQLでなく)mysqldumpコマンドを使用する。

各Mapタスクでmysqldumpを実行して標準出力にデータを出力し、パイプで受け取ってMapperの出力としている。


DirectPostgresqlManager

PostgreSQLのimportのダイレクトモードはMapReduceを使わずに動作する。

psqlコマンドでCOPY文を実行する。
(sqoopコマンドのオプションで指定して場合はQUOTEやESCAPEの文字もCOPY文に指定される)

COPY (SELECT カラム名,… FROM テーブル名 WHERE 条件) TO STDOUT
WITH DELIMITER E'\054' CSV;

このCOPY文の結果は標準出力に出力されるので、それをパイプで受け取ってHDFS上のファイルに書き込んでいる。


OracleDataDrivenDBInputFormat

Oracle独自のデータ型があるからその処理を記述しているだけで、SQLとしてはDataDrivenDBInputFormatと同じ。


export

  Manager ExportJob Mapper OutputFormat
デフォルト SqlManager JdbcExportJob TextExportMapper
SequenceFileExportMapper
AvroExportMapper
バッチ以外…ExportOutputFormat
バッチモード…ExportBatchOutputFormat
MySQL MySQLManager      
DirectMySQLManager MySQLExportJob MySQLTextExportMapper
MySQLRecordExportMapper
NullOutputFormat
PostgreSQL PostgresqlManager      
DirectPostgresqlManager      
HSQLDB HsqldbManager      
Oracle OracleManager JdbcExportJob   ExportBatchOutputFormat
SQLServer SQLServerManager JdbcExportJob   ExportBatchOutputFormat
DB2 Db2Manager JdbcExportJob   ExportBatchOutputFormat

空欄は、デフォルトのクラスを使用していることを意味する。

PostgreSQLのexportはダイレクトモードに対応していないので、DirectPostgresqlManagerでも特別な処理は無い。

Oracle・SQLServer・DB2はマルチインサートの構文が無い(そして代替方式の実行効率が悪い?)為か、デフォルトモードでもバッチモードと同じ処理方式になる(ExportBatchOutputFormatが使われる)ようだ。


ExportOutputFormat

exportのデフォルトのOutputFormat。
(全てのRDBMSのデフォルトモードでこのOutputFormatが使われるわけではなく、ものによってはExportBatchOutputFormatが使われる)

ExportRecordWriter

INSERT INTO テーブル名 VALUES(?,…,?), (?,…,?), 〜, (?,…,?)

マルチインサート。
VALUESの後ろに複数のレコードを記述する方式。


ExportBatchOutputFormat

JDBCのPrepareStatementのaddBatch()・executeBatch()を使う方式。
基本的にはバッチモード(--batch)を指定すると このOutputFormatが使われるが、RDBMSの種類によってはデフォルトで使われる。

ExportBatchRecordWriter

INSERT INTO テーブル名 VALUES(?,…,?)

INSERT文自体は1レコードずつ書き込むタイプ。


MySQLExportMapper

MySQLのexportのダイレクトモード用Mapper。
実際にはMySQLExportMapperを継承したクラス(CSVファイルの場合はMySQLTextExportMapper、SequenceFileの場合はMySQLRecordExportMapper)が使われる。

各MapタスクでHDFSの内容をローカルファイルに書き出し、それをmysqlimportコマンドで読み込んでテーブルに書き込む。
(このローカルファイルに対しては、非同期で書き込み・読み込みを行う)


OracleExportOutputFormat

Oracleにはマルチインサートの構文が無いので、代わりのSQLが用意されている。
が、実際には使われていないようだ。

OracleExportRecordWriter

INSERT INTO テーブル名
SELECT ?,…,? FROM DUAL UNION ALL
SELECT ?,…,? FROM DUAL UNION ALL
〜
SELECT ?,…,? FROM DUAL

SQLServerExportOutputFormat

たぶんOracleと同様に、マルチインサートの構文が無いので代わりのSQLを用意しているのだと思う。
これも実際には使われていないようだ。

SQLServerExportRecordWriter

INSERT INTO テーブル名
SELECT ?,…,? UNION ALL
SELECT ?,…,? UNION ALL
〜
SELECT ?,…,?

Sqoopソースへ戻る / Sqoop目次へ戻る / Hadoopへ行く / 技術メモへ戻る
メールの送信先:ひしだま