3.HDFS 原理和安装

教程 阿布都的都 ⋅ 于 2023-01-06 17:34:00 ⋅ 1150 阅读

1 单机时代的数据存储解决方案

1.1 单块硬盘

​ 在单机时代,如果把数据一块磁盘一块磁盘的写,有如下问题:

​ 1)单块磁盘写,磁盘读写速度上不去,读写慢;

​ 2)数据写入单块磁盘,一旦磁盘故障导致数据丢失;

​ 在这种情况下,RAID技术就应运而生了。

1.2 RAID

​ RAID ( Redundant Array of Independent Disks )即独立磁盘冗余阵列,简称为「磁盘阵列」,其实就是用多个独立的磁盘组成在一起形成一个大的磁盘系统,从而实现比单块磁盘更好的存储性能和更高的可靠性。

​ 根据 RAID 算法的不同,RAID 有很多种。下面主要介绍 RAID0、RAID1、RAID10。

1.2.1 RAID0

​ RAID0 是一种非常简单的的方式,它将多块磁盘组合在一起形成一个大容量的存储。

​ 假设阵列中有N块磁盘,当写数据时,会将数据分为N份,然后分别写入N块 磁盘中。因此,RAID0将提供非常优秀的读写性能。

优点:

​ 并行写入读取快,空间利用率高。

​ 如果你要读取/写入 2G 的数据,在普通硬盘上,要以单盘的速度读取/写入 2G 的数据。

​ 如果在 4 盘 RAID0 阵列中,每个盘只需读取/写入 500MB 的数据,四个盘可以并行读取/写入,因此理论的读写速度将是单块硬盘的4倍。

缺点:

​ 只要阵列中有一块硬盘坏掉,由于这块硬盘保存着所有数据(每个文件)的某一部分,因此所有数据都将无法读取,整个阵列中的数据将宣告报废。

file

1.2.2 RAID1

​ RAID1 是磁盘阵列中单位成本最高的一种方式。因为它的原理是在往磁盘写数据的时候,将同一份数据无差别的写两份到磁盘,分别写到工作磁盘和镜像磁盘,那么它的实际空间使用率只有50%了,两块磁盘当做一块用,这是一种比较昂贵的方案。

优点:

​ 数据写入两个磁盘,通过冗余存储实现容错。

缺点:

​ 空间利用率低,读写速度慢。

file

1.2.3 RAID10

​ RAID10其实就是RAID1与RAID0的一个合体。

​ 先将磁盘阵列组成 RAID1, 再将多个RAID1 组成 RAID0。

​ 读写数据时,可以将数据分N块,并行写入,而且每块数据都有备份。

​ 这样既可以通过冗余存储容错,也可以提高读写的效率。

file

2 HDFS概述

​ HDFS是Hadoop Distribute File System 的简称,也就是Hadoop的一个分布式文件系统,用来解决存储问题。

​ HDFS 可以使用低成本的硬件来搭建。

​ HDFS 可以对海量的数据进行分布式存储。

​ HDFS 实现软件RAID10。

HDFS 总思想:化大为小,分而存之And备之。

​ 将大的数据集,划分成 N 个块,再将这些块存到大量独立的机器上,而且每块都有备份,防止数据丢失。

​ 数据集1 -----> N个 数据块 -----> 并行写入集群机器 -------> 同时对每个数据块做备份

数据块(Block):是 HDFS 的最小存储单位。一秒定律来决定大小 --> 150M/S --> 128M。

2.1 HDFS 系统结构组成

​ HDFS 是一个主(master)/仆(slave)体系结构,从最终用户的角度来看,它就像传统的文件系统一样,可以通过目录路径对文件执行 增、删、改、查 操作。

​ 在 HDFS 体系结构中有两类结点:

​ 一类是 NameNode,又叫“名称结点”;

​ 另一类是 DataNode,又叫“数据结点”。

file

NameNode

​ 是大领导。管理数据块映射;处理客户端的读写请求。一般有一个active状态的namenode,有一个standby状态的namenode,其中,active状态的NameNode负责所有的客户端操作,standby状态的NameNode处于从属地位,维护着数据状态,随时准备切换。

journalnode

​ 负责两个状态的namenode进行数据同步,保持数据一致。

ZKFC

​ 作用是HA自动切换。会将NameNode的active状态信息保存到zookeeper。

DataNode

​ 干活的。负责存储client发来的数据块block;执行数据块的读写操作。

关系

