Hadoop 核心组件
  HDFS 角色及概念
是Hadoop体系中数据存储管理的基础。它是一个高度容错的系统,用于在低成本的通用硬件上运行。

角色和概念
– Client
– Namenode
– Secondarynode
– Datanode

NameNode
– Master节点,管理HDFS的名称空间和数据块映射信
息,配置副本策略,处理所有客户端请求。

Secondary NameNode
– 定期合并 fsimage 和fsedits,推送给NameNode
– 紧急情况下,可辅助恢复NameNode,
但Secondary NameNode并非NameNode的热备。

DataNode
– 数据存储节点,存储实际的数据
– 汇报存储信息给NameNode。

Client
– 切分文件
– 访问HDFS
– 与NameNode交互,获取文件位置信息
– 与DataNode交互,读取和写入数据。

Block
– 每块缺省64MB大小
– 每块可以多个副本

Mapreduce 角色及概念
源自于google的MapReduce论文,JAVA实现的分
布式计算框架

角色和概念
– JobTracker
– TaskTracker
– Map Task
– Reducer Task

JobTracker
– Master节点,只有一个
– 管理所有作业
– 作业/任务的监控、错误处理等
– 将任务分解成一系列任务,并分派给TaskTracker。

TaskTracker
– Slave节点,一般是多台
– 运行Map Task和Reduce Task
– 并与JobTracker交互,汇报任务状态。

Map Task:解析每条数据记录,传递给用户编写的map(),并执行,将输出结果写入本地磁盘(如果为map-only作业,直接写入HDFS)。
Reducer Task:从Map Task的执行结果中,远程读取输入数据,对数据进行排序,将数据按照分组传递给用户编写的reduce函数执行。

Yarn 角色及概念
Yarn 是 Hadoop 的一个通用的资源管理系统

Yarn 角色
– Resourcemanager
– Nodemanager
– ApplicationMaster
– Container
– Client

ResourceManager
– 处理客户端请求
– 启动 / 监控 ApplicationMaster
– 监控 NodeManager
– 资源分配与调度

NodeManager
– 单个节点上的资源管理
– 处理来自 ResourceManager 的命令
– 处理来自 ApplicationMaster 的命令

Container
– 对任务运行行环境的抽象,封装了 CPU 、内存等
– 多维资源以及环境变量、启动命令等任务运行相关的信息资源分配与调度

ApplicationMaster
– 数据切分
– 为应用程序申请资源,并分配给内部任务
– 任务监控与容错

Client
– 用户与 YARN 交互的客户端程序
– 提交应用程序、监控应用程序状态,杀死应用程序等

YARN 的核心思想
 将 JobTracker 和 TaskTacker 进行分离,它由下面几大构成组件:
– ResourceManager 一个全局的资源管理器
– NodeManager 每个节点(RM)代理
– ApplicationMaster 表示每个应用
– 每一个 ApplicationMaster 有多个 Container 在NodeManager 上运行

  Hadoop 安装配置
Hadoop 的部署模式有三种
– 单机
– 伪分布式
– 完全分布式

Hadoop 的单机模式安装非常简单
– 1、获取软件
http://hadoop.apache.org
– 2、安装配置 java 环境,安装 jps 工具
安装 Openjdk 和 openjdk-devel
– 3、设置环境变量,启动运行
– hadoop-env.sh
JAVA_HOME=“”

安装依赖
yum -y install  java-1.8.0-openjdk-devel  java-1.8.0-openjdk 

安装hadoop
tar -xf hadoop-2.7.3.tar.gz
mv hadoop-2.7.3 /usr/local/hadoop
cd /usr/local/hadoop
vim /usr/local/hadoop/etc/hadoop/hadoop-env.sh
....
export JAVA_HOME="/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.65-3.b17.el7.x86_64/jre/"
....
export HADOOP_CONF_DIR="/usr/local/hadoop/etc/hadoop"

mkdir input 
cp *.txt input    
./bin/hadoop jar ./share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.3.jar wordcount(标准字) input(上传文件名)  output 
  (统计数据)
cat output/part-r-00000 

   Hadoop 伪分布式
– 伪分布式的安装和完全分布式类似,但区别是所有角色安装在一台机器上,使用本地磁盘,一般生产环境都会使用完全分布式,伪分布式一般用来学习和测试方面的功能
– 伪分布式的配置和完全分布式配置类似

– Hadoop-env.sh
JAVA_HOME
HADOOP_CONF_DIR

http://hadoop.apache.org/docs/r2.7.5/hadoop-project-dist/hadoop-common/core-default.xml
– Xml 文件配置格式

关键字
变量值
 描述 


core-site.xml
– 关键配置
  fs.defaultFS
  hdfs://localhost:9000

– 常用配置
hadoop.tmp.dir

hdfs-site.xml
  dfs.replication
  dfs.namenode.name.dir
  dfs.datanode.data.dir
  dfs.namenode.http-address
  dfs.namenode.secondary.http-address
  dfs.webhdfs.enabled
  dfs.permissions.enabled

yarn-site.xml
  yarn.nodemanager.aux-services
  yarn.nodemanager.aux-services.mapreduce.shuffle.class
  yarn.resourcemanager.address
  yarn.resourcemanager.scheduler.address
  yarn.resourcemanager.resource-tracker.address
  yarn.resourcemanager.admin.address
  yarn.resourcemanager.webapp.address

   HDFS 完全分布式系统配置
