本帖最后由 亲心 于 2019-9-30 22:02 编辑
1.hadoop简介:
(1)分布式存储系统。HDFS(Hadoop Distirbuted File System)
#分布式存储系统。
#提供了高可靠/高拓展/高吞吐率的数据存储服务。
(2)分布式计算框架MapReduce。
#分布式计算框架
#具有易于编程/高容错率/高拓展性等有点。
2.HDFS优点:
(1)高容错性
#数据自动保存多个副本。
#副本丢失后,自动恢复。
(2)适合批处理。
#移动计算而非数据。
#数据位置暴露给计算框架
(3)适合大数据处理
#GB/TB/甚至PB级数据。
#百万规模以上的文件数量
#10k+节点
(4)可构建在廉价的机器上
#通过多副本提高可靠性。
#提供了容错和恢复机制。
3.HDFS缺点:
(1)低延迟数据访问
#比如毫秒级
#低延迟与高吞吐率
(2)小文件存取
#占用NameNode大量内存
#寻道时间超过读取时间
(3)并发写入/文件随机修改
#一个文件只能有一个写者
#仅支持append
4.HDFS 数据存储单元(block)
(1)文件被切分成固定大小的数据块:默认数据块大小为64MB(hadoop1.x),可配置。若文件大小不到64MB,则单独存成一个block。
(2)一个文件存储方式:按大小被切分成若干个block,存储到不同节点上,默认情况下每个block都有三个副本。
(3)Block大小和副本数通过Client端上传文件时设置,文件上传成功后副本数可以变更,Block Size不可变更。
5. NameNode(NN)
(1)NameNode主要功能:接受客户端的读写服务
(2)NameNode保存metadate信息包括
#文件owership和permissions
#文件包含哪些块
#Block保存在哪个DataNode(由DataNode启动时上报)
(3)NameNode的metadate信息在启动后会加载到内存
#metadata存储到磁盘文件名为”fsimage”
#Block的位置信息不会保存到fsimage
#edits记录对metadata的操作日志
6.SecondaryNameNode(SNN)
(1)它不是NN的备份(但可以做备份),它的主要工作是帮助NN合并edits log,减少NN启动时间。
(2)SNN执行合并时机
#根据配置文件设置的时间间隔fs.checkpoint.period 默认3600秒。
#根据配置文件设置edits log大小 fs.checkpoint.size 规定edits文件的最大值默 认是64MB。
7.DataNode(DN)
(1)存储数据(Block)
(2)启动DN线程的时候会向NN汇报block信息
(3)通过向NN发送心跳保持与其联系(3秒一次),如果NN10分钟没有收到DN的心跳,则认为其已经lost,并copy其上的block到其它DN。
8. Block的副本放置策略
(1)第一个副本:放置在上传文件的DN; 如果是集群外提交,则随机挑选一台 磁盘不太满,CPU不太忙的节点。
(2)第二个副本:放置在于第一个副本不 同的 机架的节点上。
(3)第三个副本:与第二个副本相同机架 的节点。
(4)更多副本:随机节点.
9.HDFS文件权限
(1)与Linux文件权限类似,r: read; w:write; x:execute,权限x对于文件忽略,对于文件夹表示是否允许访问其内容。
(2)如果Linux系统用户zhangsan使用hadoop命令创建一个文件,那么这个文件在HDFS中owner就是zhangsan。
(3)HDFS的权限目的:阻止好人错错事,而不是阻止坏人做坏事。HDFS相信,你告诉我你是谁,我就认为你是谁。
10.安全模式
(1)namenode启动的时候,首先将映像文件(fsimage)载入内存,并执行编辑日志(edits)中的各项操作。
(2)一旦在内存中成功建立文件系统元数据的映射,则创建一个新的fsimage文件(这个操作不需要SecondaryNameNode)和一个空的编辑日志。
(3)此刻namenode运行在安全模式。即namenode的文件系统对于客服端来说是只读的。(显示 目录,显示文件内容等。写、删除、重命名都会失败)。
(4)在此阶段Namenode收集各个datanode的报告,当数据块达到最小副本数以上时,会被认为是“安全”的,在一定比例(可设置)的数据块被确定为“安全”后,再过若干时间,安全模式结束。
(5)当检测到副本数不足的数据块时,该块会被复制直到达到最小副本数,系统中数据块的位 置并不是由namenode维护的,而是以块列表形式存储在datanode中。
11. 安装HDFS和hadoop。(集群)
使用四个real server做测试。realserver1,2,3,4.
(1)检查集群的机器时间基本一致(在30秒以内)
(2)安装java和ssh。
#安装SSH :基本CentOS已经安装好了。可以自己测试一下,如果需要安装自己在网上找教程。
#安装java:
- 首先下载java安装包到系统中,然后解压,配置环境变量。
CentOS7中 vi /etc/profile
export JAVA_HOME=/usr/java/jdk1.7.0_79
export PATH=PATH:PATH:JAVA_HOME/bin
source /etc/profile
- 测试:
$JAVA_HOME/bin/java -version和java -version输出的版本信息一致。
(3)免登录的配置。
#使用命令加密:ssh-keygen -t dsa -P ” -f ~/.ssh/id_dsa
- 在~/.ssh中有三个文件,id_dsa是私钥文件,自己使用,id_dsa.pub公钥文件,给别人使用,免密码登陆系统的时候使用。
#把公钥放到本机的认证文件中, cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys。这样登陆本机就不需要密码了。
#让本机登陆其他datenode不需要密码。
- 把本机的公钥复制给其他机器,scp ~/.ssh/id_dsa.pub root@192.168.0.5:/opt
- 把本机公钥添加到其他机器的认证文件中,cat /opt/id_dsa.pub >> ~/.ssh/authorized_keys
(4)拷贝hadoop2.5.1安装包到系统中,解压。配置文件。
#配置JAVA_HOME:hadoop-2.5.1/etc/hadoop/hadoop-env.sh.在文本内容中,修改JAVA_HOME的环境变量。
#vi core-site.xml:
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://192.168.0.4:9000</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/opt/hadoop-2.5</value>
</property>
</configuration>
#vi hdfs-site.xml:
<configuration>
<property>
<name>dfs.namenode.secondary.http-address</name>
<value>192.168.0.5:50090</value>
</property>
<property>
<name>dfs.namenode.secondary.https-address</name>
<value>192.168.0.5:50091</value>
</property>
</configuration>
#vi slaves:配置datenote的属性。
192.168.0.5
192.168.0.8
192.168.0.9
#vi masters:配置secondary namenode
192.168.0.5
(5)把安装在本机上的hadoop复制到各个节点中。
# scp -r hadoop-2.5.1/ root@192.168.0.9:/root
(6)配置hadoop的环境变量:在每个机器都配置。
#export HADOOP_HOME=/usr/yiyele/hadoop-2.5.1
export PATH=PATH:PATH:HADOOP_HOME/bin:$HADOOP_HOME/sbin
(7)格式化namenode,生成fsimage文件。
#hdfs namenode -format
#start-dfs.sh
#stop-dfs.sh
(8)如果以上配置完成后,还不能显示datanode,可以试着添加或修改主机名。hostname /etc/hosts /etc/hostname
12. HDFS 2.x
(1)解决HDFS1.0中的单点故障和内存受限问题。
#解决单点故障:
- HDFS HA:通过主备NameNode解决。除了edit文件不一致,其他文件基本一致。例如初始元数据,fsimage文件等,目的是为了实现瞬间接管。
如果在每次更新fsimage数据时,会同时更新备用NameNode的fsimage信息。datanode在发送block信息时,也会同时向备用NameNode发送。
- 如果主NameNode发生故障,则切换到备NameNode上。
#解决内存受限问题
- HDFS Federation
- 每个NameNode分管一部分目录
- 所有NameNode共享所有的DataNode存储资源
(2)2.x仅是架构上发生了变化,使用方式不变
#对HDFS使用者透明
#HDFS1.x中的命令和API仍可以使用。
13. 搭建HDFS HA集群:(实在hadoop集群搭建好的基础上进行修改)
(1)搭建zookeeper:server1 server2 server3
#安装zookeeper,解压。配置文件。
- 进入到zookeeper目录下的conf,创建文件zoo.cfg。 vi zoo.cfg
tickTime=2000
dataDir=/opt/zookeeper
clientPort=2181
initLimit=5
syncLimit=2
server.1=nginx1:2888:3888
server.2=nginx2:2888:3888
server.3=lvs:2888:3888
#在/opt/zookeeper/目录下创建myid文件。 vi myid
- 分别写入对应的id,1,2,3
#配置环境变量vi profile,把zookeeper目录下的bin加入PATH中。/usr/yiyele/zookeeper-3.4.6/bin
#启动zookeeper,在bin目录下,命令:zkServer.sh start
#连接内存数据库:zkCli.sh
(2)配置zookeeper和hadoop(保证zookeeper处于启动状态不变)
#删除hadoop配置文件中的masters(配置secondaryNameNode),删除hadoop的缓存文件。/opt/hadoop-2.5.
#编辑hdfs-site.xml:
- nameservices配置:
<property>
<name>dfs.nameservices</name>
<value>mycluster</value> //nameservice ID
</property>
- namenode配置:
<property>
<name>dfs.ha.namenodes.mycluster</name>
<value>nn1,nn2</value> //两个namenode的名称
</property>
- nameNode的rpc协议具体配置:(修改两个namenode的value值)
<property>
<name>dfs.namenode.rpc-address.mycluster.nn1</name> //注意nameservice ID要一致
<value>machine1.example.com:8020</value> //第一个namenode的配置
</property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn2</name>
<value>machine2.example.com:8020</value> //第二个namenode的配置
</property>
- namenode的http协议的具体配置:(修改两个namenode的value值)
<property>
<name>dfs.namenode.http-address.mycluster.nn1</name>
<value>machine1.example.com:50070</value> //第一个namenode的配置
</property>
<property>
<name>dfs.namenode.http-address.mycluster.nn2</name>
<value>machine2.example.com:50070</value> //第二个namenode的配置
</property>
- edits文件的共享目录:
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://node1.example.com:8485;node2.example.com:8485;node3.example.com:8485/mycluster</value>
</property>
- java连接NameNode的配置:基本不用修改
<property>
<name>dfs.client.failover.proxy.provider.mycluster</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
- <property>
<name>dfs.ha.fencing.methods</name>
<value>sshfence</value>
</property>
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/home/exampleuser/.ssh/id_rsa</value> //私钥目录
</property>
- 配置journalnode的数据存放目录:
-
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/path/to/journal/node/local/data</value>
</property>
#编辑 core-site.xml文件
- <property>
<name>fs.defaultFS</name>
<value>hdfs://mycluster</value> //nameservice ID
</property>
- <property>
<name>hadoop.tmp.dir</name>
<value>/opt/hadoop-2.5</value>
</property>
# 以上是手动切换的配置,如果需要自动切换则需:
- 编辑hdfs-site.xml:
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
- 编辑core-site.xml:配置zoodeeper的三台服务器。(server1 server2 server3)
<property>
<name>ha.zookeeper.quorum</name>
<value>zk1.example.com:2181,zk2.example.com:2181,zk3.example.com:2181</value>
</property>
(3)首先启动journaynode。(确保配置文件在各个服务器上都配置好)确保journalnode启动成功,才进行下面的步骤。
# 命令:hadoop-daemon.sh start journalnode
# 查看journalnode的日志,看看是否有错。
(4)同步两台namenode中的元数据。
# 首先任意格式化一个namenode,命令:hdfs namenode -format
# 然后把格式化后的namenode中的目录数据拷贝到另一台namenode中。/opt/hadoop-2.5
(5)初始化zookeeper。(在任意一个namenode中)
# 命令:hdfs zkfc -formatZK
(6)在免密码登陆的服务上,启动服务。
# 命令: start-dfs.sh
- 分别启动两个namenode 三个datanode 三个journalnnode 两个zookeeper。检查启动的信息。
# 单独启动节点的命令:
hadoop-daemon start datanode
zkServer.sh start
(7)检查:
# 分别用浏览器登录namenode的50070端口查看。
# 查看standby的namenode能否接管,强制关掉actived的namenode。
(8)注意:
# 注意让namenode的两个机器都能互相免密码登陆。
# 出错看日志。
14.熟悉hdfs hadoop-daemon start-dfs.sh等命令。
15.MapReduce:离线的分布式计算框架。
(1)设计概念:移动计算,不是移动数据。
(2)步骤:
# input 输入数据
# splitting 分割block数据。
# Mapping 输出key-value的值,负责把复杂的任务分解为若干个简单的任务执行。(数据规模小,就近计算,小任务并行计算)
# shuffling 复制/排序/合并等
# reducing 操作,对mapping数据进行汇总(默认是一个)
# output 输出。
(3)shuffler:
# input->map->buffer in memory->partitioin,sort,spill to disk->merge on disk->fetch->sort/group->reduce->output
- buffer in memory:把数据读到内存,当达到阈值后,就存在磁盘中。
- partitioin:计算分区号,默认是做key的hash值做取模运算。
- sort:排序。对maptask输出数据进行排序。默认排序算法是key值的字典(ASCII)排序。
- spill to disk:溢出到磁盘,内存中数据达到阈值,就存到磁盘中。
- merge on disk:在磁盘中合并
- fetch:把第一阶段合并的数据抓到(根据分区号)reduce的前处理中。可以被抓到各个reduce的task中去。
- sort/group:排序,使用默认算法。然后分组(根据键是否相等)。
- reduce:每组(排序后)数据都会传到reduce中进行计算。
- output:输出结果。
# conbiner:默认不执行,作用是把键相同的值累加,有分组的效果。所以执行这个操作会导致分组操作执行两次。
(4)split的大小:
# 公式:max(min.split,min(max.split,block))
- min.split:10M
- max.split:100M
- block: 64M
# 以上值为默认值。
(5)运行环境:YARN。
# 简介:hadoop2.x的运行环境,包括Resource Manager/Node Manager(container,App Mstr)
# 详细过程见官方文档。
16.YARN配置:
# 编辑yarn-site.xml.
- <property>
<name>yarn.resourcemanager.ha.enabled</name>
<value>true</value>
</property>
<property>
<name>yarn.resourcemanager.cluster-id</name>
<value>cluster1</value>
</property>
<property>
<name>yarn.resourcemanager.ha.rm-ids</name> //配置两个resource manager
<value>rm1,rm2</value>
</property>
<property>
<name>yarn.resourcemanager.hostname.rm1</name> //配置第一个resource manager
<value>master1</value>
</property>
<property>
<name>yarn.resourcemanager.hostname.rm2</name> //配置第二个resource manager
<value>master2</value>
</property>
<property>
<name>yarn.resourcemanager.zk-address</name> //配置zookeeper
<value>zk1:2181,zk2:2181,zk3:2181</value>
</property>
# 编辑mapred-site.xml
- <property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
# 编辑yarn-site.xml
- <property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
# 启动:
- 命令:start-yarn.sh
- 启动备用resource manager:yarn-daemon.sh start resourcemanager
# 检测:
- 访问主节点8088端口。查看信息
- 访问备用的主节点8088端口。查看信息,会重定向到主节点的页面。
17.执行。
# 第一种方式:服务器环境:(需要src下放置hadoop的配置文件)
- 1.hadoop jar 包名 执行类名(加上打包的名)
- 2.服务器环境第二种方式:(企业使用)
* 把jar包直接放在本地上
* 修改hadoop的源码,注意:确保项目的lib需要真实安装的jdk的lib
* 增加一个属性:
config.set("mapred.jar","jar包所在的路径");
* 本地执行main方法,servlet调用MR
# 第二种方式:本地测试环境:
- 在hadoop目录下的bin目录中添加winutils.exe
- 在window下配置hadoop的环境变量
- 修改hadoop的源码,注意:确保项目的lib需要真实安装的jdk的lib
- MR调用的代码需要改变:
* src不能有服务器的hadoop配置文件
* 在调用时使用:
Configuration config = new Configuration();
config.set("fs.defaultFS",“hdfs://node7:8020”); //指定namenode的主机名和端口号
config.set("yarn.resourcemanager.hostname",node7); //指定resourcemanager的主机名和端口
|
|