hadoop16--sqoop

大數據協作框架

在hadoop生態領域中, 協作框架主要分爲以下四種:

  1. sqoop: 關係型數據庫導入, 導出到HDFS, HIVE, HBASE
  2. flume: 日誌收集框架, 主要收集日誌服務器上產生的文件
  3. oozie: 任務調度框架, 在YARN上提交的任務有很多, 每個任務什麼時候運行, 該如何運行, 都是需要調度的
  4. hue: 可視化工具

sqoop 框架功能與版本介紹

sqoop功能

sqoop是一個從關係型數據庫中導入到HDFS上, 或者從HDFS上導出到mysql中數據的一種工具. sqoop中底層跑的是MR程序, 其實就是MR程序的一種封裝. 在sqoop中封裝的MR程序只存在map輸出 , 沒有reduce輸出. 所以說sqoop是基於hadoop之上的數據導入導出工具

sqoop版本

sqoop分爲兩個版本, sqoop1和sqoop2

sqoop2

由客戶端與服務器端一起運行, 類似於hiveserver2 與 beeline之間的關係, 由於涉及到了客戶端與服務器端就牽扯到了網絡IO以及網絡穩定, 並且會跨節點執行, 穩定性較差, 不推薦使用

sqoop1

sqoop1是純客戶端模式, 比較穩定, 推薦使用

sqoop部署安裝

  1. 解壓sqoop安裝包
sudo tar -zxvf sqoop-1.4.6.bin__hadoop-2.0.4-alpha.tar.gz -C /opt/app/
  1. 修改配置sqoop環境配置文件名(env)
//0. 修改文件權限
sudo chown -R hadoop:hadoop sqoop-1.4.6.bin__hadoop-2.0.4-alpha/

//1. 修改conf/sqoop-env-template.sh --> sqoop-env.sh
mv sqoop-env-template.sh sqoop-env.sh
  1. 修改配置sqoop環境配置
#Set path to where bin/hadoop is available
export HADOOP_COMMON_HOME=/opt/app/hadoop-2.7.2

#Set path to where hadoop-*-core.jar is available
export HADOOP_MAPRED_HOME=/opt/app/hadoop-2.7.2

#Set the path to where bin/hive is available
export HIVE_HOME=/opt/app/apache-hive-1.2.1-bin
  1. sqoop 是和關係型數據庫進行導入和導出的, 所以需要用到jdbc的jar包, 所以需要把jdbc的jar包拷貝到sqoop目錄的lib目錄下
cp apache-hive-1.2.1-bin/lib/mysql-connector-java-5.1.31.jar sqoop-1.4.6.bin__hadoop-2.0.4-alpha/lib/
  1. 測試sqoop配置是否成功—在sqoop的目錄下執行bin/sqoop help 可以查看sqoop常用的命令
bin/sqoop help
-----------------
Available commands:
  codegen            Generate code to interact with database records
  create-hive-table  Import a table definition into Hive
  eval               Evaluate a SQL statement and display the results
  export             Export an HDFS directory to a database table
  help               List available commands
  import             Import a table from a database to HDFS
  import-all-tables  Import tables from a database to HDFS
  import-mainframe   Import datasets from a mainframe server to HDFS
  job                Work with saved jobs
  list-databases     List available databases on a server
  list-tables        List available tables in a database
  merge              Merge results of incremental imports
  metastore          Run a standalone Sqoop metastore
  version            Display version information

list-databases: 列出數據庫

  1. 連接數據庫—使用sqoop中連接數據庫, 並且顯示數據庫參數, 測試sqoop連接數據庫
bin/sqoop list-databases --connect jdbc:mysql://localhost:3306 --username root --password root
----------------------------------------------------------
resultset.
information_schema
metastore
mysql
performance_schema
test

​ 另一種寫法: 使用\ 可以換行, 代表一行命令沒有結束

bin/sqoop list-databases \
--connect jdbc:mysql://localhost:3306 \
--username root \
--password root
---------------------------
resultset.
information_schema
metastore
mysql
performance_schema
test

