3.HDFS
3.1HDFS两类节点
- namenode:名称节点
- datanode:数据节点
1.namenode
1)namenode用来存储元数据,接收客户端的读写请求,namenode的元数据会分别保存在磁盘和内存中,保存到内存是为了快速查询数据信息,保存到磁盘是为了数据安全
元数据包括:数据文件的相关信息(文件名称、文件大小、文件切了几块...)、数据块的相关信息(数据块副本数量,每块数据块存储到哪个datanode上)等
2)namenode节点的状态有active和standby两种,三台namenode有一台状态为active,另外两台状态为standby,其中active状态的namenode负责所有客户端的请求操作,standby状态的namenode处于从属地位,维护数据状态,作为active的备份随时准备切换
2.datanode
负责存储client发来的数据块;执行数据块的读写操作,干活的
3.2安装Hadoop
解压hadoop安装包到指定路径下
ssh_root.sh tar -zxf /public/software/bigdata/hadoop-3.1.4.tar.gz -C /usr/local/
修改安装的hadoop-3.1.4文件的所属者和组
ssh_root.sh chown -R hadoop:hadoop /usr/local/hadoop-3.1.4/
设置软连接
ssh_root.sh ln -s /usr/local/hadoop-3.1.4/ /usr/local/hadoop
修改系统环境变量
su -
vim /etc/profile
export HADOOP_HOME=/usr/local/hadoop
export PATH=$HADOOP_HOME/bin:$PATH
export PATH=$HADOOP_HOME/sbin:$PATH
su hadoop
scp_all.sh /etc/profile /tmp
ssh_root.sh mv /tmp/profile /etc
# 让每台服务器配置的环境变量生效
source /etc/profile
注意:
(1)bin目录:存放对Hadoop相关服务(hdfs,yarn,mapred)进行操作的脚本
(2)etc目录:Hadoop的配置文件目录,存放Hadoop的配置文件
(3)lib目录:存放Hadoop的本地库(对数据进行压缩解压缩功能)
(4)sbin目录:存放启动或停止Hadoop相关服务的脚本
(5)share目录:存放Hadoop的依赖jar包、文档、和官方案例
hadoop的配置文件主要在/usr/local/hadoop/etc/hadoop目录下
其中主要的配置文件包括:
core-site.xml:配置hadoop核心内容
hadoop-env.sh:配置hadoop环境
hdfs-site.xml:配置hdfs相关的
mapred-site.xml:配置mapreduce的
yarn-site.xml:配置yarn的
3.3hdfs配置namenode
1.配置core-site.xml文件
起别名:给三台namenode起一个统一的别名,方便后续通过别名找到三台namenode,对namenode进行统一管理
修改临时数据存储的目录位置
修改hdfs的超级用户组为hadoop
<property>
<name>fs.defaultFS</name>
<value>hdfs://ns1</value>
<description>默认文件服务的协议和NS逻辑名称,和hdfs-site.xml里的对应此配置替代了1.0里的fs.default.name</description>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/data/tmp</value>
<description>数据存储目录</description>
</property>
<property>
<name>hadoop.proxyuser.root.groups</name>
<value>hadoop</value>
<description>配置root(超级用户)允许通过代理用户所属组</description>
</property>
<property>
<name>hadoop.proxyuser.root.hosts</name>
<value>localhost</value>
<description>配置root(超级用户)允许通过代理访问的主机节点</description>
</property>
2.配置hdfs-site.xml文件
指定namenode在磁盘存储元数据的位置
在core-site.xml文件对namenode起了别名,在hdfs-site.xml中配置与其对应的别名
指定别名管理的namenode有哪些
对别名下的每一台namenode进行配置,包括配置服务器通信端口(主要用于服务器之间通信交流)、web端访问端口(web可以通过配置的端口来访问namenode)
配置namenode工作的线程数
<property>
<name>dfs.namenode.name.dir</name>
<value>/data/namenode</value>
<description>namenode本地文件存放地址</description>
</property>
<property>
<name>dfs.nameservices</name>
<value>ns1</value>
<description>提供服务的NS逻辑名称,与core-site.xml里的对应</description>
</property>
<!--主要的-->
<property>
<name>dfs.ha.namenodes.ns1</name>
<value>nn1,nn2,nn3</value>
<description>列出该逻辑名称下的NameNode逻辑名称</description>
</property>
<!--主要的-->
<property>
<name>dfs.namenode.rpc-address.ns1.nn1</name>
<value>nn1:9000</value>
<description>指定NameNode的RPC位置</description>
</property>
<!--主要的-->
<property>
<name>dfs.namenode.http-address.ns1.nn1</name>
<value>nn1:50070</value>
<description>指定NameNode的Web Server位置</description>
</property>
<!--主要的-->
<property>
<name>dfs.namenode.rpc-address.ns1.nn2</name>
<value>nn2:9000</value>
<description>指定NameNode的RPC位置</description>
</property>
<!--主要的-->
<property>
<name>dfs.namenode.http-address.ns1.nn2</name>
<value>nn2:50070</value>
<description>指定NameNode的Web Server位置</description>
</property>
<!--主要的-->
<property>
<name>dfs.namenode.rpc-address.ns1.nn3</name>
<value>nn3:9000</value>
<description>指定NameNode的RPC位置</description>
</property>
<!--主要的-->
<property>
<name>dfs.namenode.http-address.ns1.nn3</name>
<value>nn3:50070</value>
<description>指定NameNode的Web Server位置</description>
</property>
<property>
<name>dfs.namenode.handler.count</name>
<value>77</value>
<description>namenode的工作线程数</description><property>
3.修改hadoop-env.sh
source /etc/profile
export HADOOP_HEAPSIZE_MAX=512
4.分发修改的配置文件
scp_all.sh /usr/local/hadoop/etc/hadoop/core-site.xml /usr/local/hadoop/etc/hadoop/
scp_all.sh /usr/local/hadoop/etc/hadoop/hdfs-site.xml /usr/local/hadoop/etc/hadoop/
scp_all.sh /usr/local/hadoop/etc/hadoop/hadoop-env.sh /usr/local/hadoop/etc/hadoop/
确保集群每台服务器/data目录的所有者和所属组为hadoop
ssh_root.sh chown hadoop:hadoop /data
5.格式化第一台namenode
hdfs namenode -format
格式化成功后会在/data/namenode/current看到fsimage文件
fsimage文件是namenode元数据的镜像文件,相当于内存中元数据在磁盘的快照。
6.启动第一台namenode
hadoop-daemon.sh start namenode
在web访问nn1:50070
7.格式化第二台和第三台namenode
#在nn2和nn3上执行
hdfs namenode -bootstrapStandby
格式化第二台namenode的时候失败
原因:格式化第二台namenode的时候需要从第一台同步元数据,多台namenode要保证数据一致,目前由于无法同步元数据,所以格式化失败,此时需要另外一个组件journalnode
8.journalnode环境搭建
journalnode组件的作用是用来保证各个namenode节点的元数据同步的
1)journalnode的配置-在hdfs-site.xml中添加如下配置
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://nn1:8485;nn2:8485;nn3:8485/ns1</value>
<description>指定用于HA存放edits的共享存储,通常是namenode的所在机器</description>
</property>
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/data/journaldata/</value>
<description>journaldata服务存放文件的地址</description>
</property>
<property>
<name>ipc.client.connect.max.retries</name>
<value>10</value>
<description>namenode和journalnode的链接重试次数10次</description>
</property>
<property>
<name>ipc.client.connect.retry.interval</name>
<value>10000</value>
<description>重试的间隔时间10s</description>
</property>
#将hdfs-site.xml发送到其他节点
scp_all.sh /usr/local/hadoop/etc/hadoop/hdfs-site.xml /usr/local/hadoop/etc/hadoop/
2)因为journalnode是用来进行namenode数据同步的,所以需要先启动三台journalnode再对namenode进行格式化
启动journalnode之前先将nn1上namenode停掉,并将格式化生成的/data/namenode目录删除掉
hadoop-daemon.sh stop namenode
rm -rf /data/namenode
#启动三个机器的journalnode
#nn1 nn2 nn3
su - hadoop
hadoop-daemon.sh start journalnode
3)journalnode已经准备完毕,那么再次格式化第一台namenode并启动
#在nn1机器上面进行namenode的格式化
hdfs namenode -format
#启动nn1上的namenode
hadoop-daemon.sh start namenode
4)格式化并启动第二台、第三台namenode
#格式化第二台和第三台namenode
hdfs namenode -bootstrapStandby
#启动第二台和第三台namenode
hadoop-daemon.sh start namenode
查看集群节点进程情况
查看web端情况
9.zkfc环境搭建
上面三台namenode启动以后状态都是standby,没有状态为active的,此时就需要配置zkfc在三台namenode中选举一台状态为active
zkfc的作用就是确定三台namenode中谁的状态是active,它本质上是一个进程,需要在三台namenode中都启动。它的主要任务是一边联系namenode,一边联系zookeeper。
zkfc如何确定namenode的active?
三个namenode启动之后,都会通过zkfc尝试在zookeeper上创建节点,如果哪台namenode先在zookeeper上创建节点成功,则该namenode就是状态为active的namenode,剩下的两台namenode的状态就是standby
1)core-site.xml中添加如下配置
<property>
<name>ha.zookeeper.quorum</name>
<value>nn1:2181,nn2:2181,nn3:2181</value>
<description>HA使用的zookeeper地址</description>
</property>
2)hdfs-site.xml增加如下配置
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/home/hadoop/.ssh/id_rsa</value>
<description>杀死命令脚本的免密配置秘钥</description>
</property>
<property>
<name>dfs.client.failover.proxy.provider.ns1</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property><property>
<name>dfs.client.failover.proxy.provider.auto-ha</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property><property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
3)分发脚本配置到各个节点
scp_all.sh /usr/local/hadoop/etc/hadoop/core-site.xml /usr/local/hadoop/etc/hadoop/ scp_all.sh /usr/local/hadoop/etc/hadoop/hdfs-site.xml /usr/local/hadoop/etc/hadoop/
4)启动zkfc之前需要在zookeeper中初始化zkfc的节点
# 启动zookeeper集群
ssh_all_zookeeper.sh /usr/local/zookeeper/bin/zkServer.sh start
ssh_all_zookeeper.sh /usr/local/zookeeper/bin/zkServer.sh status
#在nn1节点执行
hdfs zkfc -formatZK
初始化前后zookeeper节点变化
5)分别在nn1,nn2,nn3 机器启动zkfc
#nn1 nn2 nn3启动zkfc
hadoop-daemon.sh start zkfc
6)重启三台namenode查看是否会选举active namenode
#三个机器分别重启namenode
hadoop-daemon.sh stop namenode
hadoop-daemon.sh start namenode
至此namenode配置完成
3.4hdfs配置datanode
1.修改hdfs-site.xml
<property>
<name>dfs.datanode.data.dir</name>
<value>/data/datanode</value>
<description>datanode本地文件存放地址</description>
</property>
<property>
<name>dfs.replication</name>
<value>3</value>
<description>文件复本数</description>
</property>
<property>
<name>dfs.namenode.datanode.registration.ip-hostname-check</name>
<value>false</value>
</property>
<property>
<name>dfs.client.use.datanode.hostname</name>
<value>true</value>
</property>
<property>
<name>dfs.datanode.use.datanode.hostname</name>
<value>true</value>
</property>
2.修改workers
3.分发配置文件到各个节点中
scp_all.sh /usr/local/hadoop/etc/hadoop/hdfs-site.xml /usr/local/hadoop/etc/hadoop/ scp_all.sh /usr/local/hadoop/etc/hadoop/workers /usr/local/hadoop/etc/hadoop/
# 启动各个节点的datanode
# s1 s2 s3
hadoop-deamons.sh start datanode
到此为止,hdfs所有组件全部启动成功。
3.5hdfs启动、关闭脚本
上图可以看到集群中hdfs正常运行需要的组件还是挺多的,以后使用hdfs如果要一个一个启动所需组件还是挺麻烦的,所以我们可以通过下面脚本一键启动hdfs所需的所有组件
# 关闭hdfs的所有进程
stop-dfs.sh
# 启动hdfs的所有进程
start-dfs.sh
3.6 hdfs测试存储数据
1.上传文件到hdfs
# 在hdfs的根路径创建student目录
hadoop fs -mkdir /s
注意:web端必须连接状态为active的namenode才能查看数据
# 向s目录上传本地文件1.txt
hadoop fs -put 1.txt /s
2. datanode数据存储路径
数据在磁盘的存储位置:
/data/datanode/current/BP-1280687564-11.94.204.150-1721975367728/current/finalized/subdir0/subdir0/
#存储文件
blk_1073741825
#这个blk的信息[大小 创建时间 校验和]
blk_1073741825_1001.meta
3.7hdfs总结
NameNode:用来管理datanode,并用来存储元数据
journalnode:负责两个状态的namenode进行数据同步,保持数据一致。
ZKFC:作用是HA自动切换。会将NameNode的active状态信息保存到zookeeper。
DataNode:负责存储client发来的数据块block;执行数据块的读写操作。
3.8hdfs高级配置
1.core-site.xml中进行配置
#开启本地库对压缩的支持
<property>
<name>io.native.lib.available</name>
<value>true</value>
<description>开启本地库支持</description>
</property>#支持的压缩格式
<property>
<name>io.compression.codecs</name> <value>org.apache.hadoop.io.compress.GzipCodec,org.apache.hadoop.io.compress.DefaultCodec,org.apache.hadoop.io.compress.BZip2Codec,org.apache.hadoop.io.compress.SnappyCodec</value>
<description>相应编码的操作类</description>
</property>#SequenceFiles在读写中可以使用的缓存大小
<property>
<name>io.file.buffer.size</name>
<value>131072</value>
<description>SequenceFiles在读写中可以使用的缓存大小</description>
</property># 设置mr输入到hdfs中的数据的压缩是按照块压缩
<property>
<name>mapreduce.output.fileoutputformat.compress.type</name>
<value>BLOCK</value>
</property># 出入到hdfs中的文件是按照块为一个整体进行压缩
<property>
<name>io.seqfile.compressioin.type</name>
<value>BLOCK</value>
</property># 客户端连接超时时间
<property>
<name>ipc.client.connection.maxidletime</name>
<value>60000</value>
</property>
2.hdfs-site.xml中的配置
# hdfs开启支持文件追加操作
#关闭文件系统权限
#开启垃圾箱,删除的文件不会消失会移除到垃圾箱中
<property>
<name>dfs.support.append</name>
<value>true</value>
<description>是否支持追加</description>
</property>
<property>
<name>dfs.permissions.enabled</name>
<value>false</value>
<description>是否开启目录权限</description>
</property>
<property>
<name>fs.trash.interval</name>
<value>2880</value>
<description>回收周期</description>
</property># datanode在读写本地文件的时候设置最大机器文件打开数
<property>
<name>dfs.datanode.max.transfer.threads</name>
<value>8192</value>
<description>相当于linux下的打开文件最大数量,文档中无此参数,当出现DataXceiver报错的时候,需要调大。默认256</description>
</property>
# 在hdfs多个节点中数据均衡的时候能够用到的最大系统带宽,防止占用太多带宽
<property>
<name>dfs.datanode.balance.bandwidthPerSec</name>
<value>104857600</value>
</property># 设置每个机器的磁盘要预留两个G的数据,不能全部都给hdfs使用 # 设置存储的datanode机器的选择策略,优先以机器剩余磁盘存储两个G以上
<property>
<name>dfs.datanode.du.reserved</name>
<value>2147483648</value>
<description>每个存储卷保留用作其他用途的磁盘大小</description>
</property>
<property>
<name>dfs.datanode.fsdataset.volume.choosing.policy</name>
<value>org.apache.hadoop.hdfs.server.datanode.fsdataset.AvailableSpaceVolumeChoosingPolicy</value>
<description>存储卷选择策略</description>
</property><property>
<name>dfs.datanode.available-space-volume-choosing-policy.balanced-space-threshold</name>
<value>2147483648</value>
<description>允许的卷剩余空间差值,2G</description>
</property># 设置客户端读取数据
# 如果读取数据的客户端和datanode在同一个机器上那么可以直接从本地读取数据,不需要走远程IO
<property>
<name>dfs.client.read.shortcircuit</name>
<value>true</value>
</property>
<property>
<name>dfs.domain.socket.path</name>
<value>/data/dn_socket_PORT</value>
</property>
3.分发配置
#复制以上内容到core-site.xml和hdfs-site.xml中
#将这个文件分发到不同的机器中
scp_all.sh /usr/local/hadoop/etc/hadoop/hdfs-site.xml /usr/local/hadoop/etc/hadoop/ scp_all.sh /usr/local/hadoop/etc/hadoop/core-site.xml /usr/local/hadoop/etc/hadoop/
#重启集群
stop-dfs.sh
start-dfs.sh
3.9hdfs常用命令
1.查看hdfs根目录
# 标准写法
hadoop fs -ls hdfs://ns1/
# 简写(推荐)
hadoop fs -ls /
# -h:文件大小显示为最大单位,更加人性化
hadoop fs -ls -h /
# -R:递归显示
hadoop fs -ls -R /
2.上传文件/目录 put
#创建本地文件
echo hello >> ~/demo.txt
#标准写法:put 左面:是本地,右面是hdfs集群
hadoop fs -put ~/demo.txt hdfs://ns1/
#简写:右面默认找hdfs (推荐)
hadoop fs -put ~/demo.txt /
#当上传时要对文件进行重命名
hadoop fs -put ~/demo.txt /demo1.txt
#在本地创建多个文件
echo 'hello' >> a.txt
echo 'world' >> b.txt
#一次上传多个文件到HDFS路径
hadoop fs -put a.txt b.txt /
#上传目录
mkdir ceshi
cd ceshi
touch aa.txt
touch bb.txt
hadoop fs -put ceshi /
# -f覆盖上传
hadoop fs -put -f demo.txt /
3.读取文件 cat
#如果文件太大,不要用cat读取文件
hadoop fs -cat /data/demo.log
4.下载文件/目录 get
#下载hdfs文件到本地目录
hadoop fs -get /demo.txt ./
#下载hdfs文件到本地目录并重命名
hadoop fs -get /demo.txt ./a.txt
5.拷贝文件/目录 cp
# 创建新的文件
touch word.txt
# 上传本地文件使用file:开头
hadoop fs -cp file:/home/hadoop/word.txt /
# 查看上传
hadoop fs -ls /
# 从hdfs进行拷贝
hadoop fs -cp /demo.txt /ceshi
# 查询
hadoop fs -ls /ceshi
6.剪切文件 mv
#剪切
hadoop fs -mv /b.txt /ceshi
#查询
hadoop fs -ls /
hadoop fs -ls /ceshi
7.删除文件/目录 rm
执行-rm 命令后,默认是把文件移动到 user/hadoop/.Trash/Current 下,会根据配置文件配置的清理周期定期清理。
#删除文件
hadoop fs -rm /demo.txt
#匹配模式删除所有文件
hadoop fs -rm /ceshi/*.log
#rm只能删除文件
#删除文件夹报错
hadoop fs -rm /ceshi
#强制删除,并且递归删除文件夹中的内容
hadoop fs -rmr /ceshi
#删除之后不放到回收站
hadoop fs -rm -skipTrash /a.txt
8. 创建空文件 touchz
hadoop fs - touchz /a.txt
9.创建目录 mkdir
#同时创建多个目录
hadoop fs -mkdir /tmp1 /tmp2
#同时创建父级目录
hadoop fs -mkdir -p /dir1/dir2/dir3
10.读取文件尾部 tail
#查看尾部1K字节
hadoop fs -tail /demo1.txt
11.追加写入文件 appendToFile
#本地创建文件note.txt
touch note.txt
#写入hello
echo 'hello' >> note.txt
#本地创建文件new.txt
touch new.txt
#写入world
echo 'world' >> new.txt
#将note.txt上传到hdfs中
hadoop fs -put note.txt /
#将new.txt的内容追加到node.txt中
hadoop fs -appendToFile new.txt /note.txt
12.获取逻辑空间文件/目录大小 du
#显示HDFS根目录中各文件和文件夹大小
hadoop fs -du /
#以最大单位显示HDFS根目录中各文件和文件夹大小
hadoop fs -du -h /
#仅显示HDFS根目录大小。即各文件和文件夹大小之和
hadoop fs -du -s -h /
13. 改变文件副本数 setrep
#-R 递归改变目录下所有文件的副本数
#-w 等待副本数调整完毕后返回。可理解为加了这个参数就是阻塞式的了
hadoop fs -setrep -R -w 2 /demo.txt
14.获取HDFS目录的物理空间信息 count
hadoop fs -count / #显示HDFS根目录在物理空间的信息
8:目录个数
3:文件个数
12:总大小
3.10hdfs高级命令
hdfs dfsadmin **
例如:hadoop dfsadmin -report
dfsadmin命令详解
1) -report:
查看文件系统的基本信息和统计信息。
2)-safemode :
安全模式命令。安全模式是NameNode的一种状态,在这种状态下,NameNode不接受对元数据的更改(只读);不复制或删除块。NameNode在启动时自动进入安全模式,当配置块的最小百分数满足最小副本数的条件时,会自动离开安全模式。enter是进入,leave是离开 。
#进入安全模式
hadoop dfsadmin -safemode enter
#离开安全模式
hadoop dfsadmin -safemode leave
#获取安全模式信息
hadoop dfsadmin -safemode get
在安全模式情况下不允许任何hdfs的修改操作的
安全模式下可以查询元数据信息,但是不能对文件做任何的修改
3.11hdfs动态扩容datanode流程
1.添加新的服务器
2.创建hadoop用户并设置密码
3.安装jdk
4.配置s4的主机名
5.将s3的hadoop安装目录传输到s4上
6.将s3的环境变量文件也拷贝一份给s4
7.修改/data目录的所有者和所属组
8.修改hosts文件
9.修改其他服务器,添加s4节点的映射
10.配置s4和其它服务器免密码登陆
11.给workers文件添加s4
12.在新增的s4节点启动datanode
笔记参考:http://hainiubl.com/topics/75963