Hive的数据迁移其实就是对Hive的数据进行导入导出的操作。如果数据表不是很多,我们可以直接使用Hive SQL来处理,一张一张表的导出,然后在进行导入。
对Hive的数据进行操作,常用的是登陆Hive客户端命令,常用的方式一般有两种,①hive,直接进入;②通过Beeline,在shell中输入beeline,然后连接我们的Hive,输入beeline> !connection jdbc:hive2://chd6:10000,提示我们输入用户名和密码,然后就可以在Beeline对Hive数据进行操作。
为什么没有采用直接将Hive在HDFS上的仓库中的库目录文件使用hadoop命令直接get到本地?
因为Hive数据库中的表有可能存在外表,如果采用这种备份方式,外表的数据将会丢失。如果确定了库中的数据均采用内表的方式,则可以用hadoop命令直接get到本地进行数据上的备份(表结构需要另外备份)。考虑到后期数据恢复,最好采用Hive提供的export/import工具实现进行备份,后期恢复时直接执行脚本即可。
INSERT OVERWRITE LOCAL DIRECTORY "路径"
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
SELECT 字段1,字段2,... FROM 表名;
其中路径可以写完整路径file:///root/my/data.txt,也可以简写为:/root/my/data.txt
INSERT OVERWRITE DIRECTORY "路径"
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
SELECT 字段1,字段2,... FROM 表名;
其中路径可以写完整路径 hdfs://namenode:8020/root/my/data.txt,也可以简写为:/root/my/data.txt
LOAD DATA LOCAL INPATH '/root/my/bookstore.txt' OVERWRITE INTO TABLE 表名;
从上面的过程我们也可以看到,当我们导入数据时表结构事先要建好存在的,需要我们用“desc 表名”命令查看表信息,用“ show partitions 分区表名”查看分区信息,然后将表在新环境中创建出来,比较麻烦,这种方式适合表比较少,表结构不是很复杂的表的迁移。
如果我们的表比较多,表结构有比较复杂时,可以使用Hive提供的export/import来进行数据的导入导出迁移我们的数据。
操作之前先要对我们的数据信息进行查询,方便我们对数据进行操作和验证。
2.1 备份前需要关注的信息查询
目的是查看需要备份数据的大概大小,保证在导入和导出时有足够的空间。便于指定迁移计划和步骤(空间不够时可能某些步骤需要拆分,分批次执行)
2.1.1 查看HDFS集群使用情况
hadoop dfsadmin -report
2.1.2 查看本地空间使用情况
df -lh
2.1.3 查找Hive在HDFS上仓库的位置
hadoop fs -find / -name warehouse
2.1.4 查看Hive仓库中各个库占用的大小
hadoop fs -du -h /user/hive/warehouse
2.1.4 查看Hive中的库和表
# 查询Hive库有,
show databases;
# 使用某个库
use 库名
# 查询某个库下的表,便于后期查看导出的数据表文件个数和表的个数是否能对应上
show tables;
# 如果这条命令报权限问题,那么需要先解决权限认证的问题,可查看下面的第三点解决
SELECT * FROM 表名 LIMIT 条数;
2.2 设置默认需要导出的hive库
vi ~/.hiverc
use 库名;
Esc键,:wq退出
2.3 在hdfs上创建数据临时目录
hadoop fs -mkdir /tmp/ds10
2.4 生成导出数据脚本
hive -e "show tables " | awk '{printf "export table %s to |/tmp/ds10/%s|;\n",$1,$1}' | sed "s/|/'/g" > ~/export.hql
2.5 导出数据到HDFS
hive -f ~/export.hql
2.6 下载HDFS数据到本地并传送到目标hadoop集群的/data/input_ds10 目录
先get到本地
hdfs dfs -get /tmp/ds10 /data/ds10/
将本地的/data/ds10的数据上传到新的大数据环境中,比如先拷贝到新环境本地的/data/input_ds10目录下。
将拷贝到本地/data/input_ds10目录下的数据上传好新环境的HDFS上
hdfs dfs -put /data/ds10 /tmp/ds10
2.7 构造导入语句
这一步在生成导出脚本的同样的目录下执行
cp export.hql import.hql
sed -i 's/export table/import table/g' import.hql
sed -i 's/ to / from /g' import.hql
2.8 设置导入到新换进下的默认库
方法同2.3步
2.9 导入数据
hive -f import.sql
真实环境下比测试环境要复杂的多,比如真实环境下对权限认证比较严格、数据量比较大、两个环境下的端口访问权限问题、scp在传输大文件时网络不稳定时的问题等。
生产环境下对权限管理比较严格,Hive表数据操作有时只能通过安全性更高的beeline使用给定的用户名和密码才能登入进行操作。Hive Cli模式下进入默认以当前用户为Hive的用户,一般没有权限查看表数据,只能查看表名和库名。这是执行2.5命令时就会报权限问题而不能导出数据的异常。
因此在Hive Cli模式下对于当前的用户必须要有读取表数据的权限才能将数据导出到HDFS上的临时文件,注意这里只能是HDFS上的路径,不能直接导出到本地。如果有管理员用户,直接将当前用户赋予SELECT权限即可,但是如果不知道超级管理员角色该怎么办?
这里可以用临时的方法解决,只需要在命令中加上一个参数,--hivevar hive.security.authorization.enabled=false可以在本次执行命令时临时关闭权限认证,完整的命令如下(-f后面跟的是导出的脚本文件):
hive --hivevar hive.security.authorization.enabled=false -f ~/export_ds10.hql
一般会使用scp直接发送到目标节点。因为发送的数据文件可能会很多,为防止频繁的输入密码,可以先临时配置下SSH免密,等数据迁移完毕之后可以再删除ssh免密配置,最好两个机器的用户名相同,先切换到相同的用户名下,比如都是hadoop用户,
# 1查看家目录下.ssh文件, 如果有id_rsa.pub可以跳过2
ls -a
# 2生产密钥
ssh-keygen -t rsa
# 3如果是初次可以直接执行ssh-copy-id -i ~/.ssh/id_rsa.pub hadoop@id,
# 但如果有已经有配置或SSH,又不想破坏,最好一步一步执行下面的步骤
# 3.1将id_rsa.pub发送到目标节点
scp -P端口号 ~/.ssh/id_rsa.pub hadoop@ip:~/
# 3.2SSH登陆目标节点,将公钥追加到.ssh/authorized_keys文件中
ssh -p端口号 hadoop@ip
cat ~/id_rsa.pub >> ~/.ssh/authorized_keys
如果迁移完毕后,恢复,删除上一步对这个用户的SSH
# 1 SSH登陆目标节点
ssh -p端口号 hadoop@ip
# 2 查看前面导入的公钥
cat ~/id_rsa.pub
# 3 在~/.ssh/authorized_keys中删除上面的一行的密钥
vim ~/.ssh/authorized_keys
dd删除2中相同字符的一行,Esc : wq 退出保存
如果不确定是不是一行,可以 :set number显示行号,在确定删除
数据量很大时,一个命令或者脚本可能要执行长时间,如果直接执行命令时中间断开那么就很悲催了,可能又要重新执行一遍,因此数据量很大时,可以将命令或者脚本后台执行,因此上面的命令可以修改为如下:
## 将hives仓库中的数据统一导出到HDFS上的临时目录
nohup hive --hivevar hive.security.authorization.enabled=false -f ~/export.hql>~/export.log 2>&1 &
## 将HDFS临时文件下的数据get到本地
nohup hdfs dfs -get /tmp/hive_export /data/ds10/>~/hdfs_get.log 2>&1 &
## 如果本地空间不够,可以分批次将数据get到本地(中间用空格分隔,最后一个是本次导出的本地位置,一定是个目录)
nohup hdfs dfs -get /tmp/hive_export/表目录1 /tmp/hive_export/表目录2 /tmp/hive_export/表目录3 /data/ds10/>~/hdfs_get.log 2>&1 &
## 将本地数据发送到目标节点
nohup scp -P端口号 -r /data/ds10/* 用户@ip:/data/ds10.db/ >scp_ds10.log 2>&1 &
每次后台执行一个命令时,会返回一个进程号,可以记下这个进程号,后面用 ps aux | grep 进程号 如果不存在可以确定后台进程已经执行完毕。
如果数据安全性比较高,可以对导出的数据加密压缩打包
tar -czvf - /data/ds10|openssl des3 -salt -k 密码 -out /data/input_ds10.tar.gz
解密(执行如下命令会提示输入密码)
openssl des3 -d -salt -in /data/input_ds10.tar.gz|tar xzf –