sqoop導入命令

把關係型數據庫中的數據導入到HDFS上, 首先必須鏈接到關係型數據庫中.

  1. 首先在關係型數據庫中建立一張表
create table tohdfs(
	id int primary key not null,
	name varchar(20) not null
);
Query OK, 0 rows affected (0.15 sec)

mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| tohdfs         |
+----------------+
1 row in set (0.00 sec)

  1. 向測試表中添加測試數據
mysql> insert into tohdfs(id ,name)values(1,"zhangsan");
Query OK, 1 row affected (0.04 sec)

mysql> insert into tohdfs(id ,name)values(2,"lisi");
Query OK, 1 row affected (0.04 sec)
  1. 編寫sqoop命令, 從mysql到HDFS
bin/sqoop import \
--connect jdbc:mysql://localhost:3306/test \
--username root \
--password root \
--table  tohdfs

​ 導入命令執行完畢之後默認路徑爲/user/hadoop/

導入存在的問題

  1. 在數據庫中每條記錄就作爲一個map運行導入
  2. 導入到hdfs上的一個數據沒有自定義指定路徑

解決問題

  1. 數據導出到指定的路徑–通過參數–target-dir 可以指定關係型數據庫導入到hdfs上的指定路徑
bin/sqoop import \
--connect jdbc:mysql://localhost:3306/test \
--username root \
--password root \
--table  tohdfs \
--target-dir /tohdfs 
  1. 數據導出並指定map任務的並行執行數量–通過–num-mappers 設置map任務的並行運行數量
bin/sqoop import \
--connect jdbc:mysql://localhost:3306/test \
--username root \
--password root \
--table  tohdfs \
--target-dir /tohdfs2 \
--num-mappers 1

對於以上的兩個問題, 已經解決了, 但是每次導入數據的時候都要求刪除文件夾, 在sqoop中存在一個參數, 能夠在導入之前刪掉之前的目標文件夾

–delete-target-dir : 如果目標路徑存在則刪除

bin/sqoop import \
--connect jdbc:mysql://localhost:3306/test \
--username root \
--password root \
--table  tohdfs \
--delete-target-dir \
--target-dir /tohdfs2 \
--num-mappers 1

在sqoop導入到hdfs上的默認分隔符默認爲" ," , 同時也可以在導入的時候指定分隔符

–fields-terminated-by Sets the field separator character

bin/sqoop import \
--connect jdbc:mysql://localhost:3306/test \
--username root \
--password root \
--table  tohdfs \
--fields-terminated-by '\t' \
--delete-target-dir \
--target-dir /tohdfs2 \
--num-mappers 1

sqoop增量導入

在隨着系統的運作, 每天都會產生新的數據, 在進行數據導入的時候, 由於之前已經導入過數據, 所以在產生新的數據的時候, 就可以直接在之前導過的數據的基礎之上繼續導入數據, 沒有必要將之前的數據再次導入一遍.

增量導入參數: bin/sqoop import --help

Incremental import arguments:
   --check-column <column>        Source column to check for incremental
                                  change
   --incremental <import-type>    Define an incremental import of type
                                  'append' or 'lastmodified'
   --last-value <value>           Last imported value in the incremental
                                  check column

增量導入參數

  1. –check-column : 檢查列, 檢查數據庫中的索引列, 一般都是數據表中的主鍵.
  2. –incremental : 增量導入的類型
    ​ 1. append: 追加
    ​ 2. lastmodified: 最後一次修改的時間
  3. –last-value 最後值, 從給定上次導入索引的最後值, 在導入新數據的時候, 從最後值的下一個記錄開始導入

增量導入數據的使用:

bin/sqoop import \
--connect jdbc:mysql://localhost:3306/test \
--username root \
--password root \
--table  tohdfs \
--fields-terminated-by '\t' \
--target-dir /tohdfs2 \
--num-mappers 1 \
--check-column id \
--incremental append \
--last-value 2