1)datanode启动时要在namenode上注册,当datanode改变时,也要通知namenode。datanode 会定期向NameNode发送心跳,告知NameNode 该节点的datanode是活着的。

2)datanode之间可以相互传输数据。

2.2 数据块——block

1)数据块是基本的数据存储单位,一个大文件根据数据块的大小,将文件分为若干个块。

​ Hadoop1.x是64M, Hadoop2.x是128M,如果机器性能高可配置256M,太大失去了分布式计算的意义。

​ NameNode存储的文件数据块的元数据信息;而datanode存储块信息对应的数据。

​ NameNode存储的元数据信息包括:

    1. 文件的存储路径
    2. 文件大小
    3. block块大小
    4. 文件和blickid的映射关系
    5. 文件的权限
    6. 上传的用户
    7. Block数量信息
    8. Block和DataNode之间的关系信息

    2)一个数据块的元数据信息占用namenode内存存储空间为150字节。块越小读取的速度就越快,但是整体占用namenode的空间就越大。

比如:文件188M,

64M一块分3块, 占namenode内存:150*3 = 450字节

1M一块,188块,占namenode内存:150*188 ≈ 30000字节

块的设定要合理。太大,不适宜计算;太小,占namenode内存

3)一个大文件会被拆分成一个个的块,然后存储于不同的机器。对于大规模的集群会存储在不同的机架上,如果一个文件少于Block大小,那么实际占用的空间为其文件的大小。 60M的文件, 块单位64M,实际存储:60M

4)数据块也是基本的读写单位,类似于磁盘的扇区,每次都是读写一个块。读写多个块就合成了一个文件。

5)为了容错,文件的所有数据块都会有副本,也就是说复制的是数据块而不是单独的一个文件被复制了,默认复制3份,可以在hdft-site.xml里进行配置。

2.3 HDFS 的写数据流程

file

1)客户端发起数据写入请求,告诉namenode要写入的文件信息;

2)namenode 根据客户端的情况(client端所在位置、文件大小)给客户端分配写入数据的位置,也就是写到哪几台机器上;

3)客户端接收到namenode返回的映射信息,向datanode写入数据;

4)datanode复制数据,实现副本写入;

5)副本写入完成之后,各数据节点向namenode上报block信息;

6)datanode通知客户端写操作已完成;

2.4 HDFS 的读数据流程

file

1)客户端发起读数据的请求,通知 namenode 要读取哪个文件; 2)namenode 在内存中检索,找到该文件对应数据块的映射信息(要读取的数据在哪台机器上),并返回给客户端; 3)客户端通过映射信息,到最近的机器找到要读取的数据块; 4)客户端从数据块中读取数据信息并返回给客户端 5)客户端读完数据之后,通知 namenode 已经读取完成;注意: 在读取数据的过程中,如果客户端在与数据结点通信时出现错误,则尝试连接包含此数据块的下一个数据结点。失败的数据结点将被记录,并且以后不再连接。

3 HDFS 安装和初始化

3.1 HDFS规划

namenode:

​ nn1.hadoop

​ nn2.hadoop

datanode:

​ s1.hadoop、

​ s2.hadoop、

​ s3.hadoop

3.2 HDFS配置文件及说明

file

3.2.1 hdfs-site.xml

​ HA集群需要使用命名空间区分一个HDFS集群。同一个集群中的不同NameNode,使用不同的NameNode ID区分。为了支持所有NameNode使用相同的配置文件,因此在配置参数中,需要把“nameservice ID”作为NameNode ID的前缀。

file

dfs.nameservices 命名空间的逻辑名称。提供服务的NS(nameservices)逻辑名称,与core-site.xml里的对应。如果有多个HDFS集群,可以配置多个命名空间的名称,使用逗号分开即可。

    <property>
        <name>dfs.nameservices</name>
        <value>ns1</value>
        <description>提供服务的NS逻辑名称,与core-site.xml里的对应</description>
    </property>

dfs.ha.namenodes.[nameservice ID] 命名空间中所有NameNode的唯一标示名称。可以配置多个,使用逗号分隔。该名称是可以让DataNode知道每个集群的所有NameNode。当前,每个集群最多只能配置两个NameNode。

    <property>
        <name>dfs.ha.namenodes.ns1</name>
        <value>nn1,nn2</value>
        <description>列出该逻辑名称下的NameNode逻辑名称</description>
    </property>