master 192.168.4.10 部署:NameNode ,Secondary NameNode , Resourcemanager
Data  部署:DataNode  ,Nodemanager

vim /etc/hosts
192.168.4.10  master
192.168.4.11  Data1
192.168.4.12  Data2
192.168.4.13  Data3

1、安装操作系统
– 注意:只开启必要的服务,关闭其他无关的系统服务,
系统最小化,服务最小化
– 注意:关闭系统防火墙
– 注意:关闭 selinux
– iptables-save
– sestatus

2、在所有系统上安装 JAVA 环境和调试工具 jps
– 注意:保证所有机器系统版本及 java 版本的一致性
– 注意:保证所有安装路径的一致性
– java –version
– jps

3、配置 主机名 和 ip 对应关系 /etc/hosts
– 注意 :所有主机的配置都需要修改
– 注意 : master 要能 ping 通所有主机
– 注意 : node 要能 ping 通 master

4、配置 SSH 信任关系
– 注意:不能出现要求输入 yes 的情况,每台机器都要
能登录成功
– ssh-keygen -b 2048 -t rsa -N '' -f key
– ssh-copy-id -i ./key.pub [email protected]

5、HDFS 完全分布式配置
配置 HADOOP_CONF_DIR 路径
/usr/local/hadoop/etc/hadoop
vim hadoop-env.sh
which java
readlink –f $(which java)
– JAVA_HOME=“”
HADOOP_CONF_DIR=${HADOOP_CONF_DIR:-"/etc/hadoop"} 

 HDFS 完全分布式系统配置
– 配置 hadoop-env.sh
– 配置 core-site.xml
– 配置 hdfs-site.xml

  配置hdfs-site.xml
– dfs.namenode.http-address
– dfs.namenode.secondary.http-address
– dfs.namenode.name.dir
– dfs.datanode.data.dir
– dfs.replication
– dfs.webhdfs.enabled
– dfs.permissions.enabled

cd /usr/local/hadoop
vim /usr/local/hadoop/etc/hadoop/hadoop-env.sh
....
export JAVA_HOME="/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.65-3.b17.el7.x86_64/jre/"
....
export HADOOP_CONF_DIR="/usr/local/hadoop/etc/hadoop"

vim  /usr/local/hadoop/etc/hadoop/core-site.xml 
.....

 
   fs.defaultFS
   hdfs://master:9000  #masterIP地址
 
 
   hadoop.tmp.dir
   /var/hadoop     #路径
   A base for other temporary directories.
 


注意:所有机器上都要创建
mkdir –p /var/hadoop

vim /usr/local/hadoop/etc/hadoop/hdfs-site.xml
.....

 
   dfs.namenode.http-address  #namenode在matser上
   master:50070     #masterIP地址
 
 
   dfs.namenode.secondary.http-address #namenode.secondary也搭在master上
   master:50090  
 
 
   dfs.replication
   2
 


vim /usr/local/hadoop/etc/hadoop/slaves
node1
node2
node3

 hdfs-site.xml配置项
– dfs.namenode.http-address
– dfs.namenode.secondary.http-address
– dfs.namenode.name.dir
– dfs.datanode.data.dir
– dfs.replication
– dfs.webhdfs.enabled
– dfs.permissions.enabled

配置完成以后,把 hadoop 的文件夹拷贝到所有机器
– 在 namenode 上执行格式化操作
/usr/local/hadoop/bin/hdfs namenode –format
– 在没有报错的情况下启动集群
/usr/local/hadoop/sbin/start-dfs.sh

验证:
启动以后分别在 namenode 和 datanode执行命令
jps
– 成功的情况下应该可以看见
– NameNode
– SecondaryNode
– DataNode

/usr/local/hadoop/bin/hdfs --help
/usr/local/hadoop/bin/hdfs dfsadmin -report (查看节点数)
.......
-------------------------------------------------
Live datanodes (3):
.......

HDFS 基本命令
/usr/local/hadoop/bin/hadoop fs –ls /
– 对应 shell 命令 ls /
/usr/local/hadoop/bin/hadoop fs –mkdir /abc
– 对应 shell 命令 mkdir /abc
/usr/local/hadoop/bin/hadoop fs –rmdir /abc
– 对应 shell 命令 rmdir /abc

– 上传文件
/usr/local/hadoop/bin/hadoop fs –put localfile /remotefile
– 下载文件
/usr/local/hadoop/bin/hadoop fs –get /remotefile

cd /usr/local/hadoop
/usr/local/hadoop/bin/hadoop fs -mkdir /abc
/usr/local/hadoop/bin/hadoop  fs -put *.txt  /abc
/usr/local/hadoop/bin/hadoop fs -ls /abc

  Yarn 安装与配置
yarn 配置文件
– mapred-site.xml
– yarm-site.xml
cd /usr/local/hadoop/etc/hadoop
cp mapred-site.xml.template mapred-site.xml

vim mapred-site.xml
...

 
  mapreduce.framework.name
  yarn
 

...

vim yarn-site.xml
.....


 
   yarn.nodemanager.aux-services
   mapreduce_shuffle
 
 
  yarn.resourcemanager.hostname
  master
 