在進行增量導入的時候, 首先需要注意, 之前的刪除文件夾的參數, 本身與增量導入是衝突的, 所以在增量導入的時候不能加入刪除指定目錄的參數

由於hdfs的特點, 不能修改 , 所以在追加導入的時候, hdfs會創建新的文件來保存追加的內容

sqoop job

sqoop job可以理解爲創建一個模板, 在下次運行導入或者導出任務的時候, 直接運行的模板就可以執行任務. 可以理解爲把需要操作的任務封裝爲一個方法, 之後運行這個方法名稱就可以運行封裝好的任務.

使用job

  1. 查看job的信息
bin/sqoop job --help
  1. 通過查看job的信息得到以下的內容
Job management arguments:
   --create <job-id>            Create a new saved job
   --delete <job-id>            Delete a saved job
   --exec <job-id>              Run a saved job
   --help                       Print usage instructions
   --list                       List saved jobs
   --meta-connect <jdbc-uri>    Specify JDBC connect string for the
                                metastore
   --show <job-id>              Show the parameters for a saved job
   --verbose                    Print more information while working
  1. 創建一個job
bin/sqoop job \
--create stu_info \
-- \
import \
--connect jdbc:mysql://localhost:3306/test \
--username root \
--password root \
--table  tohdfs \
--fields-terminated-by '\t' \
--target-dir /tohdfs2 \
--num-mappers 1 \
--check-column id \
--incremental append \
--last-value 2
  1. 查看已經創建過的job(–list)
bin/sqoop job --list
------------------------
Available jobs:
  stu_info
  1. 查看job的詳細信息
bin/sqoop job --show stu_info
----------------------------
Options:
----------------------------
verbose = false
incremental.last.value = 2
db.connect.string = jdbc:mysql://localhost:3306/test
codegen.output.delimiters.escape = 0
codegen.output.delimiters.enclose.re
...	...
codegen.compile.dir = /tmp/sqoop-hadoop/compile/9ce5792bc31f0ba35d2a3823452d6d7a
direct.import = false
hdfs.target.dir = /tohdfs2
hive.fail.table.exists = false
db.batch = false
  1. 執行job任務(需要輸入mysql密碼進行驗證)
bin/sqoop job --exec stu_info
  1. 刪除job任務
bin/sqoop job --delete stu_info

將mysql的數據導入到hive中

將數據導入到hive中, 但是實際上來說, hive中的數據也是在hdfs上來保存的, 在進行導入hive的本質其實就是先把數據導入到hdfs中, 再從hdfs上把數據遷移到hive表所在的hdfs路徑

  1. 在hive中準備要導入的數據庫以及數據表
create database student;
use student;
create table stu_info(id int , name string) row format delimited fields terminated by '\t';
  1. 導入到hive中
bin/sqoop import \
--connect jdbc:mysql://localhost:3306/test \
--username root \
--password root \
--table  tohdfs \
--hive-import \
--hive-database student \
--hive-table stu_info \
--target-dir /tohdfs3 \
--fields-terminated-by '\t' \
--num-mappers 1

sqoop導出

以hdfs爲標準, 導出到關係型數據庫

  1. 在mysql中準備接收的數據表
create table tomysql(
id int primary key not null,
name varchar(20) not null
);
  1. 通過bin/sqoop export --help 查詢參數
Common arguments:
   --connect <jdbc-uri>                         Specify JDBC connect
                                                string
   --connection-manager <class-name>            Specify connection manager
                                                class name
   --connection-param-file <properties-file>    Specify connection
                                                parameters file
   --driver <class-name>                        Manually specify JDBC
                                                driver class to use
   --hadoop-home <hdir>                         Override
                                                $HADOOP_MAPRED_HOME_ARG
   --hadoop-mapred-home <dir>                   Override
                                                $HADOOP_MAPRED_HOME_ARG
   --help                                       Print usage instructions
... ...
   --hive-partition-value <partition-value>         Sets the partition
                                                    value to use when
                                                    importing to hive
   --map-column-hive <arg>                          Override mapping for
                                                    specific column to
                                                    hive types.
  1. 導出數據到關係型數據庫中mysql(不用使用分隔符)
