Sqoop 1.4.6 安装使用(自己总结)
JDK 安装
# 下载JDK8
wget --no-cookies --no-check-certificate --header \
"Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; oraclelicense=accept-securebackup-cookie" \
"http://download.oracle.com/otn-pub/java/jdk/8u241-b07/1f5b5a70bf22433b84d0e960903adac8/jdk-8u241-linux-x64.tar.gz" -P ~/
# 解压安装
sudo tar -xf jdk-8u241-linux-x64.tar.gz -C /usr/local/
# 配置~/.bashrc
echo -e '\n\n# JDK 1.8' >> ~/.bashrc
echo 'export JAVA_HOME=/usr/local/jdk1.8.0_241' >> ~/.bashrc
echo 'export JRE_HOME=${JAVA_HOME}/jre' >> ~/.bashrc
echo 'export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib' >> ~/.bashrc
echo 'export PATH=$PATH:${JAVA_HOME}/bin' >> ~/.bashrc
# 应用设置
source ~/.bashrc
# 测试效果
java -version
#java version "1.8.0_241"
#Java(TM) SE Runtime Environment (build 1.8.0_241-b07)
#Java HotSpot(TM) 64-Bit Server VM (build 25.241-b07, mixed mode)
# 清理残余
rm jdk-8u241-linux-x64.tar.gz
Sqoop 安装
# 下载
wget http://archive.apache.org/dist/sqoop/1.4.6/sqoop-1.4.6.bin__hadoop-2.0.4-alpha.tar.gz
# 解压
tar -xf sqoop-1.4.6.bin__hadoop-2.0.4-alpha.tar.gz -C /opt/modules
cd /opt/modules/ && mv sqoop-1.4.6.bin__hadoop-2.0.4-alpha sqoop-1.4.6
rm -rf /opt/modules/sqoop-1.4.6/*/*.cmd # 清理无用的.cmd 文件
# 配置
wget https://repo1.maven.org/maven2/mysql/mysql-connector-java/5.1.44/mysql-connector-java-5.1.44.jar -P /opt/modules/sqoop-1.4.6/lib
cat > /opt/modules/sqoop-1.4.6/conf/sqoop-env.sh << 'EOF'
export HADOOP_COMMON_HOME=/opt/modules/hadoop-2.7.2
export HADOOP_MAPRED_HOME=/opt/modules/hadoop-2.7.2
EOF
# 检验
cd /opt/modules/sqoop-1.4.6 && bin/sqoop help # 会提示某些组件没有安装,用不着没事
## 连接MySQL 列出所有的数据库
bin/sqoop list-databases --connect jdbc:mysql://hadoop112:3306 --username root --password root
Sqoop 使用
对应Sqoop而言,导入特指从关系型数据库导入大数据集群,反之即为导出。
如果Hadoop
配置了YARN
则需要将其开启,Sqoop
运行过程中需要调用MapReduce
,其资源由YARN
分配。
本实验没有配置YARN
,仅开启了HDFS
,但不开YARN
则不方便看MapReduce
的日志。
数据准备
RDBMS(MySQL)
# 安装MySQL
## 更新Apt 并安装,可装在本机
sudo apt-get update
sudo apt-get install -y mysql-server # 需设置root 用户密码,这里设为root
## 取消地址绑定,即本机的任何地址都可以连上来
sudo sed -i 's/bind-address/#bind-address/' /etc/mysql/my.cnf
## 允许远程root 用户登录
mysql -u root -proot -e \
"grant all on *.* to root@'%' identified by 'root' with grant option; \
flush privileges; "
## 重启MySQL 服务
sudo service mysql restart
# 创建数据
## 注意:-p后面紧跟密码,不能有空格
mysql -h localhost -u root -proot -e 'create database company;'
## 使用匿名文件Here Docs 创建数据
mysql -h localhost -u root -proot << 'EOF'
create table company.staff (
id int(4) primary key not null auto_increment,
name varchar(255),
sex varchar(255));
insert into company.staff(name, sex) values('Thomas', 'Male'), ('Catalina', 'FeMale');
EOF
## 检验一下表格及数据是否创建成功
mysql -h localhost -u root -proot -D company -e 'show tables; select * from staff;'
HDFS(单机版)
# 下载
wget https://archive.apache.org/dist/hadoop/common/hadoop-2.7.2/hadoop-2.7.2.tar.gz
# 解压
sudo mkdir -p /opt/modules
sudo chown -R `id -u`:`id -g` /opt/modules # 赋予当前用户修改该目录的权限
tar -xf hadoop-2.7.2.tar.gz -C /opt/modules
# 删除多余的cmd 文件,Linux 下不需要
rm -rf /opt/modules/hadoop-2.7.2/bin/*.cmd
rm -rf /opt/modules/hadoop-2.7.2/sbin/*.cmd
rm -rf /opt/modules/hadoop-2.7.2/etc/hadoop/*.cmd
# 配置
## 1. hadoop-env.sh,修改JAVA_HOME 路径
sed -i 's#=${JAVA_HOME}#=/usr/local/jdk1.8.0_241#' \
/opt/modules/hadoop-2.7.2/etc/hadoop/hadoop-env.sh
## 2. core-site.xml
cat > /opt/modules/hadoop-2.7.2/etc/hadoop/core-site.xml << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<!-- 指定HDFS 中NameNode 的地址 -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://localhost:9000</value>
</property>
<!-- 指定Hadoop 运行时产生文件的存储目录 -->
<property>
<name>hadoop.tmp.dir</name>
<value>/opt/modules/hadoop-2.7.2/data/tmp</value>
</property>
</configuration>
EOF
## 3. hdfs-site.xml
cat > /opt/modules/hadoop-2.7.2/etc/hadoop/hdfs-site.xml << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<!-- 指定文件在HDFS 中的副本数 -->
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
</configuration>
EOF
# 启动
## 1. 格式化`NameNode`,仅在初始化时执行一次。
### 前面将数据文件设置在data 目录下,先清空再格式化
cd /opt/modules/hadoop-2.7.2
rm -rf data/ logs/ && bin/hdfs namenode -format
### 出现Exiting with status 0 字样表示格式化成功
## 2. 启动HDFS
### 统一启动,NameNode、DataNode、SecondaryNameNode 一起
cd /opt/modules/hadoop-2.7.2 && sbin/start-dfs.sh
RDBMS 到HDFS
全量导入
# 场景需求
## 全量从company 数据库的staff 表导入到HDFS 的/user/company 目录,以制表符分隔字段
## 启动一个MR 进程,--delete-target-dir 如HDFS 输出目录已存在则先删除,注意!!生产中千万不要这么做
cd /opt/modules/sqoop-1.4.6 &&\
bin/sqoop import \
--connect jdbc:mysql://hadoop112:3306/company \
--username root \
--password root \
--table staff \
--target-dir /user/company \
--delete-target-dir \
--num-mappers 1 \
--fields-terminated-by "\t"
查询导入
cd /opt/modules/sqoop-1.4.6 &&\
bin/sqoop import \
--connect jdbc:mysql://hadoop112:3306/company \
--username root \
--password root \
--target-dir /user/company \
--delete-target-dir \
--num-mappers 1 \
--fields-terminated-by "\t" \
--query 'select name,sex from staff where id <=1 and $CONDITIONS;'
# 不使用--table 指定表,而是用--query,注意$CONDITIONS 必须原样写上,它不是shell 变量
# $CONDITIONS 的作用是当导入使用多个MapReduce 同时工作时让结果文件的记录跟原表的顺序一致
指定列导入
cd /opt/modules/sqoop-1.4.6 &&\
bin/sqoop import \
--connect jdbc:mysql://hadoop112:3306/company \
--username root \
--password root \
--table staff \
--target-dir /user/company \
--delete-target-dir \
--num-mappers 1 \
--fields-terminated-by "\t" \
--columns id,sex
# --columns 指定导入哪些列,逗号间隔,列名间不能有空格
关键字筛选导入
cd /opt/modules/sqoop-1.4.6 &&\
bin/sqoop import \
--connect jdbc:mysql://hadoop112:3306/company \
--username root \
--password root \
--target-dir /user/company \
--delete-target-dir \
--num-mappers 1 \
--fields-terminated-by "\t" \
--table staff \
--where "id=1"
# --where 是Sqoop 的关键字,效果跟SQL 里写where 一样,两者只能选其一
HDFS 到RDBMS
# 1. 创建本地数据文件
cat > /tmp/ddd << 'EOF'
Thomas1 Male
Thomas2 Male
Thomas3 Male
EOF
# 2. 上传到HDFS
cd /opt/modules/hadoop-2.7.2/
## 创建HDFS 目录
bin/hdfs dfs -mkdir -p /user/abc/results/
## 上传前先删除,为了能多次上传
bin/hdfs dfs -rm /user/abc/results/ddd
bin/hdfs dfs -put /tmp/ddd /user/abc/results/
# 3. 从HDFS 导入MySQL
## 注意:如果MySQL 中表不存在须先手动创建
## 由于staff 表中id 是自增主键,所以我们指定导入的列为name,sex
cd /opt/modules/sqoop-1.4.6 &&\
bin/sqoop export \
--connect jdbc:mysql://hadoop112:3306/company \
--username root \
--password root \
--table staff \
--columns name,sex \
--num-mappers 1 \
--export-dir /user/abc/results/ \
--input-fields-terminated-by " "
## --input-fields-terminated-by <char> 设置一个字符作为字段间的分隔符
## 注意!!输入的数据文件严格按照该字符分隔字段,且只能按照这个一个字符来分隔
# 4. 检查MySQL 中的数据
mysql -h hadoop112 -u root -proot -e 'select * from company.staff;'
## 如果数据有误请检查HDFS 上的文件和导出参数,特别是分隔符
执行Sqoop 脚本
使用Sqoop 脚本
放在crontab
里面作为定时任务。这里以之前的导出例子为例。
# 编写脚本,习惯使用opt 后缀名
cat > /opt/modules/sqoop-1.4.6/hdfs2mysql.opt << 'EOF'
export
# 每个参数换一行,参数值在下一行
--connect
jdbc:mysql://hadoop112:3306/company
--username
root
--password
root
--table
staff
--columns
name,sex
--num-mappers
1
--export-dir
/user/abc/results/
--input-fields-terminated-by
" "
EOF
# 执行脚本
cd /opt/modules/sqoop-1.4.6 && bin/sqoop --options-file hdfs2mysql.opt
# 4. 检查MySQL 中的数据
mysql -h hadoop112 -u root -proot -e 'select * from company.staff;'