dfs.namenode.rpc-address.[nameservice ID].[name node ID] 每个namenode监听的RPC地址。

dfs.namenode.http-address.[nameservice ID].[name node ID] 每个namenode监听的http地址。

    <!--主要的-->
    <property>
        <name>dfs.namenode.rpc-address.ns1.nn1</name>
        <value>nn1.hadoop:9000</value>
        <description>指定NameNode的RPC位置</description>
    </property>
    <!--主要的-->
    <property>
        <name>dfs.namenode.http-address.ns1.nn1</name>
        <value>nn1.hadoop:50070</value>
        <description>指定NameNode的Web Server位置</description>
    </property>
    <!--主要的-->
    <property>
        <name>dfs.namenode.rpc-address.ns1.nn2</name>
        <value>nn2.hadoop:9000</value>
        <description>指定NameNode的RPC位置</description>
    </property>
    <!--主要的-->
    <property>
        <name>dfs.namenode.http-address.ns1.nn2</name>
        <value>nn2.hadoop:50070</value>
        <description>指定NameNode的Web Server位置</description>
    </property>

RPC(Remote Procedure Call Protocol)

远程过程调用协议。一个通俗的描述是:客户端在不知道调用细节的情况下,调用存在于远程计算机上的某个对象,就像调用本地应用程序中的对象一样。

目前,主流的平台中都支持各种远程调用技术,以满足分布式系统架构中不同的系统之间的远程通信和相互调用。

file

主要配置说明

name value description
dfs.datanode.data.dir /data1/dfs,/data2/dfs,/data3/dfs,/data4/dfs,/data5/dfs,/data6/dfs datanode本地文件存放地址
dfs.replication 3 文件复本数 一个文件,可在其他机器共存放3个副本,保证一个文件不只是在一台机器上 ,体现高可用性
dfs.namenode.name.dir /data1/dfsname,/data2/dfsname,/data3/dfsname namenode本地文件存放地址
dfs.support.append TRUE 是否支持追加,但不支持并发线程往里追加
dfs.permissions.enabled FALSE 是否开启目录权限,自己用建议不开启
dfs.nameservices ns1 提供服务的NS逻辑名称,与core-site.xml里的对应,可以配置多个命名空间的名称,使用逗号分开即可。
dfs.ha.namenodes.[nameservice ID] nn1,nn2 命名空间中所有NameNode的唯一标示名称。可以配置多个,使用逗号分隔。该名称是可以让DataNode知道每个集群的所有NameNode。当前,每个集群最多只能配置两个NameNode。
dfs.namenode.rpc-address.ns1.nn1 nn1.hadoop:9000 指定NameNode的RPC位置
dfs.namenode.http-address.ns1.nn1 nn1.hadoop:50070 指定NameNode的Web Server位置
dfs.namenode.rpc-address.ns1.nn2 nn2.hadoop:9000 指定NameNode的RPC位置
dfs.namenode.http-address.ns1.nn2 nn2.hadoop:50070 指定NameNode的Web Server位置
dfs.namenode.shared.edits.dir qjournal://nn1.hadoop:8485;nn2.hadoop:8485/ns1 指定用于HA存放edits的共享存储,通常是namenode的所在机器
dfs.journalnode.edits.dir /data/journaldata/ journaldata服务存放文件的地址
fs.trash.interval 2880 垃圾回收周期,单位分钟
dfs.blocksize 134217728 块的大小
dfs.datanode.du.reserved 2147483648 每个存储卷保留用作其他用途的磁盘大小
dfs.datanode.fsdataset.volume.choosing.policy org.apache.hadoop.hdfs.server.datanode.fsdataset.AvailableSpaceVolumeChoosingPolicy datanode数据副本存放的磁盘选择策略, 有2种方式一种是轮询方式 (org.apache.hadoop.hdfs.server.datanode.fsdataset.RoundRobinVolumeChoosingPolicy,为默认方式), 另一种为选择可用空间足够多的磁盘存储方式 (org.apache.hadoop.hdfs.server.datanode.fsdataset.AvailableSpaceVolumeChoosingPolicy)
dfs.datanode.available-space-volume-choosing-policy.balanced-space-threshold 2147483648 当选择可用空间足够多的磁盘存储方式才生效,hdfs计算最大可用空间-最小可用空间的差值,如果差值小于此配置,则选择轮询方式存储

3.2.2 core-site.xml

主要配置说明