bin/sqoop export \
--connect jdbc:mysql://localhost:3306/test \
--username root \
--password root \
--table tomysql \
--export-dir /tohdfs \
--num-mappers 1 

日誌分析

對一個網站的日誌進行分析, 得到兩個指標, pv和uv, 將分析出來的結果導入到mysql進行保存

操作步驟

  1. 在hive中創建一個用於分析網站指標的數據庫
create database log;
  1. 在數據庫中創建源數據表, 加載數據
use log;
create table log_source(
id              string,
url             string,
referer         string,
keyword         string,
type            string,
guid            string,
pageId          string,
moduleId        string,
linkId          string,
attachedInfo    string,
sessionId       string,
trackerU        string,
trackerType     string,
ip              string,
trackerSrc      string,
cookie          string,
orderCode       string,
trackTime       string,
endUserId       string,
firstLink       string,
sessionViewNo   string,
productId       string,
curMerchantId   string,
provinceId      string,
cityId          string,
fee             string,
edmActivity     string,
edmEmail        string,
edmJobId        string,
ieVersion       string,
platform        string,
internalKeyword string,
resultSum       string,
currentPage     string,
linkPosition    string,
buttonPosition  string
)
row format delimited fields terminated by '\t'
stored as textfile;
  1. 加載數據到源數據表中
load data local inpath '/home/hadoop/data/201808.txt' into table log_source;
load data local inpath '/home/hadoop/data/201809.txt' into table log_source;
  1. 數據加載完成, 創建臨時表, 導出需要用到分析的字段與數據
create table log_qingxi
(
 id string ,
 url string,
 guid string,
 day string,
 hour string
)
row format delimited fields terminated by '\t';
  1. 創建完成後, 從源數據表中導入數據到清洗表中
insert into table log_qingxi select id,url,guid,substring(trackTime,9,2) day,substring(trackTime,12,2) hour from log_source;
  1. 將清洗表中的數據導入到分析的臨時表中進行分區處理, 創建臨時分區表
create table log_part1
(
 id string ,
 url string,
 guid string
)
partitioned by(day string,hour string)
row format delimited fields terminated by '\t';
  1. 導入數據到分區表中
insert into table log_part1 partition(day='20150828',hour='18')
select id,url,guid from log_qingxi where day='28' and hour='18';

insert into table log_part1 partition(day='20150828',hour='19')
select id,url,guid from log_qingxi where day='28' and hour='19';
  1. 統計pv和uv
//統計pv
select day,hour,count(url) pv from log_part1 where not url="" group by day,hour ;
 OK
day     hour    pv
20150828        18      35880
20150828        19      33317

//統計uv
select day,hour,count(distinct guid) uv from log_part1 group by day,hour;
OK
day     hour    uv
20150828        18      23938
20150828        19      22330
  1. 創建將要輸出的結果表
create table result as select day,hour,count(url) pv ,count(distinct guid) uv from log_part1 where not url="" group by day,hour;
OK
result.day      result.hour     result.pv       result.uv
20150828        18      35880   16068
20150828        19      33317   14590
  1. 在mysql中創建需要接收數據的數據表
create table save(
day varchar(30) not null,
hour varchar(30) not null,
pv varchar(30) not null,
uv varchar(30) not null,
primary key(day,hour)
);
  1. 利用sqoop實現導出到mysql命令
bin/sqoop export \
--connect jdbc:mysql://hadoop:3306/test \
--username root \
--password root \
--table save \
--export-dir /user/hive/warehouse/log.db/result \
--num-mappers 1 \
--input-fields-terminated-by '\001'
  1. 轉到mysql查看結果
mysql> select * from save;
+----------+------+-------+-------+
| day      | hour | pv    | uv    |
+----------+------+-------+-------+
| 20150828 | 18   | 35880 | 16068 |
| 20150828 | 19   | 33317 | 14590 |
+----------+------+-------+-------+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章