大数据的由来
• 大数据
– 随着计算机技术的发展,互联网的普及,信息的积累
已经到了一个非常庞大的地步,信息的增长也在不断
的加快,随着互联网、物联网建设的加快,信息更是
爆炸是增长,收集、检索、统计这些信息越发困难,
必须使用新的技术来解决这些问题
什么是大数据
• 大数据的定义
– 大数据指无法在一定时间范围内用常规软件工具进行捕捉、
管理和处理的数据集合,需要新处理模式才能具有更强的
决策力、洞察发现力和流程优化能力的海量、高增长率和
多样化的信息资产
– 是指从各种各样类型的数据中,快速获得有价值的信息
• 大数据能做什么
– 企业组织利用相关数据分析帮助他们降低成本、提高
效率、开发新产品、做出更明智的业务决策等
– 把数据集合并后进行分析得出的信息和数据关系性,
用来察觉商业趋势、判定研究质量、避免疾病扩散、
打击犯罪或测定即时交通路况等
– 大规模并行处理数据库,数据挖掘电网,分布式文件
系统或数据库,云计算平和可扩展的存储系统等
特性
- 大体量– (V)olume (大体量)
可从数百TB到数十数百PB、甚至EB的规模 - 速度快– (V)elocity(时效性)
很多大数据需要在一定的时间限度下得到及时处理 - 不限种类– (V)ariety(多样性)
大数据包括各种格式和形态的数据 - 统计分析,预测性– (V)alue(大价值)
大数据包含很多深度的价值,大数据分析挖掘和利用将带来巨大
的商业价值 - 真实性– (V)eracity(准确性)
处理的结果要保证一定的准确性
hadoop
开源,基于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组件
组件
- HDFS: Hadoop分布式文件系统(核心组件) 存储
- MapReduce: 分布式计算框架(核心组件)
- Yarn: 集群资源管理系统(核心组件)
- Zookeeper: 分布式协作服务
- Hbase: 分布式列存数据库
- Hive: 基于Hadoop的数据仓库
- Sqoop: 数据同步工具
- Pig: 基于hadoop的数据流系统
- Mahout: 数据挖掘算法库
- Flume: 日志收集工具
HDFS
结构
Hadoop体系中数据存储管理的基础,是一个高度容错的系统,用于在低成本的通用硬件上运行
- 角色
client
namenode
secondarynode
datanode
• NameNode
– Master节点,管理HDFS的名称空间和数据块映射信
息(fsimage),配置副本策略,处理所有客户端请求
• Secondary NameNode
– 定期合并fsimage 和fsedits,推送给NameNode
– 紧急情况下,可辅助恢复NameNode
fsedits 变更日志(打补丁)
• 但Secondary NameNode并非NameNode的热备
• DataNode
– 数据存储节点,存储实际的数据
– 汇报存储信息给NameNode
• Client
– 切分文件
– 访问HDFS
– 与NameNode交互,获取文件位置信息
– 与DataNode交互,读取和写入数据
block 每块缺省128MB大小,每块可以多个副本
MapReduce
结构
• 源自于Google的MapReduce论文,JAVA实现的分布式计算框架
• 角色和概念
– JobTracker
Master节点只有一个,管理所有作业/任务的监控、错误处理等
将任务分解成一系列任务,并分派给TaskTracker
– TaskTracker
Slave节点,一般是多台,运行Map Task和Reduce Task
并与JobTracker交互,汇报任务状态
– Map Task
解析每条数据记录,传递给用户编写的
map()并执行,将输出结果写入本地磁盘
– 如果为map-only作业,直接写入HDFS
– Reducer Task
从Map Task的执行结果中,远程读
取输入数据,对数据进行排序,将数据按照分组传递
给用户编写的reduce函数执行
Yarn
结构
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 share
etc 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
HDFS分布式文件系统
需修改的配置文件
– 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
https://hadoop.apache.org/docs/r2.7.7/hadoop-project-dist/hadoop-common/core-default.xml
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
http://192.168.5.60:8088/ resourcemanager WEB页面(nn01)
http://192.168.5.61:8042/ nodemanager WEB页面(node1 node2 node3)
http://192.168.5.60:50090/ secondory namenode WEB页面
http://192.168.5.60:50070/ namenode WEB页面
http://192.168.5.61:50075/ 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
newnode
nn01 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
开源的分布式应用程序协调服务
保证数据在集群间的事务一致性
应用场景
– 集群分布式锁
– 集群统一命名服务
– 分布式协调服务
• 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:observer
scp -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 |
[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
– 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 #消费者
接收消息,上面打的字符串会在这同步显示
Haddop高可用
为什么需要NameNode
• 原因
– NameNode是HDFS的核心配置,HDFS又是Hadoop核心组件,NameNode在Hadoop集群中至关重要
– NameNode宕机,将导致集群不可用,如果NameNode数据丢失将导致整个集群的数据丢失,而NameNode的数据的更新又比较频繁,实现NameNode高可用势在必行
• 官方提供了两种解决方案
– HDFS with NFS
– HDFS with QJM
• 两种方案异同
NFS | QJM
NN | 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