....

配置完成以后把配置同步到所有主机
– 启动 yarn 服务
/usr/local/hadoop/sbin/start-yarn.sh
– 在所有主机上执行 jps ,查看是否启动成功
resourcemanager
nodemanager

for i in  11 12 13  ;do  scp -r  /usr/local/hadoop/etc/hadoop/mapred-site.xml yarn-site.xml  192.168.4.$i:/usr/local/hadoop/etc/hadoop/mapred-site.xml yarn-site.xml ;done

/usr/local/hadoop/bin/yarn --help
/usr/local/hadoop//bin/yarn node -list
Total Nodes:3

  完全分布式
Hadoop最大的优势就是分布式集群计算,所以在生产环境下都是搭建的最后一种模式:完全分布模式

http://192.168.4.10:50070    namenode
http://192.168.4.10:50090    secondarynamenode
http://192.168.4.11:50075    datanode  
http://192.168.4.10:8088     resourcemanager
http://192.168.4.11:8042     nodemangager

Hadoop 验证
创建文件夹
/usr/local/hadoop/bin/hadoop fs –mkdir /input
导入要分析的文件
/usr/local/hadoop/bin/hadoop fs –put *.txt /input

提交分析
– ./bin/hadoop jar ./share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.3.jar wordcount /input  /output
• 查看结果
– ./bin/hadoop fs –cat /output/part-r-00000

Access time 打开文件时,变化
Modify time  修改文件时,变化
Change time   修改权限和文件内容等时,变化

    NFS 网关
NFS 网关用途
– 1.用户可以通过操作系统兼容的本地NFSv3客户端来阅览HDFS文件系统
– 2.用户可以从HDFS文件系统下载文档到本地文件系统
– 3.用户可以通过挂载点直接流化数据。支持文件附加,但是不支持随机写
– NFS 网关支持NFSv3和允许HDFS 作为客户端文件系统的一部分被挂载

特性与注意事项
– 不支持随机写
– 在非安全模式,运行网关的用户是代理用户
– 在安全模式时,Kerberos keytab中的用户是代理用户
– AIX NFS有一些知道的问题,不能让默认的HDFS NFS 网关正常工作,如果想在 AIX 访问 NFS 网关需要配置下面的参数

nfs.aix.compatibility.mode.enabled
true


特性与注意事项

– HDFS超级用户是与NameNode进程本身具有相同标识的用户,超级用户可以执行任何操作,因为权限检查永远不会为超级用户失败。

nfs.superuser
the_name_of_hdfs_superuser


特性与注意事项
– 如果客户端安装允许访问时间更新,在某些Unix系统上,用户可以通过使用“noatime”安装来禁用访问时间更新。

dfs.namenode.accesstime.precision
0
The access time for HDFS file is precise
upto this value.
The default value is 1 hour. Setting a value of 0 disables
access times for HDFS.



特性与注意事项
– nfs.dump.dir
– 用户需要更新文件转储目录参数。NFS客户端经常重新安排写操作,顺序的写操作会以随机到达NFS网关。这个目录常用于临时存储无序的写操作。对于每个文件,无序的写操作会在他们积累在内存中超过一定阈值(如。1 mb)被转储。需要确保有足够的空间的目录。例如,如果应用上传10个100M,那么这个转储目录推荐有1GB左右的空间,以便每个文件都发生最坏的情况。只有NFS网关需要在设置该属性后重启。

特性与注意事项
– nfs.exports.allowed.hosts
– 默认情况下,export可以被任何客户端挂载。为了更好的控制访问,可以设置属性。值字符串为机器名和访问策略,通过空格来分割。机器名的格式可以是单一的主机,Java的正则表达式或者IPv4地址。访问权限使用rw或ro来指定导出目录的读/写或机器只读访问。如果访问策略没被提供,默认为只读的。每个条目使用“;”来分割。

调试与日志排错
– 在配置 NFS 网关过程中经常会碰到各种各样的错误,如果出现了错误,打开调试日志是一个不错的选择。
 log4j.property
– log4j.logger.org.apache.hadoop.hdfs.nfs=DEBUG
– log4j.logger.org.apache.hadoop.oncrpc=DEBUG

NFS & portmap 相关配置
– core-site.xml
– hdfs-site.xml

master:
core-site.xml
– hadoop.proxyuser.{nfsuser}.groups
– hadoop.proxyuser.{nfsuser}.hosts
– 这里的 nfsuser 是你机器上真实运行 nfsgw 的用户
– 在非安全模式,运行nfs网关的用户为代理用户
– groups 为挂载点用户所使用的组
– hosts 为挂载点主机地址

/usr/local/hadoop/sbin/stop-all.sh
vim /usr/local/hadoop/etc/hadoop/core-site.xml
.......

hadoop.proxyuser.nfsuser.groups
*


hadoop.proxyuser.nfsuser.hosts
*

........

adduser -g 10 -u 10003 nfsuser
scp  /usr/local/hadoop/etc/hadoop/core-site.xml 192.168.4.11 12 13:/usr/local/hadoop/etc/hadoop/core-site.xml
/usr/local/hadoop/sbin/start-all.sh

scp -r /usr/local/hadoop/   192.168.4.14:/usr/local/hadoop/      ip14=nfs

