Hadoop
开源版本的HADOOP和其他框架的对应关系很混乱,要注意。
Hadoop四大模块:Common HDFS MapReduce Yarn
Hadoop能对大量的数据进行分布式处理,可以轻松的从一台服务器扩展到千台服务器,并且 每一台服务器都能进行本地计算和存储。Hadoop还提供了用于处理和探测异常的机制。
HDFS
Master/slave结构
启动:master节点 start-dfs.sh node1节点:mapred --daemon start historyserver
node2节点:start-yarn.sh
http://${namenode所在机器的ip}:9870 HDFS的图形界面
Block
Block是HDFS数据存储的基本单位,存在DataNode上。
默认最大容量是134217728B(128MB)。
经过测试,一般而言,当寻址时间是写入时间的1%的时候,此时效率是最高的。大部分磁盘的寻址时间大约是10ms,那么就意味着写入时间大约是10ms*100=1000ms=1s的时候,效率最高。目前市面上,服务器基本上都是采用机械磁盘,大部分机械磁盘的写入速度是100MB/s~150MB/s,那么就意味着Block的大小在100M~150M之间。考虑到计算机中的存储单位进制的问题,所以采用了128M(1G=8*128)
300MB的文件会被分为3个Block,2*128+44
通过hdfs-site.xml中的dfs.blocksize属性调节。
每个Block有一个全局递增且唯一的BlockID
HDFS是数据安全的,默认每个Block会在不同节点有三份
切块使得HDFS能存储任意大的文件。
NameNode
对外负责接受请求,对内负责记录元数据和管理DataNode
元数据
一条元数据大约是150B,包含的内容有三十多项。重要的内容有
1.上传的文件名以及虚拟存储路径 2.文件所属用户和所属组
3.文件大小。权限 4.文件和BlockID的映射关系。
5.Block的大小 6,这个文件的副本数量 7,Block和DataNode的映射关系。
元数据放在内存和磁盘中。在磁盘上的存储位置是file://${hadoop.tmp.dir}/dfs/name
。hadoop.tmp.dir的值由dfs.namenode.name.dir属性决定。
和元数据相关的文件:edits_inprogress edits fsimage
当NameNode接收到写请求的时候,首先会将这个命令解析记录到edits_inprogress文件中。记录完成之后,会更新内存中的元数据。更新完成之后,会给客户端返回一个ACK信号表示记录成功。注意,在这个过程中,fsimage文件中的元数据没有更新!也就意味着,fsimage文件中的元数据和内存中的元数据不是同步的!!!
当达到指定条件之后,edits_inprogress文件就会产生滚动,滚动生成edits文件,同时产生一个新的edits_inprogress文件,新来的写操作记录到新的edits_inprogress文件中。生成edits文件之后,HDFS会解析edits文件,根据edits文件的内容,更新fsimage文件中的元数据
edits_inprogress的滚动条件
- 空间:默认情况下,每隔1min(可以通过
dfs.namenode.checkpoint.check.period
属性来调节,单位是秒,默认值是60)扫描一次edits_inprogress文件。当扫描edits_inprogress文件的时候,发现达到指定大小(可以通过dfs.namenode.checkpoint.txns
属性来调节,默认值是1000000,即edits_inprogress文件中记录达到1000000条)之后,会自动滚动生成edits文件 - 时间:当距离上一次滚动达到指定的时间间隔(可以通过
dfs.namenode.checkpoint.period
属性来调节,默认值是3600,单位是秒)的时候,edits_inprogress文件自动滚动生成edits文件 - 重启:当NameNode被重启的时候,也会自动触发edits_inprogress的滚动
- 强制:可以通过命令
hdfs dfsadmin -rollEdits
来强制滚动edits_inprogress
查看edits文件
sh
hdfs oev -i edits_0000000000000000012-0000000000000000028 -o a.xml
HDFS会给每一给写操作一个递增的编号,称之为事务id,简写为txid
在HDFS中,会将开始记录日志(OP_START_LOG_SEGMENT)和结束记录日志(OP_END_LOG_SEGMENT)都看作是写操作,都会分配一个事务id
上传文件的时候,NameNode如何拆分的命令
- OP_ADD :在指定路径下添加
文件名._COPYING_
文件 - OP_ALLOCATE_BLOCK_ID:分配BlockID(意味着对文件进行切块)
- OP_SET_GENSTAMP_V2:设置时间戳编号
- OP_ADD_BLOCK:上传(添加)Block
- OP_CLOSE:关闭文件(本质上就是关流)
- OP_RENAME_OLD:重命名文件
在HDFS中,文件一旦写完就不能修改!!!(HDFS中的文件不允许被修改!!!) 但是允许对一个文件追加。
查看fsimage文件
sh
hdfs oiv -i fsimage_0000000000000000033 -o a.xml -p XML
HDFS第一次启动之后1min,会自动触发一次edits_inprogress文件的滚动
NameNode会为每一个fsimage文件生成一个md5文件,用于对fsimage文件进行校验。
md5算法的使用场景:加密(非对称加密 ,没有解密算法,不可逆。) 校验(数据有一点一点的差异生成的结果就会差别特别大称为散列。为防止元数据被修改,因为md5后的结果为散列。一个文件有一个字母改变,生成的md5就差距很大,便于比较文件是否一致)
管理DataNode
-
NameNode通过心跳(heart beat)机制来管理DataNode:DataNode定时(通过
dfs.heartbeat.interval
属性来调节,默认值是3,单位是秒)给NameNode发送心跳信号。如果在一定时间内,NameNode没有收到DataNode的心跳信号,那么就表示这个DataNode已经lost(丢失),此时NameNode就会将这个DataNode上的数据重新备份到其他的DataNode上以保证整个集群中的副本数量 -
需要注意的是,心跳超时时间由两个属性决定:
dfs.heartbeat.interval
和dfs.namenode.heartbeat.recheck-interval
属性 默认值 单位 dfs.heartbeat.interval
3 秒 dfs.namenode.heartbeat.recheck-interval
300000 毫秒 心跳超时时间=2*
dfs.namenode.heartbeat.recheck-interval
+10*dfs.heartbeat.interval
,默认情况下,心跳超时时间=2*5min+10*3s=10min30s -
心跳信号
- clusterid:集群编号。
- 当NameNode被格式化(
hdfs namenode -format
)的时候,自动计算产生一个clusterid - HDFS启动之后,DataNode第一次给NameNode发送心跳,NameNode会在心跳响应中将clusterid返回给这个DataNode,并且要求DataNode在后续的请求(包括心跳)中携带clusterid
- 当NameNode收到DataNode的请求之后,会校验clusterid是否一致。如果clusterid一致,那么NameNode才会接收DataNode的请求或者心跳,如果不一致,那么可能会导致DataNode进程或者NameNode进程结束
- 每一次格式化,NameNode都会重新计算产生一个新的clusterid
- hadoop分布式第一次启动之前,要在第一个节点上格式化namenode。格式化后会生成一个验证(就是clusterid),当datanode第一次携带null给namenode发送心跳时,namenode发现他带的是null,就会把格式化生成的验证给datanode。之后的datanode都要携带这个验证。如果再次格式化namenode,那么datanode携带的验证不匹配。因为datanode携带的不是null,所以不会给datanode新的验证。此时datanode或namenode会随机有一方停机。通常是namenode。
- 当NameNode被格式化(
- 当前DataNode的状态(预服役、服役、预退役)
- clusterid:集群编号。
-
默认情况下,DataNode每隔6个小时(由
dfs.blockreport.intervalMsec
属性来调节,单位是毫秒,默认值是21600000),会给NameNode汇报一次当前DataNode上存储的Block情况
前置基础知识
内网传递资料: scp [ 目录需要加 -r ] 源文件 root@hadoop2:目标文件
// root是用户 hadoop2映射了主机ip
环境变量 vim /etc/profile.d/hadoophome.sh 全局变量 export 需要 source /etc/profile.d/hadoophome.sh 生效。