Zookeeper
Kafka集群
一 zookeeper
1 Zookeeper是什么
一个开元分布式协调服务
2 zookeeper作用
保证数据在集群间事物一致性
3 zookeeper应用场景
集群分布式锁 ->管理类似房间门
集群统一命名
分布式协调服务
4 角色与特性
Leader->能读能写
接受所有follower的请求并同一协调发起投票,负责与所有的follower进行内部数据交换
Follower->能读
直接为客户端服务并参与投票,同时与leader 进行数据交换
Observer->能读不能投票
直接为客户端服务但是不参与投票
同时也与leader 进行数据交换
二 Zookeeper 角色选举原则
Zookeeper 服务启动是没有角色的(looking),
角色是通过选举产生的
选举产生一个leader,剩下的是flower
1 选举原则
集群中超过半数主机投票选择leader
必须n/2 +1台主机服务器的投票
Leader死亡,则会重新选举leader
死亡机器到一半,集群挂掉
无法获得足够投票会重新发起投票
Follower死亡过多,剩余机器不足n/2 +1,集群会停止工作
Observer不计算投票->它没有投票权
2 zookeeper可伸缩扩展原理与设计
1 Leader负责所有写操作
2 Follower 读操作与相应leader提议
在obsever出现前,zookeeper伸缩性由follower来实现,随着follower数量增多,天天搞太多的投票麻烦,zookeeper服务的写性能收到影响
3 客户端提交一个请求,若是读请求,则由每一台server的本地副本数据库直接响应,若是写请求,则需要通过一致性协议zab来处理
Zab:来自client所有写请求都必须转发给zk服务中唯一的leader,由leader根据请求发起投票,之后leader对vode进行收集,骗术过半是leader会向所有server发送一个通知消息.
最后当client所连接的server所连接的srever收到信息时,会把该操作更新到内存中,并对client的写请求做出回应
3 Zookeeper 原理与设计
4 zookeeper 扮演了两个职能
1接收客户端请求
2 发起投票
-> 5 在增加client数量时,如何保持较好的吞吐性能
增加不参与投票的observer
Observer 可以接收客户端的链接,并且将写的请求转发给leader节点,但是.leader节点不会要求obserevr参与投票
Observer的扩展,给zookeeper的可伸缩性带来了全新景象,加入很多的obserer节点,无须担心严重影响吞吐量.
Observer提升性能的可伸缩性
Observer提供了广域网能力
三 部署zookeeper 集群
1 扩容内存至2G
virsh edit nn01
cd /root
ls
cd hadoop/
2 安装java环境
tar -zvxf zookeeper-3.4.13.tar.gz
mv zookeeper-3.4.13 /usr/local/zookeeper
cd /usr/local/zookeeper/conf
3 修改配置文件名
mv zoo_sample.cfg zoo.cfg -
chown root.root zoo.cfg
4 修改配置文件
vim zoo.cfg
server.1=node1:2888:3888
serevr.2=node2:2888:3888
server.3=node3:2888:3888
server.4=node4:2888:3888
5 同步配置文件
拷贝 /usr/local/zookeeper 到其他集群主机node1 node2 node3
for i in node{1…3}; do rsync -aXSH --delete /usr/local/zookeeper/ $i:/usr/local/zookeeper/; done
6)创建datadir 指定目录 对应主机名的myid文件
mkdir /tmp/zookeeper,每一台都要 node1 node2 node3
[root@nn01 conf]# mkdir /tmp/zookeeper
[root@nn01 conf]# ssh node1 mkdir /tmp/zookeeper
关于myid文件
Myid文件只有一个数字
注意确保每个server的myid文件id 数字不一样
Server.id中的id与myid中的id必须一致
Id范围1-255
7)创建 myid 文件,id 必须与配置文件里主机名对应的 server.(id) 一致
[root@nn01 conf]# echo 4 >/tmp/zookeeper/myid
[root@nn01 conf]# ssh node1 ‘echo 1 >/tmp/zookeeper/myid’
8)启动服务,单启动一台无法查看状态,需要启动全部集群以后才能查看状态,每一台上面都要手工启动(以nn01为例子)
[root@nn01 conf]# /usr/local/zookeeper/bin/zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/…/conf/zoo.cfg
Starting zookeeper … STARTED
注意:刚启动zookeeper查看状态的时候报错,启动的数量要保证半数以上,这时再去看就成功了
9)查看状态
[root@nn01 conf]# /usr/local/zookeeper/bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/…/conf/zoo.cfg
Mode: observe
[root@nn01 conf]# /usr/local/zookeeper/bin/zkServer.sh stop
//关闭之后查看状态其他服务器的角色
Socat - TCP :node3:2181
Ruok
Imok
四 部署kafka集群
1 什么是kafka
Kafka是一个开源的分布式消息系统
Kafka是用scala编写
Kafka是一种消息中间件
2 kafka特点
解耦,荣誉,提高扩展性,缓冲
保证顺序,灵活,削峰填谷
异步通信
3 kafka角色
Producer:生产者,负责发布信息
Consumer:消费者
Topic:消息的类别
Partion:每个topic包含一个或者多个partion
Broker:kafka集群包含一个或者多个服务器
Kafka通过zookeeper管理集群配置
选举leader
Kafka集群安装与配置
Kafka集群的安装配置依赖zookeeper,搭建kafka集群前,需要先创建一个可用的zookeeper集群
1 安装java环境
2 同步kafka拷贝到所有主机
3 修改配置文件
4 启动与验证
\
搭建Kafka集群
1)解压 kafka 压缩包
Kafka在node1,node2,node3上面操作即可
[root@node1 hadoop]# tar -xf kafka_2.12-2.1.0.tgz
2)把 kafka 拷贝到 /usr/local/kafka 下面
[root@node1 ~]# mv kafka_2.12-2.1.0 /usr/local/kafka
3)修改配置文件 /usr/local/kafka/config/server.properties
[root@node1 ~]# cd /usr/local/kafka/config
[root@node1 config]# vim server.properties
broker.id=22
zookeeper.connect=node1:2181,node2:2181,node3:2181
4)拷贝 kafka 到其他主机,并修改 broker.id ,不能重复
[root@node1 config]# for i in 63 64; do rsync -aSH --delete /usr/local/kafka 192.168.1.$i:/usr/local/; done
[1] 27072
[2] 27073
[root@node2 ~]# vim /usr/local/kafka/config/server.properties
//node2主机修改
broker.id=23
[root@node3 ~]# vim /usr/local/kafka/config/server.properties
//node3主机修改
broker.id=24
5)启动 kafka 集群(node1,node2,node3启动)
[root@node1 local]# /usr/local/kafka/bin/kafka-server-start.sh -daemon /usr/local/kafka/config/server.properties
[root@node1 local]# jps //出现kafka
26483 DataNode
27859 Jps
27833 Kafka
26895 QuorumPeerMain
6)验证配置,创建一个 topic
7)
[root@node1 local]# /usr/local/kafka/bin/kafka-topics.sh --create --partitions 1 --replication-factor 1 --zookeeper node3:2181 --topic aa
Created topic “aa”.
- 模拟生产者,发布消息
[root@node2 ~]# /usr/local/kafka/bin/kafka-console-producer.sh
–broker-list node2:9092 --topic aa //写一个数据
ccc
Ddd
8)模拟消费者,接收消息
[root@node3 ~]# /usr/local/kafka/bin/kafka-console-consumer.sh \
–bootstrap-server node1:9092 --topic aa //这边会直接同步
ccc
ddd
五 Hadoop高可用设计与实施
集群搭建背景介绍:
Namenode ->HDFS的核心配置
HDFS又是Hadoop的核心组件,所以Namenode在集群中至关重要
Namenode 宕机,将导致集群不可用,如果namenode数据丢失,将导致整个集群的数据丢失,而namenode的数据更新有比较频繁,所以必须实现高可用
1 解决方案
官方给出了两种解决方案
HDFS with NFS
HDFS with QJM
两种方比较:
2 HA 高可用方案对比
1 都能实现热备
2 都是一个Active NN和一个Standby NN
3 都使用Zookeeper和ZKFC来实现自动失效恢复
4 失效切换都是用Fencin配置的方案来Active NN
5 NFS数据变更方案把数据存储在共享存储里,这种方案我们还要考略到NFS的高可用设计
6 QJM则不需要共享存储,但是需要让每一个DN都知道两个NN的位置,并且把信息和心跳包发送给Active和Standby这两个NN
3 QJM方案使用
1 解决了Namenode单点故障问题
2 Hadoop 给出了HDFS的高可用HA方案,HDFS通常由两个Namenode组成,一个处于Active状态,另一个处于Standby状态.
Active namenode 负责对外提供服务,比如处理来自客户端的RPC请求,二Standby namenode则不对外提供服务,仅仅是同步Active namenode 的状态
以便能够在它死亡时进行切换
3 namenode 会被配置在两台独立的机器上,在任何时候,一台namenode处于Active状态,另一个处于备份状态
4 活跃状态的namenode 会响应集群中的所有客户端,备份状态的namenode只会作为一个副本,保证在必要时提供快速转移
六 Namenode 高可用方案部署
Namenode 高可用架构介绍
为了让Standby node 和Active node 保持同步
Namenode高可用架构图
环境准备
1删除所有虚拟机 /var/hadoop/*
2 重启所有虚拟机
3 在node1 node2 node3 启动zookeeper
4安装192.168.1.66 nn02
5 nn02 安装java-1.8.0-openjdk-devel
6 配置/etc/hosts 添加nn02
7 吧nn01上的公钥 私钥拷贝给nn02
8 配置hadoop
Hadoop-env.sh
Core-site.xml
Hdfs-site.xml
Mapred-site.xml
Yarn-site.xml
Slaves
配置 Core-site.xml
[root@nn01 .ssh]# vim /usr/local/hadoop/etc/hadoop/core-site.xml
fs.defaultFS
hdfs://nsdcluster
//nsdcluster是随便起的名。相当于一个组,访问的时候访问这个组
hadoop.tmp.dir
/var/hadoop
ha.zookeeper.quorum
node1:2181,node2:2181,node3:2181 //zookeepe的地址
hadoop.proxyuser.nfs.groups
hadoop.proxyuser.nfs.hosts
配置 hdfs-site
[root@nn01 ~]# vim /usr/local/hadoop/etc/hadoop/hdfs-site.xml
dfs.replication
2
dfs.nameservices
nsdcluster
dfs.ha.namenodes.nsdcluster
//nn1,nn2名称固定,是内置的变量,nsdcluster里面有nn1,nn2
nn1,nn2
dfs.namenode.rpc-address.nsdcluster.nn1
//声明nn1 8020为通讯端口,是nn01的rpc通讯端口
nn01:8020
dfs.namenode.rpc-address.nsdcluster.nn2
//声明nn2是谁,nn02的rpc通讯端口
nn02:8020
dfs.namenode.http-address.nsdcluster.nn1
//nn01的http通讯端口
nn01:50070
dfs.namenode.http-address.nsdcluster.nn2
//nn01和nn02的http通讯端口
nn02:50070
dfs.namenode.shared.edits.dir
//指定namenode元数据存储在journalnode中的路径
qjournal://node1:8485;node2:8485;node3:8485/nsdcluster
dfs.journalnode.edits.dir
//指定journalnode日志文件存储的路径
/var/hadoop/journal
dfs.client.failover.proxy.provider.nsdcluster
//指定HDFS客户端连接active namenode的java类
org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider
dfs.ha.fencing.methods //配置隔离机制为ssh
sshfence
dfs.ha.fencing.ssh.private-key-files //指定密钥的位置
/root/.ssh/id_rsa
dfs.ha.automatic-failover.enabled //开启自动故障转移
true
配置yarn-site.xml
[root@nn01 ~]# vim /usr/local/hadoop/etc/hadoop/yarn-site.xml
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<name>yarn.resourcemanager.ha.enabled</name>
<value>true</value>
</property>
<property>
<name>yarn.resourcemanager.ha.rm-ids</name> //rm1,rm2代表nn01和nn02
<value>rm1,rm2</value>
</property>
<property>
<name>yarn.resourcemanager.recovery.enabled</name>
<value>true</value>
</property>
<property>
<name>yarn.resourcemanager.store.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value>
</property>
<property>
<name>yarn.resourcemanager.zk-address</name>
<value>node1:2181,node2:2181,node3:2181</value>
</property>
<property>
<name>yarn.resourcemanager.cluster-id</name>
<value>yarn-ha</value>
</property>
<property>
<name>yarn.resourcemanager.hostname.rm1</name>
<value>nn01</value>
</property>
<property>
<name>yarn.resourcemanager.hostname.rm2</name>
<value>nn02</value>
</property>
11)同步到nn02,node1,node2,node3
[root@nn01 ~]# for i in {61…63} 66; do rsync -aSH --delete /usr/local/hadoop/ 192.168.1.$i:/usr/local/hadoop -e ‘ssh’ & done
12)删除所有机器上面的/user/local/hadoop/logs,方便排错
[root@nn01 ~]# for i in {60…63} 66; do ssh 192.168.1.$i rm -rf /usr/local/hadoop/logs ; done
13)同步配置
[root@nn01 ~]# for i in {61…63} 66; do rsync -aSH --delete /usr/local/hadoop 192.168.1.$i:/usr/local/hadoop -e ‘ssh’ & done
七 高可用验证
初始化集群
验证集群
验证hadoop的高可用
前提
1 初始化集群;
All 所有主机
Node1 node2 node3
2 同步配置到所有集群主机
1)初始化ZK集群
[root@nn01 ~]# /usr/local/hadoop/bin/hdfs zkfc -formatZK
…
18/09/11 15:43:35 INFO ha.ActiveStandbyElector: Successfully created /hadoop-ha/nsdcluster in ZK //出现Successfully即为成功
…
2)在node1,node2,node3上面启动journalnode服务(以node1为例子)
[root@node1 ~]# /usr/local/hadoop/sbin/hadoop-daemon.sh start journalnode
starting journalnode, logging to /usr/local/hadoop/logs/hadoop-root-journalnode-node1.out
[root@node1 ~]# jps
29262 JournalNode
26895 QuorumPeerMain
29311 Jps
3)格式化,先在node1,node2,node3上面启动journalnode才能格式化
[root@nn01 ~]# /usr/local/hadoop//bin/hdfs namenode -format
//出现Successfully即为成功
[root@nn01 hadoop]# ls /var/hadoop/
dfs
4)nn02数据同步到本地 /var/hadoop/dfs
[root@nn02 ~]# cd /var/hadoop/
[root@nn02 hadoop]# ls
[root@nn02 hadoop]# rsync -aSH nn01:/var/hadoop/ /var/hadoop/
[root@nn02 hadoop]# ls
Dfs
5)初始化 JNS
[root@nn01 hadoop]# /usr/local/hadoop/bin/hdfs namenode -initializeSharedEdits
18/09/11 16:26:15 INFO client.QuorumJournalManager: Successfully started new epoch 1 //出现Successfully,成功开启一个节点
6)停止 journalnode 服务(node1,node2,node3)
[root@node1 hadoop]# /usr/local/hadoop/sbin/hadoop-daemon.sh stop journalnode
stopping journalnode
[root@node1 hadoop]# jps
29346 Jps
26895 QuorumPeerMain
启动集群
1)nn01上面操作
[root@nn01 hadoop]# /usr/local/hadoop/sbin/start-all.sh //启动所有集群
2)nn02上面操作
[root@nn02 hadoop]# /usr/local/hadoop/sbin/yarn-daemon.sh start resourcemanager
3)查看集群状态
[root@nn01 hadoop]# /usr/local/hadoop/bin/hdfs haadmin -getServiceState nn1
active
[root@nn01 hadoop]# /usr/local/hadoop/bin/hdfs haadmin -getServiceState nn2
standby
[root@nn01 hadoop]# /usr/local/hadoop/bin/yarn rmadmin -getServiceState rm1
active
[root@nn01 hadoop]# /usr/local/hadoop/bin/yarn rmadmin -getServiceState rm2
standby
4)查看节点是否加入
[root@nn01 hadoop]# /usr/local/hadoop/bin/hdfs dfsadmin -report
…
Live datanodes (3): //会有三个节点
…
[root@nn01 hadoop]# /usr/local/hadoop/bin/yarn node -list
Total Nodes:3
Node-Id Node-State Node-Http-Address Number-of-Running-Containers
node2:43307 RUNNING node2:8042 0
node1:34606 RUNNING node1:8042 0
node3:36749 RUNNING node3:8042 0
访问集群
1)查看并创建
[root@nn01 hadoop]# /usr/local/hadoop/bin/hadoop fs -ls /
[root@nn01 hadoop]# /usr/local/hadoop/bin/hadoop fs -mkdir /aa //创建aa
[root@nn01 hadoop]# /usr/local/hadoop/bin/hadoop fs -ls / //再次查看
2)验证高可用,关闭 active namenode
[root@nn01 hadoop]# /usr/local/hadoop/bin/hdfs haadmin -getServiceState nn1
active
[root@nn01 hadoop]# /usr/local/hadoop/sbin/hadoop-daemon.sh stop namenode
stopping namenode
[root@nn01 hadoop]# /usr/local/hadoop/bin/hdfs haadmin -getServiceState nn1
//再次查看会报错
[root@nn01 hadoop]# /usr/local/hadoop/bin/hdfs haadmin -getServiceState nn2
//nn02由之前的standby变为active
active
[root@nn01 hadoop]# /usr/local/hadoop/bin/yarn rmadmin -getServiceState rm1
active
[root@nn01 hadoop]# /usr/local/hadoop/sbin/yarn-daemon.sh stop resourcemanager
//停止resourcemanager
[root@nn01 hadoop]# /usr/local/hadoop/bin/yarn rmadmin -getServiceState rm2
Active
3) 恢复节点
[root@nn01 hadoop]# /usr/local/hadoop/sbin/hadoop-daemon.sh start namenode
//启动namenode
[root@nn01 hadoop]# /usr/local/hadoop/sbin/yarn-daemon.sh start resourcemanager
//启动resourcemanager
[root@nn01 hadoop]# /usr/local/hadoop/bin/hdfs haadmin -getServiceState nn1
//查看
[root@nn01 hadoop]# /usr/local/hadoop/bin/yarn rmadmin -getServiceState rm1
//查看