nfs:
hdfs-site.xml
– nfs.exports.allowed.hosts
– 设置允许访问 NFS 主机列与权限,默认 “ro”

nfs.exports.allowed.hosts
* rw


hdfs-site.xml
– dfs.namenode.accesstime.precision
– 关闭 access time

dfs.namenode.accesstime.precision
3600000


hdfs-site.xml
– nfs.dump.dir
– 设置转储目录

nfs.dump.dir
/tmp/.hdfs-nfs


hdfs-site.xml
– nfs.rtmax & nfs.wtmax
– 用户可以像访问本地文件系统的一部分一样访问HDFS,但硬链接和随机写还不支持。对于大文件I/O的优化,可以在mount的时候增加NFS传输的大小(rsize和wsize)。在默认情况下,NFS网关支持1MB作为最大的传输大小。更大的数据传输大小,需要在hdfs-site.xml中设置“nfs.rtmax”和“nfs.wtmax”.

hdfs-site.xml
– nfs.rtmax & nfs.wtmax

nfs.rtmax
4194304


nfs.wtmax
1048576


hdfs-site.xml
– nfs.port.monitoring.disabled
– 允许从没有权限的客户端挂载 nfs

nfs.port.monitoring.disabled
false


nfs.map
– 系统管理员必须确保在NFS客户端的用户和在HDFS网关主机上的用户有相同的名称和UID。不同主机上创建的用户需要修改UID(例如使用“usermod -u 123 myusername”),在NFS客户端或者NFS网关主机来进行。如果客户端的用户和NFS网关的用户 uid 不能保持一致需要我们配置 nfs.map 的静态映射关系– nfs.map uid 10 100 # Map the remote UID 10 the local UID 100 gid 11 101 # Map the remote GID 11 to the local GID 101

hdfs-site.xml 基本配置

nfs.exports.allowed.hosts
* rw


nfs.dump.dir
/tmp/.hdfs-nfs


启动与挂载
– 配置完所有的参数以后就可以启动服务了
– 这里要注意 关闭系统的 portmap 和 nfs 服务
– 添加用户
– 首先打开 log4j 的调试日志
– 重启 hdfs 集群服务
– 启动 portmap 服务
– 启动 nfs3 服务

启动与挂载
– 启动 portmap 服务
./sbin/hadoop-daemon.sh --script ./bin/hdfs start portmap
– 启动 nfs3
./sbin/hadoop-daemon.sh --script ./bin/hdfs start nfs3
– 这里要特别注意:
– 启动 portmap 需要使用 root 用户
– 启动 nfs3 需要使用 core-site 里面设置的用户

启动与挂载
– 挂载 nfs
– 目前NFS v3仅使用TCP作为传输协议。 不支持NLM,因此需要安装选项“nolock”。 强烈建议使用安装选项“sync”,因为它可以最小化或避免重新排序写入,这将导致更可预测的吞吐量。 未指定同步选项可能会导致上传大文件时出现不可靠的行为– 如果必须使用软安装,用户应该给它一个相对较长的超时(至少不小于主机上的默认超时)。

启动与挂载
– 挂载 NFS 参数
– vers=3
– proto=tcp
– nolock
– noacl
– noatime
– sync
mount -t nfs -o vers=3,proto=tcp,nolock,noacl,noatime,sync ip.xx.xx.xx:/ /localdir

yum search rpcbind
yum -y remove rpcbind  nfs-utils
vim  hdfs-site.xml
.....

  nfs.exports.allowed.hosts
  * rw


  dfs.namenode.accesstime.precision
  36000000


  nfs.dump.dir
  /var/nfstemp


  nfs.rtmax
  4194304


  nfs.wtmax
  1048576


  nfs.port.monitoring.disabled
  false

......

mkdir /var/nfstemp
chown 1003.10 /var/nfstemp

setfacl -m u:nfsuser:rwx  /usr/local/hadoop/logs/

启动与挂载
– 启动 portmap 服务
/usr/local/hadoop/sbin/hadoop-daemon.sh --script ./bin/hdfs start portmap
– 启动 nfs3
/usr/local/hadoop/sbin/hadoop-daemon.sh --script ./bin/hdfs start nfs3
– 这里要特别注意:
– 启动 portmap 需要使用 root 用户
– 启动 nfs3 需要使用 core-site 里面设置的用户

 客户机
yum -y ins nfs-utils
mount -t nfs -o  vers=3,port=tcp,nolock,sync,noatime,noacl 192.168.4.14:/  /mnt/

   HDFS 增加节点
– 1. 配置所有hadoop环境,包括主机名、ssh免密码登
录、禁用 selinux、iptables、安装 java 环境
– 2. 把namnode的配置文件复制到配置文件目录下
– 3. 修改namenode的slaves文件增加该节点
– 5. 在该节点启动Datanode
./sbin/hadoop-daemon.sh start datanode
– 6. 设置同步带宽,并同步数据
./bin/hdfs dfsadmin -setBalancerBandwidth 67108864
./sbin/start-balancer.sh -threshold 5
– 7. 查看集群状态
./bin/hdfs dfsadmin -report

master:
vim   /usr/local/hadoop/etc/hadoop/slaves
Data1
Data2
Data3
task1  #增加的节点主机名