name value description
io.native.lib.available TRUE 开启本地库支持
fs.defaultFS hdfs://ns1 客户端连接HDFS时,默认的路径前缀。默认文件服务的协议和NS(nameservices)逻辑名称,和hdfs-site里的对应此配置替代了1.0里的fs.default.name
io.compression.codecs org.apache.hadoop.io.compress.GzipCodec,org.apache.hadoop.io.compress.DefaultCodec,org.apache.hadoop.io.compress.BZip2Codec,org.apache.hadoop.io.compress.SnappyCodec 相应编码的操作类,用逗号分隔
ha.zookeeper.quorum nn1.hadoop:2181,nn2.hadoop:2181,s1.hadoop:2181 HA使用的zookeeper地址,用逗号分隔

3.2.3 hadoop-env.sh

HADOOP_CLASSPATH:hadoop的classpath

JAVA_LIBRARY_PATH:java加载本地库的地址

HADOOP_HEAPSIZE:java虚拟机使用的最大内存

HADOOP_OPTS:hadoop启动公用参数

HADOOP_NAMENODE_OPTS:namenode专用参数

HADOOP_DATANODE_OPTS:datanode专用参数

HADOOP_CLIENT_OPTS:hadoop client专用参数

3.2.4 slaves

slaves文件里面记录的是集群里所有DataNode的主机名

file

hadoop-daemons.sh 中用到了 slaves 文件

注意:配置文件里的host改成你自己的

3.3 把hadoop安装包分发到每个机器+解压+创建软链接+修改Hadoop权限

#将Hadoop安装包上传到~hadoop/up
cd ~/upload
rz
#将Hadoop安装包 分发到5台机器的/tmp 目录下
./scp_all.sh ../up/hadoop-2.7.3.tar.gz /tmp/
#批量将Hadoop安装包解压到/usr/local
./ssh_root.sh tar -zxf /tmp/hadoop-2.7.3.tar.gz -C /usr/local
#批量创建软链接 
 ./ssh_root.sh ln -s /usr/local/hadoop-2.7.3 /usr/local/hadoop 
# 批量修改解压目录为Hadoop用户和组 z 
 ./ssh_root.sh chown -R  hadoop:hadoop /usr/local/hadoop-2.7.3

file

3.4 把hadoop配置分发到每个机器上,并解压

#将配置文件压缩包上传到~hadoop/up
cd ~/up
rz
#hadoop配置文件地址
ll /usr/local/hadoop/etc/hadoop/
#批量备份hadoop老的配置
./ssh_all.sh mv /usr/local/hadoop/etc/hadoop /usr/local/hadoop/etc/hadoop_back
#批量将自定义的配置拷贝到/tmp 目录下
./scp_all.sh ../up/hadoop.tar.gz /tmp/
#批量将自定义配置 压缩包解压到/usr/local/hadoop/etc/
./ssh_all.sh tar -xzf /tmp/hadoop.tar.gz -C /usr/local/hadoop/etc
#批量检查配置是否正确解压
./ssh_all.sh head /usr/local/hadoop/etc/hadoop/hadoop-env.sh

3.5 初始化分布式文件系统HDFS

步骤:

1)启动zookeeper

2)启动 journalnode 2台

3)启动zookeeper客户端,初始化HA的zookeeper信息

4)对nn1上的namenode进行格式化

5)\启动nn1上的namenode****

*6)在nn2上 同步namenode*

*7)启动nn2上的namenode*

*8)启动ZKFC 2台*

*9)启动datanode 3台*

3.5.1 启动zookeeper

#启动zookeeper
./ssh_all_zookeeper.sh /usr/local/zookeeper/bin/zkServer.sh start
#查看zookeeper运行的状态
./ssh_all_zookeeper.sh /usr/local/zookeeper/bin/zkServer.sh status

3.5.2 启动 journalnode

file

在每个要运行的机器上执行 hadoop-daemon.sh start journalnode

cd /usr/local/hadoop/logs/ hadoop相关服务日志文件地址

vim hadoop-hadoop-journalnode-nn1.hadoop.log

file

netstat -apn |grep 8485

file

#在nn1上启动journalnode
hadoop-daemon.sh start journalnode 
#在nn2上启动journalnode
hadoop-daemon.sh start journalnode

file

3.5.3 初始化HA的zookeeper信息

#启动zkclient,并连接zookeeper集群
/usr/local/zookeeper/bin/zkCli.sh -server nn1.hadoop:2181,nn2.hadoop:2181,s1.hadoop:2181
#在nn1克隆会话,用hadoop用户执行下面命令,初始化HA的zookeeper信息
hdfs zkfc -formatZK

