day01 Hadoop 简单介绍及架构设计
第一章 单机大数据处理实现以及问题
1T 文件,数字,按行存储
- 找出文件重复行
- 全排序
- 单词重复数
只有一台
128M,64M,256G
1,内存不能放下全量数据 OOM
第二章 多机分布式大数据处理推导-hadoop 概念介绍
第一节 多机分布式大数据处理推导
并行:提升速度的关键
分而治之:并行计算
分布式运行
计算与数据在一起
- 计算向数据移动
解决办法:
第一步:多台服务器存储文件。实现分布式存储。
第二步:分别在每台服务器上计算是否有重复行。 实现分布式计算(计算与数据在一起“计算向数据移动”)
第三步:所有服务器同时计算。实现 并发。
其实还存在一个问题,将这个1T的文件分割成小文件分别存放到多台服务器上所耗费的时间其实是巨大的,非常耗时。所以,一般在企业的生产环境中,数据量大的文件一般都不会存放在同一个磁盘中。
第二节 hadoop概念介绍
起源
Hadoop的思想之源:Google
- Openstack: NASA
面对的数据和计算难题
- 大量的网页怎么存储
- 搜索算法
带给我们的关键技术和思想
- GFS
- Map-Reduce
- Bigtable
简介
Hadoop简介:http://hadoop.apache.org
- 分布式存储(文件)系统HDFS (Hadoop Distributed File System )POSIX
- 分布式存储系统
- 提供了 高可靠性、高扩展性和高吞吐率的数据存储服务
- 分布式计算框架MapReduce
- 分布式计算框架(计算向数据移动)
- 具有 易于编程、高容错性和高扩展性等优点。
- 用于处理超大数据集计算的MapReduce编程模型的实现
- 分布式资源管理框架YARN(Yet Another Resource Management)
- 负责集群资源的管理和调度
第三章 hdfs-存储模型-架构模型
存储模型:字节
- 文件线性切割成块(Block):偏移量 offset (byte)
- 偏移量:块的第一个字节面向源文件的下标就是偏移量
- 如 每个块有四个字节 ,第一块的偏移量就是0,第二块的偏移量为4…
- Block分散存储在集群节点中
- 单一文件Block大小一致,文件与文件可以不一致
- 每个block的最大存储相同,每个块中的文件大小可以不同
- Block可以设置副本数,副本分散在不同节点中
- 副本数不要超过节点数量
- 文件上传可以设置Block大小和副本数
- 已上传的文件Block副本数可以调整,大小不变
- 只支持一次写入多次读取,同一时刻只有一个写入者
- 可以append追加数据
架构模型
- 文件元数据MetaData,文件数据
- 元数据:元数据指用来描述一个文件的特征的系统数据,诸如访问权限、文件拥有者以及文件数据
- 元数据(Metadata),又称中介数据、中继数据,为描述数据的数据(data about data),主要是描述数据属性(property)的信息,用来支持如指示存储位置、历史数据、资源查找、文件记录等功能。
- 数据本身:数据是指普通文件中的实际数据
- (主)NameNode节点保存文件元数据:单节点 posix
- 接受客户端的读写请求。
- 存储和管理HDFS的元数据
- (从)DataNode节点保存文件Block数据:多节点
- 存放和管理block(数据)
- 往NN汇报block
- DataNode与NameNode保持心跳,提交Block列表
- HdfsClient与NameNode交互元数据信息
- HdfsClient与DataNode交互文件Block数据
HDFS设计思想
第四章 hdfs-角色介绍-namenode-datanode
第一节 namenode
NameNode(NN)
基于内存存储:不会和磁盘发生交换
- 只存在内存中(这样能够保证速度更快)
- NameNode数据(存储文件的元数据)存储在内存中,关机落磁盘,开机时加载fsimage文件和edits log文件,合并元数据和操作的记录。
- 1)命名空间镜像文件(fsimage):存储多个NameNode信息。(一个文件一个NameNode)
2)编辑日志(edits log):程序运行过程中对DataNode的操作记录。
- 持久化(fsimage,edits log)
- 由于NameNode存储在内存中,所以掉电易失。
- 不会持久化block的位置信息
NameNode主要功能:
- 接受客户端的读写服务
- 收集DataNode汇报的Block列表信息
- 存储和管理HDFS的元数据
- 文件的block副本个数
(每个块默认有3个副本。) - 文件修改和访问的时间
- 文件访问权限
- block大小以及组成文件的block信息(大小默认为128M)
NameNode保存metadata元数据信息包括
- 文件owership(所属用户)和permissions(权限)
- 文件大小,时间
- (Block列表:Block偏移量),位置信息
- Block每个副本的位置(由DataNode上报)
元数据:除文件内容之外的数据即为元数据。包括文件的名字、时间、所属用户、权限、大小等等,包括block的位置信息(block的编号,偏移量,大小…)。
块的偏移量不会发生变化,因为block不可以调整大小
NameNode持久化
- NameNode的metadate信息在启动后会加载到内存
- metadata存储到磁盘文件名为”fsimage”
- Block的位置信息不会保存到fsimage
- edits记录对metadata的操作日志。。。redis
第二节 DataNode(DN)
DataNode(DN)
- 本地磁盘目录存储数据(Block),文件形式
- 同时存储Block的元数据信息文件
- 面向文件,大小一样,不能调整
- 副本数可以调整,(备份,高可用,容错 / 可以调整很多个,为了计算向数据移动)
- 启动DN时会向NN汇报block信息
- block(数据块):一个块的最大存储为128M ,数据文件切割之后形成一个一个的数据块。 每个块默认有3个副本。
- 通过向NN发送心跳保持与其联系(3秒一次),如果NN 10分钟没有收到DN的心跳,则认为其已经lost,并copy其上的block到其它DN
- 每3秒DataNode向NameNode发送一次心跳信息,每30秒DataNode向NameNode发送一次Block信息。如果接收不到的的话NameNode就会认为其对应的DataNode机器宕机了。
DataNode功能
- 存放和管理block(数据)
- 往NN实时汇报block信息(block编号,偏移量,大小…)
第三节 HDFS的优缺点
HDFS优点:
- 高容错性
- 数据自动保存多个副本
- 副本丢失后,自动恢复
- 适合批处理
- 移动计算而非数据
- 数据位置暴露给计算框架(Block偏移量)
- 适合大数据处理
- GB 、TB 、甚至PB 级数据
- 百万规模以上的文件数量
- 10K+ 节点
- 可构建在廉价机器上
- 通过多副本提高可靠性
- 提供了容错和恢复 机制
HDFS缺点
- 低延迟数据访问
- 比如毫秒级
- 低延迟与高吞吐率
- 小文件存取
- 占用NameNode 大量内存
- 寻道时间超过读取时间
- 并发写入、文件随机修改
- 一个文件只能有一个写者
- 仅支持append
第五章 hdfs-fsimage 与edits 合并
命名空间镜像文件(fsimage):存储多个NameNode信息。(一个文件一个NameNode)
编辑日志(edits log):程序运行过程中对DataNode的操作记录。
fsimage和edits log均存储在磁盘,而不是内存上
第一节 SecondaryNameNode(SNN)
它不是NN的备份(但可以做备份),它的主要工作是帮助NN合并edits log到fsimage中,减少NN启动时间。
SNN执行合并时机
- 根据配置文件设置的时间间隔fs.checkpoint.period 默认3600秒
(一小时) - 根据配置文件设置edits log大小 fs.checkpoint.size 规定edits文件的最大值默认是64MB
edits
log文件很小,每次做合并操作时不会耗时很久。
- 为什么edits log文件很小?
- HDFS架构中,除了NameNode,还有一个SecondaryNameNode.
- SecondaryNameNode就是当edits log文件到达一定阈值时或到达规定的时间时会获取NameNode中的fsimage和editslog文件并将它们做一次合并,然后将新的fsimage文件发送给NameNode,这样edits log文件就可以更新为空文件,继续存储新的操作记录。
第二节SNN合并流程
步骤
工作流程如下:
- secondarynamenode请求namenode
生成新的edits log文件并向其中写日志。
NameNode会在所有的存储目录中更新
seen_txid文件 - SecondaryNameNode通过HTTP GET
的方式从NameNode下载fsimage和edits
文件到本地。 - SecondaryNameNode将fsimage加载到自己
的内存,并根据edits log更新内存中的fsimage
信息,然后将更新完毕之后的fsimage写到磁
盘上。 - SecondaryNameNode通过HTTP PUT将新的
fsimage文件发送到NameNode,NameNode将
该文件保存为.ckpt的临时文件备用。 - NameNode重命名该临时文件并准备使用。此时NameNode拥有一
个新的fsimage文件和一个新的很小的edits log文件(可能不是空的,因为在SecondaryNameNode合并期间可能对元数据进行了读写操作),管理员也可以将NameNode置于safemode,通过hdfs
dfsadmin -saveNamespace命令来进行edits log和fsimage的
合井。
SecondaryNameNode要和NameNode拥有相同的内存。
对大的集群,secondaryNameNode运行于一台专用的物理主机。
注意
- namenode启动的时候,首先将映像文件(fsimage)载入内存,并执行编辑日志(edits)中的各项操作。
- 一旦在内存中成功建立文件系统元数据的映射,则创建一个新的fsimage文件(这个操作不需要SecondaryNameNode)和一个空的编辑日志。
- 程序关机时,系统会将fsimage与edits log做一次合并为新的fsimage文件,当系统重新启动时,会加载新的fsimage文件。
- 安全模式:
- fsimage文件不会记录每个block所在的DataNode信息。这些信息在每次系统开机启动的时候从DataNode(DataNode向NameNode发送心跳)重建。之后DataNode会周期性地通过心跳包向NameNode报告block信息。
- DataNode向NameNode注册的时候NameNode会请求DataNode发送block列表信息。
- edits
log文件很小,每次做合并操作时不会耗时很久。
为什么edits log文件很小?
HDFS架构中,除了NameNode,还有一个SecondaryNameNode.
SecondaryNameNode就是当edits log文件到达一定阈值时或到达规定的时间时会获取NameNode中的fsimage和editslog文件并将它们做一次合并,然后将新的fsimage文件发送给NameNode,这样edits log文件就可以更新为空文件,继续存储新的操作记录。
第三节 Block的副本放置策略
- 第一个副本:放置在上传文件的DN;如果是集群外提交,则随机挑选一台磁盘不太满,CPU不太忙的节点。
- 第二个副本:放置在于第一个副本不同的 机架的节点上。
- 第三个副本:与第二个副本相同机架的节点。
- 更多副本:随机节点
记住:副本的第一个副本和第二个副本不会在一个机架上
白色:文件 黑色:文件切割后的三个块
第六章 hdfs-读写流程
第一节 HDFS写流程
Client:
- 切分文件Block
- 按Block线性和NN获取DN列表(副本数)
- 验证DN列表后以更小的单位流式传输数据
- 各节点,两两通信确定可用
- Block传输结束后:
- DN向NN汇报Block信息
- DN向Client汇报完成
- Client向NN汇报完成
- 获取下一个Block存放的DN列表
- 。。。。。。
- 最终Client汇报完成
- NN会在写流程更新文件状态
把数据队列中的packet写入DN时,是同步在多个DN副本中进行写入的
第二节 HDFS读流程
Client:
- 和NN获取一部分Block副本位置列表
- 线性和DN获取Block,最终合并为一个文件
- 在Block副本列表中按距离择优选取
注意
- NameNode会为客户端返回一个按距离排序的block副本列表,然后从距离最近的block开始进行读取
- 拥有在任意范围读取block的能力
结论:HDFS很好的支撑了计算层的本地化读取
从DN中读取block不是同步进行的,必须读取完一个后再读取下一个
第三节 HDFS文件权限 POSIX
- 与Linux文件权限类似
- r: read; w:write; x:execute
- 权限x对于文件忽略,对于文件夹表示是否允许访问其内容
- 如果Linux系统用户zhangsan使用hadoop命令创建一个文件,那么这个文件在HDFS中owner就是zhangsan。
- HDFS的权限目的:阻止好人错错事,而不是阻止坏人做坏事。HDFS相信,你告诉我你是谁,我就认为你是谁。
第四节 安全模式
- namenode启动的时候,首先将映像文件(fsimage)载入内存,并执行编辑日志(edits)中的各项操作。
- 一旦在内存中成功建立文件系统元数据的映射,则创建一个新的fsimage文件(这个操作不需要SecondaryNameNode)和一个空的编辑日志。
- 此刻namenode运行在安全模式。即namenode的文件系统对于客服端来说是只读的。(显示目录,显示文件内容等。写、删除、重命名都会失败)。
- 在此阶段Namenode收集各个datanode的报告,当数据块达到最小副本数以上时,会被认为是“安全”的, 在一定比例(可设置)的数据块被确定为“安全”后,再过若干时间,安全模式结束
- 当检测到副本数不足的数据块时,该块会被复制直到达到最小副本数,系统中数据块的位置并不是由namenode维护的,而是以块列表形式存储在datanode中。
总结
- 集群
- 角色==进程
- namenode
- 数据元数据
- 内存存储,不会有磁盘交换
- 持久化(fsimage,eidts log)
- 不会持久化block的位置信息
- block:偏移量,因为block不可以调整大小,hdfs,不支持修改文件
- 偏移量不会改变
- datanode
- block块
- 磁盘
- 面向文件,大小一样,不能调整
- 副本数,调整,(备份,高可用,容错/可以调整很多个,为了计算向数据移动)
- SN
- NN&DN
- 心跳机制
- DN向NN汇报block信息
- 安全模式
- client
第七章 HDFS环境搭建配置解读
一,操作系统环境
- 依赖软件ssh,jdk
- 环境的配置
- java_home
- 免密钥
- 时间同步
- hosts,hostname
二,hadoop部署
- /opt/sxt/
- 配置文件修改
- java_home
- 角色在哪里启动
第八章 伪分布式环境搭建
先决条件
- 三台机器(以上)
- 每台机器时间一致,相差30秒以内。
- 必须有主机名和ip映射。
- 必须有JDK1.7,并且JDK的环境变量必须配置好。
- rpm -ivh jdk-7u79-linux-x64.rpm 安装jdk
- 配置环境变量:vi ~/.bash_profile
在文件的最后添加:
export JAVA_HOME=/usr/java/default
export PATH=JAVA_HOME/bin
source ~/.bash_profile
- 防火墙暂时关闭。
i. service iptables stop
ii. chkconfig iptables off
具体步骤
- 安装JDK并完成相关配置
(1)安装jdk
rpm –ivh jdk-7u80-linux-x64.rpm -I install,-v 查看安装进度,-h 计算hash值
注:如何查看jdk的安装路径
whereis java :查看java命令的路径
cd /usr/java
ls :->jdk1.7.0_80
cd /jdk1.7.0_80
pwd 复制jdk的安装路径
(2)vi /etc/profile 配置环境变量
export JAVA_HOME=jdk的安装路径
export PATH=JAVA_HOME/bin
wq
(3)执行 . /etc/profile 让配置生效 - 在root用户的家目录下创建myapps目录,通过xftp上传jdk1.7.0_80和hadoop—2.6.5.tar.gz
- 解压hadoop,配置相关环境变量。
- 解压tar –zxvf hadoop-2.6.5.tar.gz
cd ~/myapps/hadoop-2.6.5
pwd 复制路径
/root/myapps/hadoop-2.6.5
[root@node01 myapps]# ls
hadoop-2.6.5 hadoop-2.6.5.tar.gz
- 配置环境变量(配置Hadoop到/etc/profile)
[root@node01 hadoop-2.6.5]# vi /etc/profile
....
#添加两行
export HADOOP_HOME=/root/myapps/hadoop-2.6.5
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
- 执行文件,让配置生效
source /etc/profile
- 配置/etc/hosts文件
[root@node01 hadoop]# vi /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.223.101 node01
192.168.223.102 node02
192.168.223.103 node03
192.168.223.104 node04
此时即可使用主机名代替ip地址进行访问
[root@node01 hadoop]# ssh node02
root@node02's password:
Last login: Wed Jun 12 03:34:01 2019 from 192.168.223.101
[root@node02 ~]#
- 配置免密钥登录
- 生成密钥
ssh
–keygen :生成公钥和私钥。
[root@node01 hadoop-2.6.5]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
d6:25:c7:8a:ad:b5:13:ca:ce:05:e2:22:6c:45:75:8f root@node01
The key's randomart image is:
+--[ RSA 2048]----+
| . . |
| . . o . |
| . E o + |
| . + = |
| . . S * |
| . . . + = o |
| + . . + + |
| . . . o . . |
| o |
+-----------------+
- 把公钥拷给主机
[root@node01 .ssh]# ssh-copy-id -i ./id_rsa.pub root@node01
root@node01's password:
Now try logging into the machine, with "ssh 'root@node01'", and check in:
.ssh/authorized_keys
to make sure we haven't added extra keys that you weren't expecting.
[root@node01 .ssh]# ssh-copy-id -i ./id_rsa.pub root@node02
root@node02's password:
Permission denied, please try again.
root@node02's password:
Now try logging into the machine, with "ssh 'root@node02'", and check in:
.ssh/authorized_keys
to make sure we haven't added extra keys that you weren't expecting.
- 编辑hadoop配置文件:hadoop-env.sh, core-site.xml, hdfs-site.xml,Slaves 所有的配置文件在/root/myapps/hadoop-2.5.2/etc/hadoop目录中
- 配置hadoop-env.sh更改第25行
[root@node01 hadoop]# vi hadoop-env.sh
.....
export JAVA_HOME=/usr/java/default
- core-site.xml配置
[root@node01 hadoop]# vi core-site.xml
.....
<property>
21 <name>fs.defaultFS</name>
22 <value>hdfs://node01:9000</value>
23 </property>
24 <property>
25 <name>hadoop.tmp.dir</name>
26 <value>/opt/hadoop_data</value>
27 </property>
- Hdfs-site.xml 配置
[root@node01 hadoop]# vi hdfs-site.xml
<property>
21 <name>dfs.namenode.secondary.http-address</name>
22 <value>node01:50090</value>
23 </property>
24 <property>
25 <name>dfs.replication</name>
26 <value>1</value>
</property>
- Slaves
[root@node01 hadoop]# vi slaves
1 node01
- 继续
[root@node01 hadoop-2.6.5]# cd sbin/
[root@node01 sbin]# ./start-dfs.sh
19/06/11 22:40:22 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Starting namenodes on [node01]
root@node01's password:
node01: starting namenode, logging to /root/myapps/hadoop-2.6.5/logs/hadoop-root-namenode-node01.out
root@node01's password:
node01: starting datanode, logging to /root/myapps/hadoop-2.6.5/logs/hadoop-root-datanode-node01.out
Starting secondary namenodes [node01]
root@node01's password:
node01: starting secondarynamenode, logging to /root/myapps/hadoop-2.6.5/logs/hadoop-root-secondarynamenode-node01.out
19/06/11 22:41:01 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
[root@node01 sbin]# jps
1445 Bootstrap
2376 SecondaryNameNode
2237 DataNode
2493 Jps
[root@node01 sbin]# cd ..
[root@node01 hadoop-2.6.5]# cd bin/
[root@node01 bin]# ls
container-executor hadoop hadoop.cmd hdfs hdfs.cmd mapred mapred.cmd rcc test-container-executor yarn yarn.cmd
[root@node01 bin]# ./hadoop namenode -format
[root@node01 bin]# jps
1445 Bootstrap
2376 SecondaryNameNode
2237 DataNode
2557 Jps
[root@node01 bin]# cd ..
[root@node01 hadoop-2.6.5]# ls
bin etc include lib libexec LICENSE.txt logs NOTICE.txt README.txt sbin share
[root@node01 hadoop-2.6.5]# cd sbin/
[root@node01 sbin]# ls
distribute-exclude.sh hdfs-config.sh refresh-namenodes.sh start-balancer.sh start-yarn.cmd stop-balancer.sh stop-yarn.cmd
hadoop-daemon.sh httpfs.sh slaves.sh start-dfs.cmd start-yarn.sh stop-dfs.cmd stop-yarn.sh
hadoop-daemons.sh kms.sh start-all.cmd start-dfs.sh stop-all.cmd stop-dfs.sh yarn-daemon.sh
hdfs-config.cmd mr-jobhistory-daemon.sh start-all.sh start-secure-dns.sh stop-all.sh stop-secure-dns.sh yarn-daemons.sh
[root@node01 sbin]# ./hadoop-daemon.sh start namenode
starting namenode, logging to /root/myapps/hadoop-2.6.5/logs/hadoop-root-namenode-node01.out
[root@node01 sbin]# jps
1445 Bootstrap
2663 Jps
2376 SecondaryNameNode
2237 DataNode
2591 NameNode
- 测试
[root@node01 sbin]# cd ..
[root@node01 hadoop-2.6.5]# cd bin/
[root@node01 bin]# ls
container-executor hadoop hadoop.cmd hdfs hdfs.cmd mapred mapred.cmd rcc test-container-executor yarn yarn.cmd
[root@node01 bin]# ./hdfs dfs -put ~/jdk-8u171-linux-x64.rpm /
19/06/11 22:52:55 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
注意:上传的根目录不是root根目录,而是hdfs的根目录