vim  /etc/hosts
192.168.4.10  master
192.168.4.11  Data1
192.168.4.12  Data2
192.168.4.13  Data3
192.168.4.14  nfs
192.168.4.15  task1

scp /etc/hosts  192.168.4.15:/etc/hosts

scp /usr/local/hadoop/  192.168.4.15:/usr/local/hadoop/

./sbin/hadoop-daemon.sh start datanode

HDFS 删除节点
– 配置NameNode的hdfs-site.xml
– dfs.replication 副本数量
– 增加 dfs.hosts.exclude 配置

dfs.hosts.exclude
/usr/local/hadoop/etc/hadoop/exclude
 Decommissioned 才能删除task1

task1:
./sbin/hadoop-daemon.sh stop datanode

HDFS 修复节点
– 修复节点比较简单
– 单独配置一台新 datanode
– 启动服务
./sbin/hadoop-daemon.sh start datanode
– 数据恢复是自动的
– 我们上线以后会自动恢复数据,如果数据量非常巨大,可能需要一定的时间.

Yarn 的相关操作
– 由于在 2.x hadoop 引入了 yarn 框架,对于计算节点的操作已经变得非常简单
– 增加节点
sbin/yarn-daemon.sh start nodemanager
– 删除节点
sbin/yarn-daemon.sh stop nodemanager
– 查看节点 (Resourcemanager)
./bin/yarn node -list

HDFS 还有很多其他的应用方式,比如 native-hdfs,有兴趣的可以自行测试.
– 用到的软件依赖
– cmake, fuse-devel
– protobuf
– protobuf-c
– native-hdfs-fuse

Hadoop 完全分布式安装的配置
– java 环境
– ssh key 认证
– hosts 配置
– hadoop-env.sh
– core-site.xml
– hdfs-site.xml
– mapred-site.xml
– yarn-site.xml
– slaves

Hadoop NFS网关
– hadoop-env.sh
– core-site.xml
– hdfs-site.xml
– mount 参数

Hadoop 节点管理
– datanode 的增加 删除 修复
– nodemanager 的增加 删除 修复

 zookeeper
– ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务

 ZooKeeper能干什么
– ZooKeeper是用来保证数据在集群间的事务性一致

zookeeper 应用场景
– 集群分布式锁
– 集群统一命名服务
– 分布式协调服务
– ......

zookeeper 角色与特性*
– Leader:(领导)
– 接受所有Follower的提案请求并统一协调发起提案的投票,负责与所有的Follower进行内部的数据交换。
– Follower:(随同)
– 直接为客户端服务并参与提案的投票,同时与Leader进行数据交换。
– Observer:(临时工)
– 直接为客户端服务但并不参与提案的投票,同时也与。
Leader进行数据交换

zookeeper 角色与选举
– 服务在启动的时候是没有角色的 (LOOKING)
– 角色是通过选举产生的
– 选举产生一个 leader,剩下的是 follower
– 选举 leader 原则:
– 集群中超过半数机器投票选择leader.
– 假如集群中拥有n台服务器,那么leader必须得到(n/2)+1台服务器投票
– 如果 leader 死亡,从新选举 leader
– 如果死亡的机器数量达到一半,集群挂起
– 如果无法得到足够的投票数量,就重新发起投票,如果参与投票的机器不足(n/2)+1集群停止工作
– 如果 follower 死亡过多,剩余机器不足(n/2)+1集群也会停止工作
– observer 不计算在投票总设备数量里面

zookeeper 可伸缩扩展性原理与设计
– leader 所有写相关操作
– follower 读操作与响应leader提议
– 在Observer出现以前,ZooKeeper的伸缩性由Follower来实现,我们可以通过添加Follower节点的数量来保证ZooKeeper服务的读性能。但是随看Follower节点数量的增加,ZooKeeper服务的写性能受到了影响。为什么会出现这种情况?在此,我们需要首先了解一下这个"ZK服务"是如何工作的。
– 客户端提交一个请求,若是读请求,则由每台Server的本地副本数据库直接响应。若是写请求,需要通过一致性协议(Zab)来处理
– Zab协议规定:来自Client的所有写请求,都要转发给ZK服务中唯一的Leader,由Leader根据该请求发起一个Proposal。然后,其他的Server对该Proposal进行Vote。之后,Leader对Vote进行收集,当Vote数量过半时Leader会向所有的Server发送一个通知消息。最后,当Client所连接的Server收到该消息时,会把该操作更新到内存中并对Client的写请求做出回应。
(每一次客户端发起写请求,zookeeper集群都要自主投票,投票数过一半以上才可以写入。)
– ZooKeeper 服务器在上述协议中实际扮演了两个职能。它们一方面从客户端接受连接与操作请求,另一方面对操作结果进行投票。这两个职能在ZooKeeper集群扩展的时候彼此制约。
– 从Zab协议对写请求的处理过程中我们可以发现,增加follower的数量,则增加了对协议中投票过程的压力。因为Leader节点必须等待集群中过半Server响应投票,于是节点的增加使得部分计算机运行较慢,从而拖慢整个投票过程的可能性也随之提高,随着集群变大,写操作也会随之下降。
–所以,我们不得不,在增加Client数量的期望和我们希望保持较好吞吐性能的期望间进行权衡。要打破这一耦合关系,我们引入了不参与投票的服务器,称为Observer。 Observer可以接受客户端的连接,并将写请求转发给Leader节点。但是,Leader节点不会要求 Observer参加投票。相反,Observer不参与投票过程,仅仅在上述第3歩那样,和其他服务节点一起得到投票结果。
– Observer的扩展,给 ZooKeeper 的可伸缩性带来了全新的景象。我们现在可以加入很多 Observer 节点,而无须担心严重影响写吞吐量。但他并非是无懈可击的,因为协议中的通知阶段,仍然与服务器的数量呈线性关系。但是,这里的串行开销非常低。因此,我们可以认为在通知服务器阶段的开销不会成为瓶颈。
– Observer提升读性能的可伸缩性
– Observer提供了广域网能力
(为了减轻写速度,所以Observer可以接受客户端的连接,但不要求Observer参加投票)

  ZK 集群的安装配置