通过zookeeper客户端查看结点

file

在nn1上执行 hdfs zkfc -formatZK 初始化HA的zookeeper信息

file

初始化后,通过zookeeper客户端查看结点

file

4.5.4 对nn1上的namenode进行格式化

初始化一些目录和文件。

在nn1上执行 hadoop namenode -format

file

3.5.5 启动nn1上的namenode并观察日志文件

在nn1上执行 hadoop-daemon.sh start namenode

vim /usr/local/hadoop/logs/hadoop-hadoop-namenode-nn1.hadoop.log

file

3.5.6 第二个namenode同步第一个namenode状态

在nn2上执行 hadoop namenode -bootstrapStandby

file

3.5.7 在nn2上启动namenode

在nn2上执行 hadoop-daemon.sh start namenode

vim /usr/local/hadoop-2.7.3/logs/hadoop-hadoop-namenode-nn2.hadoop.log 观察日志

file

3.5.8 启动ZKFC

在 nn1 和 nn2 分别启动ZKFC,这时两个namenode,一个变成active,一个变成standby

zkfc作用:HA自动切换。

hadoop-daemon.sh start zkfc

active

file

standby

file

在自己的windows电脑上配置好hosts

C:\Windows\System32\drivers\etc\hosts

192.168.142.160 nn1.hadoop
192.168.142.161 nn2.hadoop
192.168.142.162 s1.hadoop
192.168.142.163 s2.hadoop
192.168.142.164 s3.hadoop
192.168.142.165 s4.hadoop

在任何机器上执行hdfs haadmin -getServiceState 可查看HA状态

file

3.5.9 启动datanode

在nn1上执行hadoop-daemons.sh start datanode 启动s1 s2 s3上的datanode服务,注意这里是hadoop-daemons.sh而不是hadoop-daemon.sh

启动完成后看http://nn1.hadoop:50070 页面的状态,查看集群的存储情况和节点信息

http://nn1.hadoop:50070 nn1节点页面

http://nn2.hadoop:50070 nn2节点页面

介绍页面内容

file

3.5.10 测试新建的HDFS是否有问题

hadoop fs -mkdir /data (等于 hadoop fs -mkdir hdfs://ns1/data)

在hdfs上创建一下data目录

hadoop fs -put ./hadoop.tar.gz /data/

向hdfs上传一个文件进行测试

tail -f /usr/local/hadoop/logs/

file

hadoop-hadoop-datanode-s2.hadoop.log 查看数据节点的datanode日志

在web页面上查看文件

file

因为有3个副本所以每台机器上使用的容量是一样的

file

4 已经初始化分布式文件系统HDFS,怎么启动和关闭

#启动分布式文件系统HDFS
/usr/local/hadoop/sbin/start-dfs.sh
#关闭分布式文件系统HDFS
/usr/local/hadoop/sbin/stop-dfs.sh

file

关闭

file

5 HDFS HA

5.1 带HA的HDFS都包括哪些进程

#查看每个机器上的java进程
./ssh_all.sh jps 

file

#查看详细进程信息
ps -aux|grep java

从里面查看启动信息是否有你自己的配置,就是你配置的hadoop-env.sh里的信息

file

5.2 测试 HDFS HA 切换

注意HA不能切换是因为nn1和nn2的没有安装fuser,可在zkfc日志中看到

file

先用root用户 ,安装 在nn1和nn2上执行

yum -y install psmisc

重启hdfs集群,在执行HA切换。

切换前

file

切换后:

file

版权声明:原创作品,允许转载,转载时务必以超链接的形式表明出处和作者信息。否则将追究法律责任。来自海汼部落-阿布都的都,http://hainiubl.com/topics/76036
成为第一个点赞的人吧 :bowtie:
回复数量: 0
    暂无评论~~
    • 请注意单词拼写,以及中英文排版,参考此页
    • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`, 更多语法请见这里 Markdown 语法
    • 支持表情,可用Emoji的自动补全, 在输入的时候只需要 ":" 就可以自动提示了 :metal: :point_right: 表情列表 :star: :sparkles:
    • 上传图片, 支持拖拽和剪切板黏贴上传, 格式限制 - jpg, png, gif,教程
    • 发布框支持本地存储功能,会在内容变更时保存,「提交」按钮点击时清空
    Ctrl+Enter