在迁移hdfs和hive之前我首先想到的是,是不是可以直接拷贝文件夹呢?毕竟hdfs文件实际都是存储在设定的dir中,hive的元数据也都在mysql里头,备份再恢复一下简直是so easy啊!好吧,这篇文章就是用来填上这个想法背后的各种坑的,也顺便回顾一下部分相关环境配置的过程。
一、 准备工作
首先需要在新的虚拟机上完成运行hadoop的必备工作,以下操作主机和从机都要执行。
1. 创建hadoop用户及相关配置
使用root用户登录vm,或使用su切换到root,执行下述命令
useradd -m hadoop #新建hadoop账户
passwd hadoop #设置密码
然后在/etc/sudoers中添加下面这句
%hadoop ALL=(ALL) NOPASSWD: ALL
使hadoop用户可以免密使用sudo命令提升权限,提示找不到sudo命令的话就使用yum install sudo来安装(centos中)。
2. SSH配置
为了让hadoop运行起来时不用频繁的输入密码,所以需要为主机和从机分别生成对称密钥,并添加到公钥名单中。
su - hadoop # 切换到hadoop账户并切换到其home目录
ssh-keygen -t dsa #dsa生成方式安全性更高,选择默认的目录即可,如果要免密就不要填写密码短语
cat id_rsa.pub >> authorized_keys # 将本机公钥写入公钥名单,hdfs启动时会ssh登录本机
sudo chmod 700 ~/.ssh # 修改文件权限,否则免密无法生效
接下来使用下述命令将主机的公钥依次远程复制到从机的公钥名单中
ssh-copy-id -i ~/.ssh/id_dsa.pub 从机IP
此时便可以使用ssh免密登录本机和远程主机了。
3. 环境变量配置
环境变量的配置和当初部署时一样,直接从之前的.bash_profile或.bashrc中复制过来即可,如JAVA_HOME、JAVA_BIN、CLASSPATH、HADOOP_HOME、HIVE_HOME、PATH等。当然java环境自然需要先配好,具体教程百度有很多。
4. HOSTNAME修改
为了省去每次填写ip的麻烦我们需要修改主机和从机的hostname
su
hostname 你的主机名
# 或者在/etc/sysconfig/network中修改(没有这行就自己增加):
HOSTNAME=你的主机名
重启
然而我的vm并不允许重启,第一种办法一直提示需要root(已经是root了),所以我们可以用更简单粗暴的方式来达到同样的效果——修改hosts
sudo vim /etc/hosts
加入:
主机IP master # 主机hostname
从机IP slave1 # 从机1的hostname
... # 所有从机都要设置
本机IP 当前hostname # 重要
虽然hosts修改的是本地dns解析的结果,但是和修改hostname达到的效果是一样的。
最后别忘了修改主机hadoop中的slaves文件,把需要当从机的hostname都修改成新的。
二、 Hdfs (NameNode & DataNode) 迁移
1. 停止服务
迁移前请在原先的主机上停止hdfs和yarn的服务,如果有其他相关服务也需要都停止。
stop-dfs.sh
stop-yarn.sh
如果你没有将hadoop/sbin目录配置到PATH的话,需要切到该目录下执行sh,之后执行的一些shell脚本也同理。
2. 复制hadoop文件夹、hdfs数据文件夹、元数据文件夹
1)首先将hadoop文件夹进行远程复制,主机复制到主机,从机复制到从机
scp -r hadoop root@接收方hostname:/usr/local
我通常将hadoop文件夹放在/usr/local下,所以需要指定对方的root账户,否则权限不够,注意这儿会要求输入接收方的root密码。这儿使用的是整个文件夹复制的方式,推荐还是使用tar打包后再用scp传输,然后解压。
在收到hadoop文件夹后需要恢复文件夹的所有者为hadoop
cd /usr/local
sudo chown -R hadoop:hadoop hadoop/
2)复制hdfs数据文件夹和元数据文件夹
两个文件夹的路径都是在hdfs-site.xml中配置过的
<property>
<name>dfs.namenode.name.dir</name>
<value>file:/usr/local/hadoop/tmp/dfs/name</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>file:/usr/local/hadoop/tmp/dfs/data</value>
</property>
dfs.namenode.name.dir配置了元数据的文件夹路径,元数据(fsimage和edits)只在namenode中记录,datanode.name.dir则是保存了所有数据块的文件夹,这儿的复制方式和上述的一样,不要忘了chown。由于我都设置在了hadoop文件夹里,所以在上一步中就连带着复制过去了。
3)修改hdfs和yarn配置
更新slaves文件(在主机上),以及hdfs-site.xml 、core-site.xml、mapred-site.xml、yarn-site.xml等文件中所有的ip设置,如果之前都是用hostname设置的那就不用修改了(hosts里已经设置了对应关系了),建议都换成使用hostname设置。
注意:如果修改了JAVA_HOME,那么hadoop/etc/hadoop下的hadoop-env.sh里的JAVA_HOME也需要修改,这儿必须写完整路径,不知为什么这个脚本跑的时候获取不到系统环境变量。
3. 启动hdfs
到这儿NameNode和DataNode的迁移工作就都完成了,开启下hdfs和yarn服务看下效果
start-dfs.sh
stat-yarn.sh
如果出现问题就去hadoop/logs目录下看对应的log信息。
三、 Hive迁移
hive的迁移的重点在元数据mysql的迁移,如果你存放元数据的mysql在远程服务器上且无需迁移,那么就跳过这一Part吧。然而我的mysql布在了主机上……1. 迁移hive文件夹
过程和迁移hadoop文件夹一样,使用scp后用chown修改所有者。
hive-site.xml中的相关配置如果有变动那也得更新一下。
2. 迁移保存hive元数据的mysql
1) 安装mysql
使用su把用户切到root,在新vm安装mysql(服务器、客户端、lib),具体的安装过程和my.cnf配置百度都有。
2) mysql配置
启动mysql服务,登录mysql,修改root的密码,授权等
service mysql start # 启动服务,5.1版本要换成mysqld
chkconfig mysql on # 开机自启动
mysql # 先用''@localhost登录无需密码
use mysql; -- 切换数据库
UPDATE user SET password=PASSWORD('password') WHERE user='root'; -- 设置root的密码
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost'; -- root本地授权
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' identified by '123'; -- 对root进行远程授权,%表示针对所有远程IP,远程登录密码为123
insert into mysql.user (Host,User,Password) values ("localhost","hive",password ("hive")); -- 创建hive用户
create database hive; -- 创建hive数据库,对应hive-site.xml中的配置
grant all on hive.* to hive@'%' identified by 'hive';
grant all on hive.* to hive@'localhost' identified by 'hive';
flush privileges;
exit;
防火墙可以选择关闭,或者添加3306端口规则,然后重启防火墙。这时就可以使用root远程登录mysql了,配置mysql中出现的任何denied问题大都是权限问题,为此我还查了一堆资料,其实只要针对提示的用户@主机,用mysql直接进入client对其grant all 就行。
3)备份与恢复
// 对原mysql备份,最后不要加分号
mysqldump -u username -p [-B] 数据库名 [table1 table2 ...] > backup.sql
-u 指定用户,-p手动输入密码,-B用于导出建库语句但是不可跟表名,如果不写后面的表名就备份所有表。对于hive库需要使用hive用户备份,还有一些--all-databases之类的备份所有数据库的指令可以自行研究。然后使用scp将backup.sql远程复制到新主机上。
// 在新的主机上恢复
mysql -u username -p [数据库名] < backup.sql
不带-B参数生成备份文件应该是没有建库语句的,所以需要先手动创建要导入的数据库,使用mysql-gui或者自己create也行。
4)修改hive元数据中的路径
mysql迁移过来后,你会发现没法启动hive,因为保存在mysql里头的元数据把数据地址写死了。好,打开表DBS和表SDS,注意是两张表。
将表DBS里头DB_LOCATION_URI字段里的所有原IP都换成主机namenode的IP,表SDS则是修改LOCATION字段。
里头要替换的行可能很多,这儿介绍一个快捷的办法,使用软件远程连接或用mysqldump将该表导出成sql,编辑该sql文件,删除建表删表语句,使用文本编辑器对IP进行批量替换,复制所有insert语句。由于原表有外键约束,在删除原来数据时会报错,按以下步骤来走就行
SET FOREIGN_KEY_CHECKS=0;
TRUNCATE TABLE 表名;
粘贴刚才复制的insert语句;
SET FOREIGN_KEY_CHECKS=1;
此时hive已经可以正常启动,跑几个查询试试,如果还会报错显示原先vm的IP的话,那就在hive里修改下每个表的信息吧
show create table hive表名; -- 查看建表信息
alter table hive表名 set location 'hdfs://新IP/...'
好了,填坑完毕,大伙儿继续愉快地使用hadoop吧~