hadoop节点规划
服务器集群规划,6台服务器:
一个主节点
两个从节点
三个工作节点
集群服务器用的都是centos7.9.2009的镜像
一、基础环境
1.1配置阿里云yum源
1.下载repo文件
wget http://mirrors.aliyun.com/repo/Centos-7.repo
2.备份并替换系统的repo文件
cp Centos-7.repo /etc/yum.repos.d/
cd /etc/yum.repos.d/
mv CentOS-Base.repo CentOS-Base.repo.bak
mv Centos-7.repo CentOS-Base.repo
3.执行yum源更新命令
yum clear all
yum makecache
yum update -y
安装sz rz工具,用于服务器和windows之间上传、下载文件
yum install -y lrzsz
安装完直接执行rz命令就能进行上传任务的工作
安装常用软件
yum install -y openssh-server vim gcc gcc-c++ glibc-headers bzip2-devel lzo-devel curl wget openssh-clients zlib-devel autoconf automake cmake libtool openssl-devel fuse-devel snappy-devel telnet unzip zip net-tools.x86_64 firewalld systemd ntp unrar bzip2
1.2安装JDK
Hadoop是用java写的,并且使用Hadoop作分布式计算的时候有的进程要启动到jvm中,需要jdk的支持,所以Hadoop集群中所有服务器都要安装jdk并进行相关配置
1.jdk下载
下载 jdk-8u144-linux-x64.rpm 到/public/software/java/
2.安装jdk
rpm -ivh /public/software/java/jdk-8u144-linux-x64.rpm
3.配置java系统的环境变量
进入/etc/profile文件中
export JAVA_HOME=/usr/java/jdk1.8.0_144
export PATH=$JAVA_HOME/bin:$PATH
让配置文件生效并检查
source /etc/profile
echo $PATH
或者使用批量命令
echo 'export JAVA_HOME=/usr/java/jdk1.8.0_144' >> /etc/profile
echo 'export PATH=$JAVA_HOME/bin:$PATH' >> /etc/profile
1.3修改主机名配置hosts映射
1.修改主机名
# 六台服务器分别进入/etc/hostname文件中,分别修改主机名为nn1、nn2、nn3、s1、s2、s3
# 查看当前主机名
hostname
2.配置hosts映射
# 配置hosts文件,添加主机名和ip地址映射
vim /etc/hosts
# 修改完第一台机器的ip映射后,然后分发到各个不同的机器上 xxx代表目标服务器的主机名
scp /etc/hosts root@xxx:/etc/
hosts文件配置前
127.0.0.1 localhost
11.26.164.142 linux-81580
11.94.204.169 linux-27782
11.26.164.150 op-68863
11.26.164.148 linux-89059
11.26.164.183 linux-29220
11.94.204.182 linux-47527
11.94.204.168 linux-84035
hosts文件配置后
127.0.0.1 localhost
11.26.164.150 op-68863
11.94.204.168 nn1
11.26.164.142 nn2
11.26.164.183 nn3
11.26.164.148 s1
11.94.204.182 s2
11.94.204.169 s3
1.4.配置hadoop用户免密切换root
1.设置hadoop用户并配置密码
# 添加hadoop用户
useradd hadoop
# 检查hadoop用户是否被添加
id hadoop
# 设置hadoop用户的密码
echo "12345678"| passwd hadoop --stdin
或 passwd hadoop
2.配置hadoop用户免密切换root用户
2.1修改/etc/pam.d/su配置
sed -i 's/#auth\t\trequired\tpam_wheel.so/auth\t\trequired\tpam_wheel.so/g' '/etc/pam.d/su'
sed -i 's/#auth\t\tsufficient\tpam_wheel.so/auth\t\tsufficient\tpam_wheel.so/g' '/etc/pam.d/su'
2.2修改/etc/login.defs文件 只有wheel组可以su到root
# 先备份一个
cp /etc/login.defs /etc/login.defs_back
# 把“SU_WHEEL_ONLY yes”字符串追加到/etc/login.defs文件底部
echo "SU_WHEEL_ONLY yes" >> /etc/login.defs
tail命令查看/etc/login.defs文件最后10行
tail /etc/login.defs
2.3 添加hadoop用户到wheel组
# 添加hadoop用户到wheel组
gpasswd -a hadoop wheel
# 查看wheel组是否有hadoop用户
cat /etc/group | grep wheel
1.5配置集群的hadoop用户之间可以通过ssh免密连接登入
1.在集群任意一台服务器生成公私钥
# nn1生成公私钥
ssh-keygen
2.其它服务器注册nn1生成的公钥
# 在nn1分别给其它服务器注册公钥
ssh-copy-id nn2
ssh-copy-id nn3
ssh-copy-id s1
ssh-copy-id s2
ssh-copy-id s3
此时nn1可以免密连接到其它服务器,但是其它服务器不能免密连接到nn1,包括其它服务器之间也不能免密连接
如果想要实现各个服务器之间都能免密连接,那么就要把nn1的私钥都给其它服务器copy一份,并且nn1自己还要再注册一份公钥
# nn1自己注册一份公钥
ssh-copy-id nn1
# nn1的私钥给其它服务器分别copy一份
scp ~/.ssh/id_rsa hadoop@nn2:/home/hadoop/.ssh/
scp ~/.ssh/id_rsa hadoop@nn3:/home/hadoop/.ssh/
scp ~/.ssh/id_rsa hadoop@s1:/home/hadoop/.ssh/
scp ~/.ssh/id_rsa hadoop@s2:/home/hadoop/.ssh/
scp ~/.ssh/id_rsa hadoop@s3:/home/hadoop/.ssh/
1.6集群常用脚本编写
获取脚本位置并输出
#! /bin/bash
# 获取脚本当前位置
cd `dirname $0`
# 输出脚本位置
echo `pwd`
scp命令
scp 文件名 登陆用户名@目标机器ip或者主机名:目标目录
ssh命令
ssh 登陆用户名@目标ip或主机名
eval命令
可以把字符串的内容作为一个命令执行
name=hadoop
cmd="echo hi $name"
echo $cmd # echo hi hadoop
eval $cmd # hi hadoop
1.批量脚本说明及使用
1)ips:用于存放要操作的主机列表,用回车或空格隔开
2)scp_all.sh:在hadoop用户下copy当前机器的文件到其它操作机(多机分发脚本)
3)ssh_all.sh:在hadoop用户下登陆其它操作机执行相应操作(多机操作脚本)
4)ssh_root.sh:与ssh_all.sh功能相同,不过该脚本是以root用户的身份执行相应操作(带root的多机操作脚本)
2.定义ips
首先在/home/hadoop目录下创建一个bin目录,然后进入bin目录创建ips文件并添加如下内容
nn1
nn2
nn3
s1
s2
s3
3.ssh_all.sh
在/home/hadoop/bin目录下创建ssh_all.sh文件
#!/bin/bash
# 进入当前脚本所在的目录
cd "$(dirname "$0")"
# 获取当前脚本所在的目录
dir_path="$(pwd)"
# 读取ips文件获得要批量操作的主机名
ip_arr=($(cat "$dir_path/ips"))
# 遍历数组依次操作每一台主机
for ip in "${ip_arr[@]}"
do# 拼接ssh命令cmd="ssh hadoop@$ip \"$@\""echo "$cmd"# 通过eval命令,执行拼接的ssh命令if ssh hadoop@$ip "$@"; thenecho "OK"elseecho "FAIL"fi
done
4.scp_all.sh
在/home/hadoop/bin目录下创建scp_all.sh文件
#!/bin/bash
# 进入当前脚本所在的目录
cd "$(dirname "$0")"
# 获取当前脚本所在的目录
dir_path="$(pwd)"
# 读取ips文件获得要批量操作的主机名
ip_arr=($(cat "$dir_path/ips"))
# 源
source=$1
# 目标
target=$2
# 遍历数组依次操作每一台主机
for ip in "${ip_arr[@]}"
do# 拼接ssh命令cmd="scp -r ${source} hadoop@${ip}:${target}"echo "$cmd"# 通过eval命令,执行拼接的ssh命令if eval ${cmd} ; thenecho "OK"elseecho "FAIL"fi
done
5.ssh_root.sh
在/home/hadoop/bin目录下创建ssh_root.sh文件,批量执行ssh_all.sh脚本没有权限执行的命令
5.1 exe.sh
执行su命令,与ssh_root.sh配合使用
# 切换到root用户执行cmd命令
cmd=$*
su - << EOF
$cmd
EOF
exe.sh脚本需要在每台服务器的/home/hadoop/bin目录下都copy一份
5.2 ssh_root.sh
#!/bin/bash
# 进入当前脚本所在的目录
cd "$(dirname "$0")"
# 获取当前脚本所在的目录
dir_path="$(pwd)"
# 读取ips文件获得要批量操作的主机名
ip_arr=($(cat "$dir_path/ips"))
# 遍历数组依次操作每一台主机
for ip in "${ip_arr[@]}"
do# 拼接ssh命令cmd="ssh hadoop@$ip ~/bin/exe.sh \"$@\""echo "$cmd"# 通过eval命令,执行拼接的ssh命令if ssh hadoop@$ip ~/bin/exe.sh "$@"; thenecho "OK"elseecho "FAIL"fi
done
注意:在写sh脚本的时候,层级之间不能使用空格,必须要使用Tab键,不然报错!
二、zookeeper
2.1zookeeper简介
zookeeper是用来管理hadoop集群的
提供了统一配置、统一命名、分布式锁的功能
2.2zookeeper节点规划及多机分发脚本设计
1.zookeeper节点规划
nn1 nn2 nn3
一个leader,两个follower
2.多机分发脚本设计
cp ips ips_zookeeper
cp scp_all.sh scp_all_zookeeper.sh
cp ssh_all.sh ssh_all_zookeeper.sh
cp ssh_root.sh ssh_root_zookeeper.sh
然后修改ips_zookeeper删除s1 s2 s3
修改scp_all_zookeeper.sh、ssh_all_zookeeper.sh、ssh_root_zookeeper.sh中的ips改为ips_zookeeper
2.3zookeeper安装、启动
1.zookeeper安装
# 安装zookeeper安装包
/public/software/bigdata/zookeeper-3.4.8.tar.gz
# 在zookeeper集群所有机器上把zookeeper的tar包解压到/usr/local目录下
ssh_root_zookeeper.sh tar -zxf /public/software/bigdata/zookeeper-3.4.8.tar.gz -C /usr/local/
# 查看解压的zookeeper
ssh_all_zookeeper.sh ls /usr/local/|grep zookeeper
# 创建软连接
ssh_root_zookeeper.sh ln -s /usr/local/zookeeper-3.4.8/ /usr/local/zookeeper
# 在/usr/local/zookeeper/conf目录下copy zoo_sample.cfg并重命名为zoo.cfg
cp zoo_sample.cfg zoo.cfg
# 修改zoo.cfg
dataDir=/tmp/zookeeper 修改为 dataDir=/data/zookeeper
添加配置
server.1=nn1:2888:3888
server.2=nn2:2888:3888
server.3=nn3:2888:3888# 在/usr/local/zookeeper/bin目录下配置zkEnv.sh,添加一个配置
ZOO_LOG_DIR=/data/zookeeper
# 把配置好的zoo.cfg、zkEnv.sh分发给zookeeper集群的其它机器
scp_all_zookeeper.sh /usr/local/zookeeper/bin/zkEnv.sh /usr/local/zookeeper/bin/
scp_all_zookeeper.sh /usr/local/zookeeper/conf/zoo.cfg /usr/local/zookeeper/conf/
# 创建/data/zookeeper目录
ssh_root_zookeeper.sh mkdir /data/zookeeper
# 递归修改/data目录,方便后续操作
ssh_root_zookeeper.sh chown -R hadoop:hadoop /data/
# 在zookeeper集群的nn1、nn2、nn3机器上分别在/data/zookeeper目录下创建myid文件,然后分别添加1、2、3(添加的id要和zoo.cfg里面的server.*一致)
echo "1" > myid
echo "2" > myid
echo "3" > myid
# 切换到root用户修改环境变量
su -
vim /etc/profile 添加环境变量
export ZOOKEEPER_HOME=/usr/local/zookeeper
export PATH=$PATH:$ZOOKEEPER_HOME/bin# 切换回hadoop用户分发修改的配置文件
scp_all_zookeeper.sh /etc/profile /tmp
ssh_root_zookeeper.sh mv /tmp/profile /etc/
# 检查配置文件
ssh_root_zookeeper.sh cat /etc/profile| grep ZOO
# 让配置生效
ssh_root_zookeeper.sh source /etc/profile
如果批量执行没有用的话就每个机器单独执行source /etc/profile
2.zookeeper启动
# 启动zookeeper集群
ssh_all_zookeeper.sh /usr/local/zookeeper/bin/zkServer.sh start
# 查看jps进程看zookeeper是否启动
ssh_all_zookeeper.sh jps
# 查看zookeeper集群的各个节点状态
ssh_all_zookeeper.sh /usr/local/zookeeper/bin/zkServer.sh status
zookeeper服务命令
# 启动zk服务
ssh_all_zookeeper.sh /usr/local/zookeeper/bin/zkServer.sh start
# 查看每个机器zk运行状态
ssh_all_zookeeper.sh /usr/local/zookeeper/bin/zkServer.sh status
# 停止zk服务
ssh_all_zookeeper.sh /usr/local/zookeeper/bin/zkServer.sh stop
# 重启zk服务
ssh_all_zookeeper.sh /usr/local/zookeeper/bin/zkServer.sh restart
启动zookeeper客户端
zkCli.sh
由于zookeeper是集群,所以通过zkCli.sh无论连接哪个机器都可以,连接上后操作的都是整个zookeeper集群
2.4zookeeper特点及常用命令
- zookeeper本质是一个分布式小文件存储系统
- zookeeper本质是树状结构,由节点构成,每个节点叫做znode节点,因此这棵树叫做znode树,根节点为/
- 在zookeeper中,没有相对路径,所有的节点路径都是从根节点开始计算,比如创建一个节点,create /demo " ",必须从根节点开始
- 每个节点都必须存储数据,否则这个节点不会创建成功,比如 create /demo1,不会被创建成功
- zookeeper主要是用来协调服务的,而不是用来存储数据业务的,所以不能放比较大的数据在节点上,zookeeper给出每个节点的数据量上限是1M
- 每个持久节点可以挂载子节点,但是临时节点不能挂载子节点
- zookeeper对hadoop集群的统一配置功能是指把hadoop集群的配置信息放到zookeeper的节点上,然后集群的机器监控存放配置信息的znode节点,如果节点的配置信息发生变化,那么集群的机器也会发生变化
1.zookeeper节点类型
持久节点:客户端断开后节点不会消失
create /demo1 ""
临时节点:客户端断开后节点会消失
create -e /demo1 ""
持久顺序节点:创建带有事务编号的节点,客户端断开后不会消失
create -s /demo1 ""
临时顺序节点:创建带有事务编号的节点,客户端断开后会消失
create -e -s /demo1 ""
每一个节点路径都是唯一的,所以基于这一特点,可以做集群统一命名服务
2.zookeeper存储特点
zookeeper的树状结构是维系在内存中的,即每一个节点的数据也会存储在内存中,这样做的目得是为了方便快速查找;同时zookeeper的树状结构也会以快照的形式维系在磁盘中,这样做的目得是保证数据安全,在磁盘的存储位置是由dataDir和dataLogDir属性决定的
3.zookeeper常用命令
create /video "" | 创建一个/video的持久节点,数据为空 |
get /video | 查看/video的节点信息 |
set /video "hello" | 修改节点数据为”hello“ |
create -e /demo1 "" | 创建一个临时节点/demo1 |
create -s /demo2 "" | 创建一个顺序节点/demo2 |
ls / | 查看根目录下的节点 |
rmr /test | 递归删除节点,即删除根目录下test节点及test下的子节点 |
ls /demo3 watch | 监听/demo3下子节点变化 |
get /demo4 watch | 监听/demo4数据变化 |
2.5zookeeper选举机制
- 当zookeeper集群启动的时候,每一个节点都会进入选举状态,并且会推举自己成为leader,然后将自己的选举信息发送给其它节点
- 节点之间进行两两比较,经过多轮比较之后,最终胜出的节点成为leader
- 选举信息
自己拥有的最大事务id--Zxid
自己的选举id--myid
- 比较原则
先比较最大事务id,谁大谁赢
如果最大事务id一致,则比较myid,谁大谁赢
经过多轮比较之后,一个节点如果胜过了一半以上的节点,则这个节点就会成为leader ---过半选举
- 一旦zookeeper集群选举出了leader,那么新添加的节点无论事务id或者myid多大都只能是follower
- 在zookeeper集群中,一旦当leader节点宕机以后,会自动重新选举新的leader,所以不存在单点故障问题,但是一旦集群中存活的节点个数不足一半,那么整个zookeeper集群就不能正常工作了 ---过半存活
- 如果在zookeeper集群出现2个及以上leader,这种现象称为脑裂
- 脑裂产生的原因:集群产生了分裂;分裂之后进行了选举
- 如何抑制脑裂:在zookeeper集群中,会对每次选举出来的leader分配一个唯一的全局递增的编号,称之为epochid。如果zookeeper集群中存在多个leader,那么会自动将epochid较低的节点转为follower状态
2.6zookeeper原子广播流程
zookeeper通过原子广播流程保证了zookeeper集群数据的一致性
当zookeeper集群收到请求后会把请求交给leader处理,leader会把请求记录到本地的log文件中,如果记录成功,leader会把这个操作记录发送给每一个follower,放到每个follower的队列中,follower会把请求从队列中拿出,试图记录到follower的本地log中,如果成功就会给leader返回ok信号,失败就会返回no信号,如果leader收到一半以上的follower返回的是ok信号,就会认为这个操作可以执行,leader会通知所有的节点执行此操作,否则没有收到一半以上的ok信号,则认为此操作不可执行,leader就会通知所有的节点从log中删除刚才的记录
其实zookeeper集群对于请求的处理就是如果请求在follower中,则会把请求转发给leader处理,如果请求直接在leader,则leader直接处理,然后由leader转发请求发送给每个follower来执行,以此保证zookeeper集群的数据一致性
2.7observer观察者
observer就是一个不参与投票也不参与选举的follower,只监听投票的结果,但是可以正常工作,所以observer可以提高选举的效率,并且observer的作用不仅限于leader的选举过程,在原子广播流程中observer也不参与,只负责最后执行命令来保证observer的数据与leader的数据一致
2.8zookeeper特性总结
1.数据一致性:服务端启动后,客户端无论通过哪个节点连接zookeeper集群,展示出来的都是同一个视图,即查询的数据都是一样的
2.原子性:对于事务决议的更新,只能是成功或者失败两种可能,没有中间状态。要么集群所有机器都成功应用某一事务,要么都没有应用,一定不会出现集群中一部分机器应用了事务,另一部分机器没有应用的情况
3.可靠性
4.实时性
5.顺序性
6.过半性:过半选举、过半存活、过半操作