本文共 24355 字,大约阅读时间需要 81 分钟。
大数据的由来
• 大数据 – 随着计算机技术的发展,互联网的普及,信息的积累 已经到了一个非常庞大的地步,信息的增长也在不断 的加快,随着互联网、物联网建设的加快,信息更是 爆炸是增长,收集、检索、统计这些信息越发困难, 必须使用新的技术来解决这些问题什么是大数据
• 大数据的定义 – 大数据指无法在一定时间范围内用常规软件工具进行捕捉、 管理和处理的数据集合,需要新处理模式才能具有更强的 决策力、洞察发现力和流程优化能力的海量、高增长率和 多样化的信息资产 – 是指从各种各样类型的数据中,快速获得有价值的信息
• 大数据能做什么
– 企业组织利用相关数据分析帮助他们降低成本、提高 效率、开发新产品、做出更明智的业务决策等 – 把数据集合并后进行分析得出的信息和数据关系性, 用来察觉商业趋势、判定研究质量、避免疾病扩散、 打击犯罪或测定即时交通路况等 – 大规模并行处理数据库,数据挖掘电网,分布式文件 系统或数据库,云计算平和可扩展的存储系统等
开源,基于java开发,提供分布式基础架构, 特点:高可靠性、高扩展性、高效性、高容错性、低成本
• 2003年开始Google陆续发表了3篇论文
– GFS,MapReduce,BigTable• GFS
– GFS是一个可扩展的分布式文件系统,用于大型的、分布式 的、对大量数据进行访问的应用 – 可以运行于廉价的普通硬件上,提供容错功能 • MapReduce – MapReduce是针对分布式并行计算的一套编程模型,由 Map和Reduce组成,Map是映射,把指令分发到多个 worker上,Reduce是规约,把worker计算出的结果合并• BigTable
– BigTable是存储结构化数据 – BigTable建立在GFS,Scheduler,Lock Service和 MapReduce之上 – 每个Table都是一个多维的稀疏图
• GFS、MapReduce和BigTable三大技术被称为
Google的三驾马车,虽然没有公布源码,但发布了 这三个产品的详细设计论 • Yahoo资助的Hadoop,是按照这三篇论文的开源 Java实现的,但在性能上Hadoop比Google要差很多 – GFS - - -> HDFS – MapReduce - - -> MapReduce – BigTable - - -> Hbase
Hadoop组件
结构
Hadoop体系中数据存储管理的基础,是一个高度容错的系统,用于在低成本的通用硬件上运行
- 角色
client
namenode
secondarynode
datanode
• NameNode
– Master节点,管理HDFS的名称空间和数据块映射信 息(fsimage),配置副本策略,处理所有客户端请求 • Secondary NameNode – 定期合并fsimage 和fsedits,推送给NameNode – 紧急情况下,可辅助恢复NameNodefsedits 变更日志(打补丁)
• 但Secondary NameNode并非NameNode的热备
• DataNode
– 数据存储节点,存储实际的数据 – 汇报存储信息给NameNode• Client
– 切分文件 – 访问HDFS – 与NameNode交互,获取文件位置信息 – 与DataNode交互,读取和写入数据block 每块缺省128MB大小,每块可以多个副本
结构
• 源自于Google的MapReduce论文,JAVA实现的分布式计算框架
• 角色和概念– JobTrackerMaster节点只有一个,管理所有作业/任务的监控、错误处理等
将任务分解成一系列任务,并分派给TaskTracker – TaskTrackerSlave节点,一般是多台,运行Map Task和Reduce Task
并与JobTracker交互,汇报任务状态 – Map Task解析每条数据记录,传递给用户编写的
map()并执行,将输出结果写入本地磁盘 – 如果为map-only作业,直接写入HDFS – Reducer Task从Map Task的执行结果中,远程读
取输入数据,对数据进行排序,将数据按照分组传递 给用户编写的reduce函数执行
结构
Yarn是Hadoop的一个通用的资源管理系统
角色
– Resourcemanager
– 处理客户端请求
– 启动/监控ApplicationMaster – 监控NodeManager – 资源分配与调度 – Nodemanager– 单个节点上的资源管理
– 处理来自ResourceManager的命令 – 处理来自ApplicationMaster的命令 – ApplicationMaster– 数据切分
– 为应用程序申请资源,并分配给内部任务 – 任务监控与容错 – Container– 对任务运行行环境的抽象,封装了CPU 、内存等
– 多维资源以及环境变量、启动命令等任务运行相关的信息资源分配与调度 – Client– 用户与Yarn交互的客户端程序
– 提交应用程序、监控应用程序状态,杀死应用程序等
• Yarn的核心思想
• 将JobTracker和TaskTacker进行分离,它由下面几大构成组件 – ResourceManager一个全局的资源管理器 – NodeManager每个节点(RM)代理 – ApplicationMaster表示每个应用 – 每一个ApplicationMaster有多个Container在NodeManager上运行
• Hadoop的部署模式有三种
– 单机 – 伪分布式 – 完全分布式新虚拟机 192.168.5.61 node1
安装 java-1.8.0-openjdk-devel
[root@node1 ~]# jps #测试是否成功
1446 Jps[root@node1 ~]# tar -xf hadoop-2.7.7.tar.gz
[root@node1 ~]# mv hadoop-2.7.7/ /usr/local/hadoop #保证所有者和所属组为root[root@node1 ~]# cd /usr/local/hadoop
[root@node1 hadoop]# rpm -ql java-1.8.0-openjdk
/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.161-2.b14.el7.x86_64/jre/ 截取前面相同的路径[root@node1 hadoop]# ./bin/hadoop verion
Error: JAVA_HOME is not set and could not be found. #找不到java你装哪了,需定义变量指定[root@node1 hadoop]# vim etc/hadoop/hadoop-env.sh
# The java implementation to use.
export JAVA_HOME="/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.161-2.b14.el7.x86_64/jre"export HADOOP_CONF_DIR="/usr/local/hadoop/etc/hadoop"
[root@node1 hadoop]# ./bin/hadoop version
[root@node1 ~]# cd /usr/local/hadoop/
[root@node1 hadoop]# mkdir input[root@node1 hadoop]# ls
bin include lib LICENSE.txt README.txt shareetc input libexec NOTICE.txt output sbin[root@node1 hadoop]# cp *.txt input/
[root@node1 hadoop]# ./bin/hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.7.jar wordcount input output
[root@node1 hadoop]# ls output/
part-r-00000 _SUCCESS
需修改的配置文件
– Hadoop-env.sh
JAVA_HOME HADOOP_CONF_DIR
– xml文件配置格式
<property> <name>关键字</name> <value>变量值</value> <description> 描述 </description> </property>
环境准备
192.168.5.60 nn01
192.168.5.61 node1 前面已配置 192.168.5.62 node2 192.168.5.63 node3
修改 /etc/hosts
# ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 192.168.5.60 nn01 192.168.5.61 node1 192.168.5.62 node2 192.168.5.63 node3
全部装 java-1.8.0-openjdk-devel
selinux关闭,禁用firewalld
所有机器能被nn01无密码ssh
ssh-keygen 生成密钥,
ssh-copy-id nn01/node1/node2/node3
[root@nn01 ~]# vim /etc/ssh/ssh_config
Host * StrictHostKeyChecking no 设置第一次ssh时不需要输入yes
tar -xf hadoop-2.7.7.tar.gz
chown -R root:root hadoop-2.7.7/
mv hadoop-2.7.7/ /usr/local/hadoop
cd /usr/local/hadoop
[root@nn01 hadoop]# vim etc/hadoop/core-site.xml 核心配置文件
<configuration> <property> <name>fs.defaultFS</name> 文件系统配置参数 <value>hdfs://nn01:9000</value> </property> <property> <name>hadoop.tmp.dir</name> 数据根目录配置参数 <value>/var/hadoop</value> </property> </configuration>
[root@nn01 hadoop]# vim etc/hadoop/hdfs-site.xml
<configuration> <property> <name>dfs.namenode.http-address</name> 地址声明(谁是namenode) <value>nn01:50070</value> </property> <property> <name>dfs.namenode.secondary.http-address</name> 地址声明(SecondaryNameNode) <value>nn01:50090</value> </property> <property> <name>dfs.replication</name> 文件冗余份数() <value>2</value> </property> </configuration>[root@nn01 hadoop]# cd etc/hadoop
[root@nn01 hadoop]# vim slaves #只写DataNode节点的主机名称
node1
node2 node3
[root@nn01 hadoop]# vim etc/hadoop/hadoop-env.sh
export JAVA_HOME="/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.161-2.b14.el7.x86_64/jre"
export HADOOP_CONF_DIR="/usr/local/hadoop/etc/hadoop"Hadoop所有节点的配置参数完全一样,在一台配置好
后,把配置文件同步到其它所有主机上rsync -aSH --delete /usr/local/hadoop node1:/usr/local/
rsync -aSH --delete /usr/local/hadoop node2:/usr/local/
rsync -aSH --delete /usr/local/hadoop node3:/usr/local/
[root@nn01 hadoop]# cd /usr/local/hadoop/
[root@nn01 hadoop]# mkdir /var/hadoop
[root@nn01 hadoop]# ./bin/hdfs namenode -format [root@nn01 hadoop]# ./sbin/start-dfs.sh
[root@nn01 hadoop]# jps
30871 SecondaryNameNode 30680 NameNode 31017 Jps
[root@node1 logs]# jps 其他节点上查看
1093 Jps 998 DataNode
核心手段:拆()
不同服务合在一台机器上
主机 | 角色 | 软件 |
192.168.1.60 Master | NameNode SecondaryNameNode ResourceManager | HDFS YARN |
192.168.1.61 node1 | DataNode NodeManager | HDFS YARN |
192.168.1.62 node2 | DataNode NodeManager | HDFS YARN |
192.168.1.63 node3 | DataNode NodeManager | HDFS YARN |
[root@nn01 hadoop]# cd /usr/local/hadoop/etc/hadoop
[root@nn01 hadoop]# mv mapred-site.xml.template mapred-site.xml
[root@nn01 hadoop]# vim mapred-site.xml<configuration>
<property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> </configuration>[root@nn01 hadoop]# vim yarn-site.xml
<configuration>
<!-- Site specific YARN configuration properties -->
<property> <name>yarn.resourcemanager.hostname</name> <value>nn01</value> </property><property>
<name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property></configuration>
[root@nn01 hadoop]# for i in node1 node2 node3; do rsync -avXSH --delete /usr/local/hadoop ${i}:/usr/local; done
[root@nn01 hadoop]# ./sbin/start-yarn.sh[root@nn01 hadoop]# ./bin/yarn node -list
19/06/21 09:54:01 INFO client.RMProxy: Connecting to ResourceManager at nn01/192.168.5.60:8032 Total Nodes:3 Node-Id Node-State Node-Http-Address Number-of-Running-Containers node1:38135 RUNNING node1:8042 0 node3:39287 RUNNING node3:8042 0 node2:33541 RUNNING node2:8042 0[root@nn01 hadoop]# jps
1684 NameNode 1876 SecondaryNameNode 2775 Jps 2206 ResourceManager
[root@node1 ~]# jps
914 DataNode 1474 NodeManager 1634 Jps
resourcemanager WEB页面(nn01)
nodemanager WEB页面(node1 node2 node3)
/ secondory namenode WEB页面
namenode WEB页面
datanode(node1 node2 node3) WEB页面
[root@nn01 hadoop]# ./bin/hadoop fs -ls /
[root@nn01 hadoop]# ./bin/hadoop fs -mkdir /abc
[root@nn01 hadoop]# ./bin/hadoop fs -ls / [root@nn01 hadoop]# ./bin/hadoop fs -touchz /abc/f1 创建 [root@nn01 hadoop]# ./bin/hadoop fs -put *.txt /abc 上传文件 [root@nn01 hadoop]# ./bin/hadoop fs -get /abc/f1 下载文件 [root@nn01 hadoop]# ls f1
hdfs安全模式相关命令(不是必要操作)
hdfs dfsadmin -report 查看
hadoop dfsadmin safemode leave 强制namenode退出安全模式
[root@nn01 hadoop]# ./bin/hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.7.jar wordcount /abc/* /bcd #提交分析作业
[root@nn01 hadoop]# ./bin/hadoop fs -cat /bcd/* #查看结果
扩容
新增192.168.5.64 newnode
– 启动一个新的系统,设置SSH免密码登录
[root@nn01 #] ssh-copy-id newnode
– 在所有节点修改 /etc/hosts,增加新节点的主机信息nn01 ]# vim /etc/hosts
# ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 192.168.5.60 nn01 192.168.5.61 node1 192.168.5.62 node2 192.168.5.63 node3 192.168.5.64 newnode]# for i in node{1..3}; do scp /etc/hosts ${i}:/etc/; done
]# scp /etc/hosts newnode:/etc/
– 安装java运行环境(java-1.8.0-openjdk-devel) – 修改NameNode的slaves文件增加该节点[root@nn01 hadoop]# vim /usr/local/hadoop/etc/hadoop/slaves
node1
node2 node3 newnodenn01 hadoop]# for i in node1 node2 node3 ; do scp ./slaves ${i}:/usr/local/hadoop/etc/hadoop; done
– 拷贝NamNode(nn01)的/usr/local/hadoop到本机nn01]# scp -r /usr/local/hadoop newnode:/usr/local
– 在该节点启动DataNode newnode]# ./sbin/hadoop-daemon.sh start datanode
– 设置同步带宽,并同步数据
# ./bin/hdfs dfsadmin -setBalancerBandwidth 60000000 # ./sbin/start-balancer.sh – 查看集群状态 # ./bin/hdfs dfsadmin -report
HDFS 修复节点比较简单,与增加节点基本一致
--注意:新节点的ip和主机名要与损坏节点的一致
--启动服务: /usr/local/hadoop/sbin/hadoop-daemon.sh start datanode
--数据恢复是自动的
--上线以后会自动恢复数据,如果数据量非常巨大,可能需要一段时间
[root@nn01 hadoop]# cd /usr/local/hadoop/
[root@nn01 hadoop]# ./bin/hadoop fs -put /root/CentOS7-1804.iso /bcd
[root@nn01 ~]# vim etc/hadoop/hdfs-site.xml
<property>
<name>dfs.hosts.exclude</name> <value>/usr/local/hadoop/etc/hadoop/exclude</value> </property>[root@nn01 hadoop]# ./bin/hdfs dfsadmin -report
NFS网关
• NFS 网关用途
– 用户可以通过操作系统兼容的本地NFSv3客户端来浏 览HDFS文件系统 – 用户可以从HDFS文件系统下载文档到本地文件系统 – 用户可以通过挂载点直接流化数据,支持文件附加, 但是不支持随机写 – NFS网关支持NFSv3和允许HDFS作为客户端文件系统 的一部分被挂载
新机器192.168.5.65 nfsgw
192.168.5.66 localhost
添加/etc/hosts,然后同步给其他集群主机
192.168.5.60 nn01
192.168.5.61 node1 192.168.5.62 node2 192.168.5.63 node3 192.168.5.64 newnode 192.168.5.65 nfsgw安装 java-1.8.0-openjdk-devel
卸载rpcbind nfs-utils
nfsgw服务器和nn01上配置用户
]# useradd nfsgw ; useradd nn01
]# groupadd -g 800 nfsuser ]# useradd -u 800 -g 800 -r -d /var/hadoop nfsuser
[root@nn01 hadoop]# ./sbin/stop-all.sh 停止集群
[root@nn01 hadoop]# vim etc/hadoop/core-site.xml
<property>
<name>hadoop.proxyuser.nfsuser.groups</name> <value>*</value> </property> <property> <name>hadoop.proxyuser.nfsuser.hosts</name> <value>*</value> </property>同步/usr/local/hadoop给其他集群主机(node1,node2,node3)
启动集群
jps
hdfs dfsadmin -report
[root@nfsgw ~]# rsync -aSH --delete nn01:/usr/local/hadoop /usr/local
[root@nfsgw ~]# vim /usr/local/hadoop/etc/hadoop/hdfs-site.xml
<configuration>
<property>
<name>nfs.exports.allowed.hosts</name> <value>* rw</value> </property><property>
<name>nfs.dump.dir</name> <value>/var/nfstmp</value> </property></configuration>
[root@nfsgw ~]# mkdir /var/nfstmp
[root@nfsgw ~]# chown 800.800 /var/nfstmp [root@nfsgw ~]# ls -ld /var/nfstmp drwxr-xr-x 2 nfsuser nfsuser 6 6月 21 16:47 /var/nfstmp[root@nfsgw ~]# cd /usr/local/hadoop/
[root@nfsgw hadoop]# rm -rf logs/* [root@nfsgw hadoop]# setfacl -m nfsuser:rwx logs/[root@nfsgw hadoop]# ./sbin/hadoop-daemon.sh --script ./bin/hdfs start portmap 使用root启动portmap服务
[root@nfsgw hadoop]# sudo -u nfsuser ./sbin/hadoop-daemon.sh --script ./bin/hdfs start nfs3 使用代理用户启动nfs3
[root@nfsgw hadoop]# jps 23659 Nfs3 23596 Portmap 23710 Jps
pormap(root用户先起服务,停的话后停,先停nfs)
nfs3(nfsuser用户后起服务,)
atime 访问的时间
ctmie 改变的时间
mtime 修改的时间
客户端192.168.5.66测试
[root@localhost ~]# yum -y install nfs-utils
[root@localhost ~]# mount -t nfs -o vers=3,proto=tcp,noatime,nolock,sync,noacl 192.168.5.65:/ /mnt
[root@localhost ~]# ls /mnt
开源的分布式应用程序协调服务
保证数据在集群间的事务一致性
应用场景
– 集群分布式锁 – 集群统一命名服务 – 分布式协调服务
• Zookeeper角色与特性
– Leader:接受所有Follower的提案请求并统一协调发起 提案的投票,负责与所有的Follower进行内部数据交换 – Follower:直接为客户端服务并参与提案的投票,同时 与Leader进行数据交换 – Observer:直接为客户端服务但并不参与提案的投票, 同时也与Leader进行数据交换
• Zookeeper角色与选举
– 服务在启动的时候是没有角色的(LOOKING) – 角色是通过选举产生的 – 选举产生一个Leader,剩下的是Follower • 选举Leader原则 – 集群中超过半数机器投票选择Leader – 假如集群中拥有n台服务器,那么Leader必须得到 n/2+1台服务器的投票
• Zookeeper角色与选举
– 如果Leader死亡,重新选举Leader – 如果死亡的机器数量达到一半,则集群挂掉 – 如果无法得到足够的投票数量,就重新发起投票,如果参与投票的机器不足n/2+1,则集群停止工作 – 如果Follower死亡过多,剩余机器不足n/2+1,则集群也会停止工作 – Observer不计算在投票总设备数量里面
• Zookeeper可伸缩扩展性原理与设计
– Leader所有写相关操作 – Follower读操作与响应Leader提议 – 在Observer出现以前,Zookeeper的伸缩性由Follower 来实现,我们可以通过添加Follower节点的数量来保证 Zookeeper服务的读性能,但是随着Follower节点数量 的增加,Zookeeper服务的写性能受到了影响
• Zookeeper可伸缩扩展性原理与设计
– 客户端提交一个请求,若是读请求,则由每台Server的本地 副本数据库直接响应。若是写请求,需要通过一致性协议 (Zab)来处理 – Zab协议规定:来自Client的所有写请求都要转发给ZK服务 中唯一的Leader,由Leader根据该请求发起一个Proposal。 然后其他的Server对该Proposal进行Vote。之后Leader对 Vote进行收集,当Vote数量过半时Leader会向所有的 Server发送一个通知消息。最后当Client所连接的Server收 到该消息时,会把该操作更新到内存中并对Client的写请求 做出回应– ZooKeeper在上述协议中实际扮演了两个职能。一方面从 客户端接受连接与操作请求,另一方面对操作结果进行投票。 这两个职能在Zookeeper集群扩展的时候彼此制约 – 从Zab协议对写请求的处理过程中可以发现,增加Follower 的数量,则增加了协议投票过程的压力。因为Leader节点 必须等待集群中过半Server响应投票,是节点的增加使得部 分计算机运行较慢,从而拖慢整个投票过程的可能性也随之 提高,随着集群变大,写操作也会随之下降
– 所以,我们不得不在增加Client数量的期望和我们希望保
持较好吞吐性能的期望间进行权衡。要打破这一耦合关系, 我们引入了不参与投票的服务器Observer。Observer可 以接受客户端的连接,并将写请求转发给Leader节点。但 Leader节点不会要求Observer参加投票,仅仅在上述第3 歩那样,和其他服务节点一起得到投票结果
– Observer的扩展,给Zookeeper的可伸缩性带来了全
新的景象。加入很多Observer节点,无须担心严重影 响写吞吐量。但并非是无懈可击,因为协议中的通知 阶段,仍然与服务器的数量呈线性关系。但是这里的 串行开销非常低。因此,我们可以认为在通知服务器 阶段的开销不会成为瓶颈 – Observer提升读性能的可伸缩性 – Observer提供了广域网能力
[root@nn01 ~]# tar -xf zookeeper-3.4.13.tar.gz
[root@nn01 ~]# mv ~/zookeeper-3.4.13 /usr/local/zookeeper
[root@nn01 ~]# cd /usr/local/zookeeper/
[root@nn01 zookeeper]#cd conf/
[root@nn01 conf]# mv zoo_sample.cfg zoo.cfg[root@nn01 conf]# vim zoo.cfg
server.1=node1:2888:3888
server.2=node2:2888:3888 server.3=node3:2888:3888 server.4=nn01:2888:3888:observerscp -r /usr/local/zookeeper node1:/usr/local
scp -r /usr/local/zookeeper node2:/usr/local scp -r /usr/local/zookeeper node3:/usr/local
mkdir /tmp/zookeeper #所有集群上创建
node1]# echo 1 > /tmp/zookeeper/myid 请确保每个server的myid文件中id数字不同,server.id中的id与myid中的id必须一致
node2]# echo 2 > /tmp/zookeeper/myid id的范围是1~255
node3]# echo 3 > /tmp/zookeeper/myid
nn01]# echo 4 > /tmp/zookeeper/myid
启动集群,查看验证(在所有集群节点执行)
/usr/local/zookeeper/bin/zkServer.sh start
/usr/local/zookeeper/bin/zkServer.sh status #刚启动一个查看状态为不运行的,因为还需投票,等全部起完了就运行了
Zookeeper管理文档
http://zookeeper.apache.org/doc/r3.4.10/zookeeperAdmin.html man bash ---> 搜索/dev/tcp /dev/fd/fd If fd is a valid integer, file descriptor fd is duplicated. /dev/stdin File descriptor 0 is duplicated. /dev/stdout File descriptor 1 is duplicated. /dev/stderr File descriptor 2 is duplicated. /dev/tcp/host/port If host is a valid hostname or Internet address, and port is an integer port number or service name, bash attempts to open a TCP connection to the corresponding socket. /dev/udp/host/port If host is a valid hostname or Internet address, and port is an integer port number or service name, bash attempts to open a UDP connection to the corresponding socket. |
[root@nn01 ~]# vim zkstats #检测zookeeper状态脚本
#!/bin/bash
function getzkstat(){ exec 2>/dev/null exec 8<>/dev/tcp/$1/2181 echo stat >&8 Msg=$(cat <&8 |grep -P "^Mode:") echo -e "$1\t${Msg:-Mode: \x1b[31mNULL\x1b[0m}" exec 8<&- }if (( $# == 0 ));then
echo "${0##*/} zk1 zk2 zk3 ... ..." else for i in $@;do getzkstat ${i} done fi [nn01 ~]# ./zkstats node{1..3}
– Kafka是由LinkedIn开发的一个分布式的消息系统
– Kafka是使用Scala编写 – Kafka是一种消息中间件 • 为什么要使用Kafka – 解耦、冗余、提高扩展性、缓冲 – 保证顺序,灵活,削峰填谷 – 异步通信
• Kafka角色与集群结构
– producer:生产者,负责发布消息 – consumer:消费者,负责读取处理消息 – topic:消息的类别 – Parition:每个Topic包含一个或多个Partition – Broker:Kafka集群包含一个或多个服务器• Kafka通过Zookeeper管理集群配置,选举Leader
• Kafka集群的安装配置
– Kafka集群的安装配置依赖Zookeeper,搭建Kafka集群之前,请先创建好一个可用的Zookeeper集群 – 安装OpenJDK运行环境 – 同步Kafka拷贝到所有集群主机 – 修改配置文件 – 启动与验证
vim /usr/local/kafka/config/server.properties
broker.id=1 #每台服务器的broker.id都不能相同 zookeeper.connect=node1:2181,node2:2181,node3:2181 #zookeeper集群地址,不用都列出,写一部分即可 [root@nn01 kafka]# for i in node{1..3}; do scp -r /usr/local/kafka ${i}:/usr/local ; done/usr/local/kafka/bin/kafka-server-start.sh -daemon /usr/local/kafka/config/server.properties #所有主机启动服务
– jps命令应该能看到Kafka模块 – netstat应该能看到9092在监听[root@node1 ~]# /usr/local/kafka/bin/kafka-topics.sh --create --partitions 2 --replication-factor 2 --zookeeper localhost:2181 --topic mymsg #创建一个topic
Created topic "mymsg".
[root@node2 ~]# /usr/local/kafka/bin/kafka-console-producer.sh --broker-list localhost:9092 --topic mymsg #生产者
发布消息,随便打一些字符串[root@node3 kafka]# /usr/local/kafka/bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic mymsg #消费者
接收消息,上面打的字符串会在这同步显示
为什么需要NameNode
• 原因 – NameNode是HDFS的核心配置,HDFS又是Hadoop核心组件,NameNode在Hadoop集群中至关重要 – NameNode宕机,将导致集群不可用,如果NameNode数据丢失将导致整个集群的数据丢失,而NameNode的数据的更新又比较频繁,实现NameNode高可用势在必行
• 官方提供了两种解决方案
– HDFS with NFS – HDFS with QJM • 两种方案异同NFS | QJMNN | NN ZK | ZK ZKFailoverController | ZKFailoverController NFS | JournalNode
• HA方案对比
– 都能实现热备 – 都是一个Active NN和一个Standby NN – 都使用Zookeeper和ZKFC来实现自动失效恢复 – 失效切换都使用Fencin配置的方法来Active NN – NFS数据共享变更方案把数据存储在共享存储里,我们还需要考虑NFS的高可用设计 – QJM不需要共享存储,但需要让每一个DN都知道两个NN的位置,并把块信息和心跳包发送给Active和Standby这两个NN
• 使用原因(QJM)
– 解决NameNode单点故障问题 – Hadoop给出了HDFS的高可用HA方案:HDFS通常由两 个NameNode组成,一个处于Active状态,另一个处于 Standby状态。Active NameNode对外提供服务,比如 处理来自客户端的RPC请求,而Standby NameNode则 不对外提供服务,仅同步Active NameNode的状态,以 便能够在它失败时进行切换 • 典型的HA集群 – NameNode会被配置在两台独立的机器上,在任何时 候 , 一 个 NameNode 处 于 活 动 状 态 , 而 另 一 个 NameNode则处于备份状态 – 活动状态的NameNode会响应集群中所有的客户端, 备份状态的NameNode只是作为一个副本,保证在必 要的时候提供一个快速的转移
• NameNode高可用架构
– 为了让Standby Node与Active Node保持同步,这两个 Node 都 与 一 组 称 为 JNS 的 互 相 独 立 的 进 程 保 持 通 信 (Journal Nodes)。当Active Node更新了namespace, 它将记录修改日志发送给JNS的多数派。Standby Node将 会从JNS中读取这些edits,并持续关注它们对日志的变更 – Standby Node将日志变更应用在自己的namespace中, 当Failover发生时,Standby将会在提升自己为Active之前, 确保能够从JNS中读取所有的edits,即在Failover发生之前 Standy持有的namespace与Active保持完全同步 – NameNode更新很频繁,为了保持主备数据的一致性, 为了支持快速Failover,Standby Node持有集群中 blocks的最新位置是非常必要的。为了达到这一目的, DataNodes上需要同时配置这两个Namenode的地址, 同时和它们都建立心跳连接,并把block位置发送给它们
– 任何时刻,只能有一个Active NameNode,否则会导致
集群操作混乱,两个NameNode将会有两种不同的数据 状态,可能会导致数据丢失或状态异常,这种情况通常 称为"split-brain"(脑裂,三节点通讯阻断,即集群中不 同的DataNode看到了不同的Active NameNodes) – 对于JNS而言,任何时候只允许一个NameNode作为 writer;在Failover期间,原来的Standby Node将会接 管Active的所有职能,并负责向JNS写入日志记录,这种 机制阻止了其他NameNode处于Active状态的问题
系统规划:
新准备机器 192.168.5.66 nn02
免密码登录
[root@nn02 ~]# scp -r 192.168.5.60:/root/.ssh /root
[root@nn02 ~]# cd ./.ssh [root@nn02 .ssh]# ls authorized_keys id_rsa id_rsa.pub known_hosts [root@nn02 .ssh]# rm -rf known_hosts[root@nn01 ~]# vim /etc/hosts
# ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 192.168.5.60 nn01 192.168.5.61 node1 192.168.5.62 node2 192.168.5.63 node3 192.168.5.65 nfsgw 192.168.5.66 nn02 ]# for i in 61 62 63 66; do scp /etc/hosts 192.168.5.$i:/etc; done
关机重启(全部)
再开启zookeeper
/usr/local/zookeeper/bin/zkServer.sh start #node{1..3},nn01都起zookeeper服务
]# jps
[root@nn01 ~]# rm -rf /var/hadoop/*
[root@nn01 ~]# ssh node1 rm -rf /var/hadoop/* [root@nn01 ~]# ssh node2 rm -rf /var/hadoop/* [root@nn01 ~]# ssh node3 rm -rf /var/hadoop/* [root@nn01 ~]# rm -rf /usr/local/hadoop/logs/*
[root@nn02 ~]# mkdir /var/hadoop
yarn高可用 • ResourceManager高可用 – RM的高可用原理与NN一样,需要依赖ZK来实现,这里配置文件的关键部分,感兴趣的同学可以自己学习和测试 – yarn.resourcemanager.hostname – 同理因为使用集群模式,该选项应该关闭 |
[root@nn01 hadoop]# cd /usr/local/hadoop/etc/hadoop/
0. [root@nn01 hadoop]# vim hadoop-env.sh
export JAVA_HOME="/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.161-2.b14.el7.x86_64/jre"
export HADOOP_CONF_DIR="/usr/local/hadoop/etc/hadoop"
1. [root@nn01hadoop]# vim core-site.xml
<configuration>
<property> <name>fs.defaultFS</name> <value>hdfs://nsd1902</value> </property> <property> <name>hadoop.tmp.dir</name> <value>/var/hadoop</value> </property> <property> <name>ha.zookeeper.quorum</name> <value>node1:2181,node2:2181,node3:2181</value> </property> <property> <name>hadoop.proxyuser.nfsuser.groups</name> <value>*</value> </property> <property> <name>hadoop.proxyuser.nfsuser.hosts</name> <value>*</value> </property> </configuration> ~
2. vim hdfs-site.xml
<configuration>
<property> <name>dfs.nameservices</name> #指定hdfs的nameservices名称 <value>nsd1902</value> </property> <property> <name>dfs.ha.namenodes.nsd1902</name> #指定集群的两个namenode的名称分别为nn1,nn2 <value>nn1,nn2</value> #这里不是指主机名 </property> <property> <name>dfs.namenode.rpc-address.nsd1902.nn1</name> #配置nn1,nn2的rpc通信端口 <value>nn01:8020</value> </property> <property> <name>dfs.namenode.rpc-address.nsd1902.nn2</name> <value>nn02:8020</value> </property> <property> <name>dfs.namenode.http-address.nsd1902.nn1</name> #配置nn1,nn2的http通信端口 <value>nn01:50070</value> </property> <property> <name>dfs.namenode.http-address.nsd1902.nn2</name> <value>nn02:50070</value> </property> <property> <name>dfs.namenode.shared.edits.dir</name> #指定namenode元数据存储在journalnode中的路径 <value>qjournal://node1:8485;node2:8485;node3:8485/nsd1902</value> </property> <property> <name>dfs.journalnode.edits.dir</name> #指定journalnode日志文件存储路径 <value>/var/hadoop/journal</value> </property> <property> <name>dfs.client.failover.proxy.provider.nsd1902</name> #指定HDFS客户端连接Active NameNode的java类 <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value> </property> <property> <name>dfs.ha.fencing.methods</name> #配置隔离机制为ssh <value>sshfence</value> </property> <property> <name>dfs.ha.fencing.ssh.private-key-files</name> #指定密钥的位置 <value>/root/.ssh/id_rsa</value> </property> <property> <name>dfs.ha.automatic-failover.enabled</name> #开启自动故障转移 <value>true</value> </property> <property> <name>dfs.replication</name> <value>2</value> </property> <property> <name>dfs.hosts.exclude</name> <value>/usr/local/hadoop/etc/hadoop/exclude</value> </property> </configuration>
3. vim mapred-site.xml
<configuration>
<property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> </configuration>
4. vim slaves
node1
node2 node3
5. vim yarn-site.xml
<configuration>
<property> <name>yarn.resourcemanager.ha.enabled</name> <value>true</value> </property> <property> <name>yarn.resourcemanager.ha.rm-ids</name> <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> <!-- Site specific YARN configuration properties --> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> </configuration>
6. vim exclude 把里面的内容删除
集群初始化:
– ALL: 代表所有机器
– nodeX: 代表node1 node2 node3 (标示方便全部一起操作)– ALL: 同步配置到所有集群机器
for i in node{1..3} nn02; do scp -r /usr/local/hadoop ${i}:/usr/local & done
– NN1: 初始化ZK集群 # ./bin/hdfs zkfc -formatZK – nodeX: 启动journalnode服务 # ./sbin/hadoop-daemon.sh start journalnode
• 初始化
– NN1: 格式化 # ./bin/hdfs namenode -format – NN2: 数据同步到本地/var/hadoop/dfs # rsync -aSH nn01:/var/hadoop/dfs /var/hadoop/ – NN1: 初始化JNS # ./bin/hdfs namenode -initializeSharedEdits – nodeX: 停止journalnode服务 # ./sbin/hadoop-daemon.sh stop journalnode
• 启动集群
– NN1: 启动hdfs # ./sbin/start-dfs.sh – NN1: 启动yarn # ./sbin/start-yarn.sh – NN2: 启动热备ResourceManager # ./sbin/yarn-daemon.sh start resourcemanager
• 查看集群状态
– 获取NameNode状态 # ./bin/hdfs haadmin -getServiceState nn1 # ./bin/hdfs haadmin -getServiceState nn2 – 获取ResourceManager状态 # ./bin/yarn rmadmin -getServiceState rm1 # ./bin/yarn rmadmin -getServiceState rm2
– 获取节点信息 # ./bin/hdfs dfsadmin -report #查看有3台集群节点 # ./bin/yarn node -list – 访问集群文件 # ./bin/hadoop fs -mkdir /input # ./bin/hadoop fs -ls hdfs://mycluster/ – 主从切换Activate # ./sbin/hadoop-daemon.sh stop namenode (把Activate的那台namenode停掉服务)
./bin/hadoop fs -put *.txt /input
./sbin/hadoop-daemon.sh start namenode
./bin/hadoop fs -ls /input
转载地址:http://eriqi.baihongyu.com/