– 1、安装 openjdk 环境
– 2、解压创建配置文件
– 3、设置集群机器 id、ip、port
– 4、拷贝分发到所有集群节点
– 5、启动服务
– 6、查看状态

ZK 集群的安装配置
– 1、安装 openjdk 环境
– 2、解压创建配置文件
– 3、设置集群机器 id、ip、port
– 4、拷贝分发到所有集群节点
– 5、创建目录和 myid 文件
– 6、启动服务
– 7、查看状态

– zoo.cfg
– server.1=Data1:2888:3888  servier.1的1表示(id) 
– server.2=Data2:2888:3888
– server.3=Data3:2888:3888
– server.4=master:2888:3888:observer

zoo.cfg 集群的安装配置
– 创建 datadir 指定的目录
– mkdir /tmp/zookeeper
– 在目录下创建 id 对应的主机名的 myid 文件
– 关于myid文件:
– myid文件中只有一个数字
– 注意,请确保每个server的myid文件中id数字不同
– server.id 中的 id 与 myid 中的 id 必须一致
– id的范围是1~255
– 启动集群,查看验证
– 在所有集群节点执行
– /usr/local/zk/bin/zkServer.sh start
– 查看角色
– /usr/local/zk/bin/zkServer.sh status
– or
– { echo 'stat';yes; }|telnet 192.168.4.10 2181
– Zookeeper 管理文档

Zookeeper 实验
– 搭建 zookeeper 集群
– 添加 observer
– 查找 leader
– 模拟 leader 故障
– 模拟 follower 故障
– 故障恢复

tar -xf zookeeper-3.4.10.tar.gz 
mv zookeeper-3.4.10 /usr/local/zookeeper
cp /usr/local/zookeeper/conf/zoo_sample.cfg  /usr/local/zookeeper/conf/zoo.cfg 
vim /usr/local/zookeeper/conf/zoo_sample.cfg 
...
server.1=Data1:2888:3888   
server.2=Data2:2888:3888
server.3=Data3:2888:3888
server.4=master:2888:3888:observer

for i in 10 11 12 13;do ssh 192.168.4.$i mkdir /tmp/zookeeper;done

所有主机同步/usr/local/zookeeper  
Data1:echo 1 > /tmp/zookeeper/myid
Data2:echo 2 > /tmp/zookeeper/myid
Data3:echo 3 > /tmp/zookeeper/myid
master:echo 4 > /tmp/zookeeper/myid

1-4: 
/usr/local/zookeeper/bin/zkServer.sh start
jps

vim a.sh
#!/bin/bash
function zkstatus(){
    exec 9<>/dev/tcp/$1/2181
    echo "$2" >&9
    cat  <&9
    exec 9<&-
}

for i in master Data{1..3}
do 
 echo -ne "${i}\t"
 zkstatus ${i} stat |grep -P "^Mode"
done 

zkstatus Data2 ruok
echo

bash a.sh

kafka集群 
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 拷贝到所有集群主机
– 修改配置文件
– 启动与验证

kafka 集群的安装配置
server.properties
– broker.id
– 每台服务器的broker.id都不能相同
– zookeeper.connect
– zookeeper 集群地址,不用都列出,写一部分即可

kafka 集群的安装配置
– 在所有主机启动服务
– /usr/local/kafka/bin/kafka-server-start.sh -daemon /usr/local/kafka/config/server.properties
– 验证
– jps 命令应该能看到 kafka 模块
– netstat 应该能看到 9092 在监听

集群验证与消息发布
– 创建一个 topic
./bin/kafka-topics.sh --create --partitions 2 --replication-factor 2 --zookeeper Data1:2181 --topic mymsg
– 查看所有 topic
./bin/kafka-topics.sh --list --zookeeper Data1:2181
– 查看 topic的详细信息
./bin/kafka-topics.sh --describe --zookeeper Data1:2181 --topic mymsg

集群验证与消息发布
– 在两个终端里面,生产者发布消息,消费者读取消息
– 生产者消息
. /bin/kafka-console-producer.sh --broker-list  master:9092,Data1:9092 --topic mymsg
– 消费者消息
./bin/kafka-console-consumer.sh --bootstrap-server Data2:9092,Data3:9092 --topic mymsg
– 表示从开始读取消息
./bin/kafka-console-consumer.sh --bootstrap-server Data2:9092,Data3:9092 --topic mymsg --from-beginning 

