FS File System:
DFS Distributed File System:
文件在磁盘真实存储文件的抽象概念
对字节数组进行切分
按照数组的偏移量将数据连接到一起,连接字节数据
当前数据在数组中的相对位置
系统会将大文件线性切割成块block,分散存放在集群的节点中。
单一文件的block块大小一致,不同文件可以不一样。
(1)HDFS中一旦文件被存储,数据不允许修改
(2)可以在尾部追加数据,但是不推荐
(3)一般HDFS存储的都是历史数据
(4)块的大小一旦文件上传就不允许被修改(128M-512M)
(5)为了数据安全,存在副本机制
(6)系统只支持一次写入多次读取,同一时刻只有一个写入者
(5)如果数据文件的切割点128M正好是一个单词的中间部分,切分数据如何保证数据的完整性?
为了保证数据安全,存在副本机制,对存储数据进行备份。
如何进行备份操作?
需要专门给节点进行分工:
Hadoop节点 | 物理机 | 配置文件 |
---|---|---|
NameNode | node1 | core-site.xml |
DateNode | node1 | slaves |
SecondaryNameNode | node1 | hdfs-site.xml |
1.主机间免秘钥
具体可参考:主机间免秘钥具体操作
2.上传安装包并解压
tar -zxvf hadoop-2.7.1.tar.gz
3.修改JAVA_HOME配置信息
①hadoop-env.sh
# 25行
export JAVA_HOME=/usr/java/jdk1.8.0_162
②mapred-env.sh
# 16行
export JAVA_HOME=/usr/java/jdk1.8.0_162
③yarn-env.sh
# 23行
export JAVA_HOME=/usr/java/jdk1.8.0_162
4.修改核心配置文件
core-site.xml
<configuration>
<property>
<name>fs.default.namename>
<value>hdfs://node1:9000value>
property>
<property>
<name>hadoop.tmp.dirname>
<value>/var/abc/hadoop/localvalue>
property>
<configuration>
5.修改HDFS配置文件
hdfs-site.xml
<configuration>
<property>
<name>dfs.replicationname>
<value>1value>
property>
<property>
<name>dfs.namenode.secondary.http-addressname>
<value>node1:50090value>
property>
<configuration>
6.配置Slaves文件
vim slaves
# localhost
node1
7.配置Hadoop环境变量
export HADOOP_HOME=/opt/hadoop-2.7.1
export PATH=$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH
8.初始化namenode节点
hdfs namenode -format
注意:
9.启动集群
开启集群
start-dfs.sh
web端口:50070
10.创建文件夹及上传文件
hdfs dfs -mkdir -p /abc/
hdfs dfs -put ./a.txt /abc/
hdfs dfs -D dfs.blocksize=1048576 -put ./a.txt /abc/
功能:
①系统启动
②集群运行中
持久化: 当集群或者系统因为各种原因关闭之后,在重启时,可以返回到我们集群关闭的那一时刻
作用: 为了防止系统故障导致的数据丢失,采用持久化机制
将namenode管理的文件元数据信息存放到磁盘上,为了防止namenode因为过度繁忙而挂掉
可以: 前提是成本低,数据量小。
不可以: 因为namenode本身工作很繁忙,如果再进行持久化,namenode会很累;当元数据持久化到磁盘的过程中,通过IO来进行传输,在传输的过程中,namenode无法进行元数据的修改,也无法对外提供服务,相当于集群短暂性宕机。
文件 | 内容 |
---|---|
edits | 日志文件 |
fsimage | 系统镜像 |
seen_txid | 事务id |
VERSION | 集群相关信息 |
1.将namenode的edits和fsimage拉取到secondary namenode进行合并,生成fsimage.ckpt
2.从secondary namenode拉回fsimage.ckpt形成新的fsimage,这次已经完成相应的更新,有了更新之前的所有数据
3.当我们secondary namenode进行合并的时候,再有新的系统操作进行怎么办?
会生成一个新的edites,默认大小64M,与更新后的fsimage再进行合并,当新的edits和fsimage生成之后,在满足一定条件下,会再次进行重演,将其拉到secondary namenode中进行合并
4.满足一定条件指的是什么条件?
时间:超过3600s
内存:edits文件超过64M
5.合并过程中又有系统文件产生,并超过64m怎么办?
可以改变edits默认值(前提:自己清楚会有很多操作,有可能会出现问题)
系统会自动再次创建
6.当持久化结束之后,系统已经更新完成,之前的数据保存在合并之后的文件中,这些文件会持久化到磁盘中,在磁盘中进行存储,防止在内存中因为系统故障丢失(内存是断电清零的)
安全模式: 指集群启动时的一个状态
NameNode启动时:
安全模式干了什么?
HDFS对权限的控制:
为了保证副本在集群的安全性,将副本放在不同的datanode节点上,节点也需要一定的考虑
集群内部: 优先考虑与客户端相同节点作为第一个节点
集群外部: 选择资源丰富且不繁忙(负载不高)的节点作为第一个节点
选择和第一个节点不同机架的随机一个节点
与第二个节点相同机架的其它节点
与前面节点不重复的其它节点
pipeline管道机制
client请求block存放位置之后,namenode会返回一批负载不高的datanode,client会与这批datanode之间形成pipeline管道
pipeline管道连接
pipeline管道中的数据传输
数据首先以block形式存储,在pipeline中,会将block再次细分,分成一个个的ack packet,ack packet在管道中流淌。
默认一个packet大小为64k,128M为2048个packet
pipeline管道中的数据传输流程
字段名称 | 字段类型 | 字段长度 | 字段含义 |
---|---|---|---|
pktLen | int | 4 | 4+dataLen+checksumLen |
offsetInBlock | long | 8 | packet在Block中的偏移量 |
seqNo | long | 8 | packet序列号,在同一个Block中唯一 |
lastPacketInBlock | boolean | 1 | 是否是一个Block的最后一个packet |
dataLen | int | 4 | dataPos-dataStart,不包含Header和checksum的长度 |
参数名称 | 参数值 | 参数含义 |
---|---|---|
chunkSize | 512+4=516 | 每个chunk的字节数(数据+校验和) |
csize | 512 | 每个chunk数据的字节数 |
psize | 64*1024 | 每个packet的最大字节数(不包含header) |
DataNode.PKT_HEADER_LEN | 21 | 每个packet的header的字节数 |
chunksPerPacket | 127 | 组成每个packet的chunk的个数 |
packetSize | 25+516*127=65557 | 每个packet的字节数(一个header+一组chunk) |
伪分布式集群: 单台节点实现了类似于分布式的处理方式
完全分布式: 多台服务器协同作业,改变的是节点的数量以及不同节点在哪一个服务器上启动
NameNode | SecondaryNameNode | DataNode | |
---|---|---|---|
node1 | * | * | |
node2 | * | * | |
node3 | * |
1.预备条件
与伪分布式一样,需要主机间免秘钥并安装JDK
2.上传安装包并解压
tar -zxvf hadoop-2.7.1.tar.gz
3.修改JAVA_HOME配置信息
①hadoop-env.sh
# 25行
export JAVA_HOME=/usr/java/jdk1.8.0_162
②mapred-env.sh
# 16行
export JAVA_HOME=/usr/java/jdk1.8.0_162
③yarn-env.sh
# 23行
export JAVA_HOME=/usr/java/jdk1.8.0_162
4.修改核心配置文件
core-site.xml
<configuration>
<property>
<name>fs.default.namename>
<value>hdfs://node1:9000value>
property>
<property>
<name>hadoop.tmp.dirname>
<value>/var/abc/hadoop/fullvalue>
property>
<configuration>
5.修改HDFS配置文件
hdfs-site.xml
<configuration>
<property>
<name>dfs.replicationname>
<value>2value>
property>
<property>
<name>dfs.namenode.secondary.http-addressname>
<value>node2:50090value>
property>
<property>
<name>dfs.namenode.secondary.https-addressname>
<value>node2:50091value>
property>
<configuration>
6.配置Slaves文件
vim slaves
# localhost
node1
node2
node3
7.配置Hadoop环境变量
export HADOOP_HOME=/opt/hadoop-2.7.1
export PATH=$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH
8.将配置好的文件拷贝至其它节点服务器上
scp -r hadoop-2.7.1 root@node2:`pwd`
scp -r hadoop-2.7.1 root@node3:`pwd`
scp /etc/profile root@node2:/etc/profile
scp /etc/profile root@node3:/etc/profile
9.初始化namenode节点
hdfs namenode -format
注意:
10.启动集群
开启集群
start-dfs.sh
web端口:50070
11.创建文件夹及上传文件
hdfs dfs -mkdir -p /abc/
hdfs dfs -put ./a.txt /abc/
hdfs dfs -D dfs.blocksize=1048576 -put ./a.txt /abc/
①单点故障: 仅有一个namenode主节点,当namenode出现故障,整个集群都会瘫痪,无法提供对外服务
②namenode只有一个节点,很难水平扩展: 服务器启动时,启动速度慢
③namenode随着业务增多,内存占用也会越来越多: 如果namenode内存占满,将无法继续提供服务
④业务隔离性差
⑤存储计算: 可能需要存储不同部分的数据,可能存在不同业务的计算流程
⑥namenode的吞吐量将会是集群的瓶颈: 客户端所有请求都会先访问namenode
高可用(HA,high availability): 单点有问题,集群容易全面崩塌,为了解决问题,采用多个namenode,实现namenode节点的高可用
联邦(Federation): 服务器能力有限,当要处理的问题超过他最大承载量或者datanode的数量超过其的管理量,namenode达到性能瓶颈,易出现问题,可以采用多个人联合的方式来进行namenode的水平扩展,这种方式成为联邦
Standby NameNode(SNN)
NameNode的备用节点
和主节点做同样的工作,但是不发出任何指令
合并日志文件及镜像
DateNode(DN)
Quorum JournalNode Manager(QJM)
脑裂是Hadoop2.x版本之后出现的全新问题,实际运行过程中有可能出现两个NameNode同时服务于整个集群的情况,这种情况称之为脑裂
脑裂通常发生在主从NameNode切换时,由于ActiveNameNode的网络延迟、设备故障等问题,另一个NameNode会认为活跃的NameNode成为失效状态,此时StandbyNameNode会转换成活跃状态,集群中将会出现两个活跃的NameNode。因此,可能出现的因素有网络延迟、心跳故障、设备故障等。
HDFS Federation就是使得HDFS支持多个命名空间,并且允许在HDFS中同时存在多个Name Node。
1.主机间相互免密钥
2.上传zookeeper解压拷贝
tar -zxvf zookeeper-3.4.6.tar.gz # [1]
mv zookeeper-3.4.6 /opt/ # [1]
3.修改配置文件
zoo.cfg
cd /opt/zookeeper-3.4.6/conf/ # [1]
cp zoo_sample.cfg zoo.cfg # [1]
vim zoo.cfg # [1]
# 修改zookeeper数据存放目录
dataDir=/var/data/zookeeper
# 设置服务器内部通信的地址和zk集群的节点
server.1=node1:2888:3888
server.2=node2:2888:3888
server.3=node3:2888:3888
创建myid
[123]mkdir -p /var/data/zookeeper
[123]touch /var/data/zookeeper/myid
[1]echo 1 > /var/data/zookeeper/myid
[2]echo 2 > /var/data/zookeeper/myid
[3]echo 3 > /var/data/zookeeper/myid
拷贝zookeeper
scp -r /opt/zookeeper-3.4.6 root@node3:/opt/ # [1]
scp -r /opt/zookeeper-3.4.6 root@node4:/opt/ # [1]
设置环境变量
vim /etc/profile # [1]
# 添加
export ZOOKEEPER_HOME=/opt/zookeeper-3.4.6
export PATH=$ZOOKEEPER_HOME/bin:$PATH
scp /etc/profile root@node3:/etc/profile # [1]
scp /etc/profile root@node4:/etc/profile # [1]
source /etc/profile # [123]
开启集群
zkServer.sh start # [123]
zkServer.sh status # [123]
zkServer.sh stop # [123]
NN-1 | NN-2 | DN | ZK | ZKFC | JN | |
---|---|---|---|---|---|---|
node1 | * | * | * | * | * | |
node2 | * | * | * | * | * | |
node3 | * | * | * |
1.预备条件
与伪分布式一样,需要主机间免秘钥并安装JDK
2.上传安装包并解压
tar -zxvf hadoop-2.7.1.tar.gz
3.修改JAVA_HOME配置信息
①hadoop-env.sh
# 25行
export JAVA_HOME=/usr/java/jdk1.8.0_162
②mapred-env.sh
# 16行
export JAVA_HOME=/usr/java/jdk1.8.0_162
③yarn-env.sh
# 23行
export JAVA_HOME=/usr/java/jdk1.8.0_162
4.修改核心配置文件
core-site.xml
<configuration>
<property>
<name>fs.defaultFSname>
<value>hdfs://myclustervalue>
property>
<property>
<name>ha.zookeeper.quorumname>
<value>node1:2181,node2:2181,node3:2181value>
property>
<property>
<name>hadoop.tmp.dirname>
<value>/var/data/hadoop/havalue>
property>
configuration>
5.修改HDFS配置文件
hdfs-site.xml
<configuration>
<property>
<name>dfs.nameservicesname>
<value>myclustervalue>
property>
<property>
<name>dfs.ha.namenodes.myclustername>
<value>nn1,nn2value>
property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn1name>
<value>node1:8020value>
property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn2name>
<value>node2:8020value>
property>
<property>
<name>dfs.namenode.http-address.mycluster.nn1name>
<value>node1:50070value>
property>
<property>
<name>dfs.namenode.http-address.mycluster.nn2name>
<value>node2:50070value>
property>
<property>
<name>dfs.namenode.shared.edits.dirname>
<value>qjournal://node1:8485;node2:8485;node3:8485/myclustervalue>
property>
<property>
<name>dfs.journalnode.edits.dirname>
<value>/var/data/hadoop/ha/jnvalue>
property>
<property>
<name>dfs.client.failover.proxy.provider.myclustername>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvidervalue>
property>
<property>
<name>dfs.ha.fencing.methodsname>
<value>sshfencevalue>
<value>shell(true)value>
property>
<property>
<name>dfs.ha.fencing.ssh.private-key-filesname>
<value>/root/.ssh/id_rsavalue>
property>
<property>
<name>dfs.ha.automatic-failover.enabledname>
<value>truevalue>
property>
<property>
<name>dfs.replicationname>
<value>2value>
property>
configuration>
6.配置Slaves文件
vim slaves # [1]
# localhost
node1
node2
node3
7.配置Hadoop环境变量
vim /etc/profile # [1]
export HADOOP_HOME=/opt/hadoop-2.7.1
export PATH=$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH
8.将配置好的文件拷贝至其它节点服务器上
scp -r hadoop-2.7.1 root@node2:`pwd` # [1]
scp -r hadoop-2.7.1 root@node3:`pwd` # [1]
scp /etc/profile root@node2:/etc/profile # [1] node23节点上存放zookeeper的环境变量
scp /etc/profile root@node3:/etc/profile # [1]
9.单独启动journalNode线程
[123]hadoop-daemon.sh start journalnode
[123]jps
10.启动zookeeper
[123]zkServer.sh start
[123]zkServer.sh status
11.初始化主namenode节点
[1]hdfs namenode -format
[1]hadoop-daemon.sh start namenode
12.启动备用namenode节点
[2]hdfs namenode -bootstrapStandby
13.格式化zkfc
[1]hdfs zkfc -formatZK
14.启动集群
开启集群
[1]start-dfs.sh
web端口:50070
15.创建文件夹及上传文件
[1]hdfs dfs -mkdir -p /abc/
[1]hdfs dfs -put ./a.txt /abc/
[1]hdfs dfs -D dfs.blocksize=1048576 -put ./a.txt /abc/
16.关闭
[1]stop-dfs.sh
[123]zkServer.sh stop