利用 zookeeper 搭建一个 kafka 集群
创建一个 topic
查看系统 topic 情况
模拟生产者发布消息
模拟消费者接收消息

tar -xf kafka_2.10-0.10.2.1.tgz 
mv kafka_2.10-0.10.2.1 /usr/local/kafka
cd /usr/local/kafka/config/
vim  servi.propreties
log.dirs=/tmp/kafka-logs (日志路径)
broker.id=4 (每台kafka的id不能相同)
zookeeper.connect=Data1:2181,Data2:2181,Data3:2181

cp 所有主机
启动/usr/local/kafka/bin/kafka-server-start.sh -daemon /usr/local/kafka/config/server.properties
– 验证
– jps 命令应该能看到 kafka 模块
– netstat 应该能看到 9092 在监听

       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                      Journal

HA 方案对比:
– 都能实现热备
– 都是一个active NN 和一个 standby NN
– 都使用Zookeeper 和 ZKFC 来实现自动失效恢复
– 失效切换都使用 fencing 配置的方法来 active NN
– NFS 数据数据共享变更方案把数据存储在共享存储里面,我们还需要考虑 NFS 的高可用设计。
– QJM 不需要共享存储,但需要让每一个 DN 都知道两个 NN 的位置,并把块信息和心跳包发送给active和standby这两个 NN。

NameNode 高可用方案 (QJM)
– 为了解决 NameNode 单点故障问题,Hadoop 给出了 HDFS 的高可用HA方案:HDFS 通常由两个NameNode组成,一个处于 active 状态,另一个处于standby 状态。Active NameNode对外提供服务,比如处理来自客户端的 RPC 请求,而 Standby NameNode 则不对外提供服务,仅同步 Active NameNode 的状态,以便能够在它失败时进行切换。

NameNode 高可用架构
– 一个典型的HA集群,NameNode会被配置在两台独立的机器上,在任何时间上,一个NameNode处于活动状态,而另一个NameNode处于备份状态,活动状态的NameNode会响应集群中所有的客户端,备份状态的NameNode只是作为一个副本,保证在必要的时候提供一个快速的转移。

– 为了让Standby Node与Active Node保持同步,这两个Node都与一组称为JNS的互相独立的进程保持通信(Journal Nodes)。当Active Node上更新了namespace,它将记录修改日志发送给JNS的多数派。Standby noes将会从JNS中读取这些edits,并持续关注它们对日志的变更。Standby Node将日志变更应用在自己的namespace中,当failover发生时,Standby将会在提升自己为Active之前,确保能够从JNS中读取所有的edits,即在failover发生之前Standy持有的namespace应该与Active保持完全同步。

– NameNode 更新是很频繁的,为了的保持主备数据的一致性,为了支持快速failover,Standby node持有集群中blocks的最新位置是非常必要的。为了达到这一目的,DataNodes上需要同时配置这两个Namenode的地址,同时和它们都建立心跳链接,并把block位置发送给它们。

– 还有一点非常重要,任何时刻,只能有一个ActiveNameNode,否则将会导致集群操作的混乱,那么两个NameNode将会分别有两种不同的数据状态,可能
会导致数据丢失,或者状态异常,这种情况通常称为“split-brain”(脑裂,三节点通讯阻断,即集群中不同的Datanode 看到了不同的Active NameNodes)。对于JNS而言,任何时候只允许一个NameNode作为writer;在failover期间,原来的Standby Node将会接管Active的所有职能,并负责向JNS写入日志记录,这中机制阻止了其他NameNode基于处于Active状态的问题。

环境:
192.168.4.10 NameNode1 Zookeeper
192.168.4.16 NameNode2 
192.168.4.11  Data1 DataNode  Zookeeper
192.168.4.12  Data2 DataNode  Zookeeper
192.168.4.13  Data3 DataNode  Zookeeper

core-site.xml

fs.defaultFS
hdfs://mycluster


hadoop.tmp.dir
/var/hadoop


ha.zookeeper.quorum
Data2:2181,Data3:2181


hdfs-site.xml

dfs.replication
1

– secondarynamenode 在高可用里面没有用途,这里把他关闭
– namenode 在后面定义

hdfs-site.xml 续 ......
– 

dfs.nameservices
mycluster

– 指定集群的两个 NaneNode 的名称分别为nn1,nn2

dfs.ha.namenodes.mycluster
nn1,nn2


hdfs-site.xml 续 ......
– 配置nn1,nn2的rpc通信端口

  dfs.namenode.rpc-address.mycluster.nn1
  master:8020


  dfs.namenode.rpc-address.mycluster.nn2
  namenode2:8020


hdfs-site.xml 续 ......
– 配置nn1,nn2的http通信端口

  dfs.namenode.http-address.mycluster.nn1
  master:50070


  dfs.namenode.http-address.mycluster.nn2
  namenode2:50070


hdfs-site.xml 续 ......
– 指定namenode元数据存储在journalnode中的路径

dfs.namenode.shared.edits.dir
qjournal://Data3:8485;Data2:8485/mycluster

– 指定journalnode日志文件存储的路径

dfs.journalnode.edits.dir
/var/hadoop/journal


hdfs-site.xml 续 ......
– 指定HDFS客户端连接active namenode的java类

dfs.client.failover.proxy.provider.mycluster
org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider


hdfs-site.xml 续 ......
– 配置隔离机制为 ssh

dfs.ha.fencing.methods
sshfence

– 指定秘钥的位置

dfs.ha.fencing.ssh.private-key-files
/home/hadoop/.ssh/id_rsa


hdfs-site.xml 续 ......
– 开启自动故障转移

dfs.ha.automatic-failover.enabled
true


vim core-site.xml
1.修改:master:9....
2.添加 zokeeper
vim core-site.xml

 
   fs.defaultFS
   hdfs://mycluster
 
 
   hadoop.tmp.dir
   /var/hadoop
 
 
   hadoop.proxyuser.nfsuser.groups
   *
 
 
   hadoop.proxyuser.nfsuser.hosts
   *
 
 
   ha.zookeeper.quorum
   Data1:2181,Data2:2181,Data3:2181
 


vim hdfs-site.xml
1.删除秘书 namenode.secondary
2.删除 namenode.http-address
3.添加nameservices组mycluster
4.添加namenodes.mycluster并定义
5.添加namenodes.rpc-address.mycluster.nn1
6.添加namenodes.rpc-address.mycluster.nn2
7.http.master1
8.http.namedoe2
9.添加namenode.shared.edits.dir
10.journalnode日志文件存储的路径
11.HDFS客户端连接active namenode的java类
12.配置隔离机制为 ssh
13.指定秘钥的位置  /root/.ssh/id_rsa
14.开启自动故障转移

vim hdfs-site.xml


  dfs.replication
  2


  dfs.hosts.exclude
  /usr/local/hadoop/etc/hadoop/exclude


  dfs.nameservices
  mycluster


  dfs.ha.namenodes.mycluster
  nn1,nn2


  dfs.namenode.rpc-address.mycluster.nn1
  master:8020


  dfs.namenode.rpc-address.mycluster.nn2
  namenode2:8020


  dfs.namenode.http-address.mycluster.nn1
  master:50070


  dfs.namenode.http-address.mycluster.nn2
  namenode2:50070


  dfs.namenode.shared.edits.dir
  qjournal://Data2:8485;Data3:8485/mycluster


  dfs.journalnode.edits.dir
  /root/hadoop/journal


  dfs.client.failover.proxy.provider.mycluster
  org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider


  dfs.ha.fencing.methods
  sshfence


  dfs.ha.fencing.ssh.private-key-files
  /root/.ssh/id_rsa


  dfs.ha.automatic-failover.enabled
  true



   同步数据与高可用验证
– 同步配置到所有集群机器
– 在其中一台初始化 zookeeper 集群
./bin/hdfs zkfc -formatZK
– 在定义的节点启动 journalnode
./sbin/hadoop-daemon.sh start journalnode
– 所有节点都要启动
– 在其中一台 namenode 上执行格式化命令
./bin/hdfs namenode -format
– 注意是格式化其中一台,格式化以后把数据目录拷贝到另一台
– 初始化 JournalNode
./bin/hdfs namenode -initializeSharedEdits
– 停止 JournalNode
./sbin/hadoop-daemon.sh stop journalnode
– 启动 dfs
./sbin/start-dfs.sh 

同步数据与高可用验证
– 验证节点数
./bin/hadoop dfsadmin -report
– 查看集群状态
./bin/hdfs haadmin -getServiceState nn1
./bin/hdfs haadmin -getServiceState nn2

同步数据与高可用验证
– 测试文件读写与 namenode 故障转移
./bin/hadoop fs -ls hdfs://mycluster/
./bin/hadoop fs -mkdir hdfs://mycluster/input
./bin/hadoop fs -put *.txt hdfs://mycluster/input
./bin/hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.3.jar wordcount hdfs://mycluster/input hdfs://mycluster/output
– 关闭主Namenode
./bin/hdfs haadmin -getServiceState nn1
./bin/hdfs haadmin -getServiceState nn2
./bin/hadoop fs -cat hdfs://mycluster/output/*

  ResourceManager高可用
Yarn 高可用
ResourceManager 高可用
– RM 的高可用原理与 NN 是一样的,需要依赖 ZK 来实现,这里就不重复了,只给出配置文件的关键部分,感兴趣的同学可以自己学习和测试
– yarn.resourcemanager.hostname
– 同理因为使用集群模式,该选项应该关闭

yarn-site.xml 配置

yarn.resourcemanager.ha.enabled
true


yarn.resourcemanager.ha.rm-ids
rm1,rm2


yarn-site.xml 配置

yarn.resourcemanager.recovery.enabled
true


yarn.resourcemanager.store.class
org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore


yarn-site.xml 配置

yarn.resourcemanager.zk-address
Data2:2181,Data3:2181,Data1:2181
For multiple zk services, separate them with comma


yarn.resourcemanager.cluster-id
yarn-ha   (yarn集群名)


yarn-site.xml 续 ......

yarn.resourcemanager.hostname.rm1
Data1


yarn.resourcemanager.hostname.rm2
Data2


ResourceManager 高可用
– 启动集群
./sbin/start-yarn.sh 
– 查看集群状态
./bin/yarn rmadmin -getServiceState rm1
./bin/yarn rmadmin -getServiceState rm2