目录
1.HDFS的基础概念
1.1基本概念:
- 是一个文件系统,用于存储文件,通过目录树来定位文件;
- 是分布式的,由很多服务器联合起来实现其功能,集群中的服务器有各自的角色。
- 适合一次写入,多次读出的场景,且不支持文件的修改。
- 不需要RAID对磁盘做一个备份,而是直接通过冗余数据备份在不同机架的节点上来保证数据可靠,当机器/磁盘出现异常,通过其它副本快速恢复。
- 数据正确性可以通过checksum校验和或者cyc循环冗余校验码进行检验;
1.2基本组成:
- NameNode(nn):存储文件的元数据(描述数据特征的信息),可以对客户端的请求(优先空闲的主机)以及datanode的数据块(数据迁移)这两方面来进行负载均衡,来保证更高的性能。
- DataNode(dn):在本地文件系统存储文件块数据--默认128MB,以及块数据的校验和(实际的数据信息)。
- Secondary NameNode(2nn):可以监控HDFS状态的辅助后台程序,每隔一段时间获取HDFS元数据的快照,以及将NameNode的编辑文件转化为映射文件。
1.3存储单元
- 会把一个文件分成若干个Block块,在老版本默认为64MB,新版本为128MB;
- 这是为了将传输数据和等待io就绪的时间满足一定比例,来符合规定;
- 扩展:存储单元的大小会影响元数据的大小,也会影响传输时间和等待io的时间比值;
1.4节点之间的数据通讯
- 基于RPC通讯:适合数据小传输块的场景,对文件/目录的基本操作使用RPC的方式;
- 基于TCP流通讯:文件的读写使用基于TCP的流式数据接口访问有利于批量处理数据,提高效率;
- 基于HTTP通讯:NameNode和SecondaryNameNode的通讯合并编辑日志和镜像日志文件基于HTTP的方式实现,内建了HTTP服务器Jetty来实现;
- 扩展:TCP流通讯的实现;
- 使用socket实现tcp的数据接口访问,tcp基于字节流没有消息边界的概念,比如读请求发送的数据包含数据长度、偏移量、数据块id、访问tocken、操作码标示等信息,然后读响应会有多个数据包,包含包长度、是否为最后一个包、校验和、实际数据;
- 扩展:文件的读写为什么不使用HTTP或者RPC的方式实现而要自己写一个;
- 大数据量的传输不适合RPC的适用场景,如果放在一块那么会导致读写请求阻塞小请求,而基于HTTP的方式效率方面不如直接使用TCP的方式,所以就自己利用Socket的方式实现了通信;
2.HDFS的基本组件
2.1HDFS写数据流程
- 客户端进行写数据的时候,不会全用客户端去写这样会有网络瓶颈,而是用流水线的去写进行向后传播的方式;
- 请求服务器的时候为了高效都使用了RPC调用;
- 写入数据的时候也会计算校验和,并在读取数据的时候验证校验和,来保证数据是正确的;
- 同步数据做备份的时候,会根据分区/机架来进行选取,比如需要备份三份数据:
- 第一个副本在client所处的节点上。如果客户端在集群外,随机选一个。
- 老版本:
- 第二个副本和第一个副本位于相同机架,随机节点。
- 第三个副本位于不同机架,随机节点。
- 新版本:
- 第二个副本和第一个副本位于不同机架,随机节点。
- 第三个副本和第二个副本在相同机架,随机节点。
- 更多副本,随机节点;
- 写数据时,如果namenode是一个主从结构保证高可用,那么要保证分布式的强一致性,需要考虑提供出paxos/raft协议的接口;
2.2HDFS读数据流程
- 请求服务器的时候为了高效都使用了RPC调用;
2.3NameNode 和 Secondary NameNode工作机制
- 默认情况checkpoint,每小时执行一次,或者编辑日志里的操作次数达到一百万时,就是做一个持久化的东西最多丢失部分数据而已。
- Fsimage文件:HDFS文件系统的元数据,其中包含HDFS文件系统的所有目录和文件的信息。
- Edits文件:HDFS文件系统的所有更新操作的记录,文件系统客户端执行的所有写操作首先会被记录到edits文件中。
- namenode上文件path到文件块的对应以及文件块到datenode节点的对应,第一个是会进行持久化的,第二个由于是动态变化的不适合于持久化。
2.4DataNode工作机制
- 1.更新namenode的数据块映射的datenode
- 2.发送心跳包给namenode,判断datenode是否宕机
- 3.通过心跳包来惰性删除数据;
- HDFS默认的心跳超时时长为10分钟+30秒;
- 如果定义超时时间为timeout,则超时时长的计算公式为
- timeout = 2 * dfs.namenode.heartbeat.recheck-interval + 10 * dfs.heartbeat.interval。
- 而默认的dfs.namenode.heartbeat.recheck-interval 大小为5分钟,dfs.heartbeat.interval默认为3秒。
- 拷贝队列是一个优先级队列,Master Server根据多个因素来评估文件块的优先级,从而决定哪些文件块将被优先拷贝。
- 评估的因素包括:该文件块所剩余的拷贝数,该文件块是否有客户端在等待读写,该文件块损坏了几个拷贝,该文件块在过去的—段时间内被读写的次数
3.HDFS的优缺点
3.1优点一高容错性:
- 数据自动保存多个副本。它通过增加副本的形式,提高容错性。
- 某一个副本丢失以后,它可以用其他节点自动恢复。
3.2优点二适合大数据处理:
- 数据规模:能够处理数据规模达到 GB、TB、甚至PB级别的数据。
- 文件规模:能够处理百万规模以上的文件数量,数量相当之大。
3.3优点三流式数据访问:
- 一次写入,多次读取,不能修改,只能追加。
- 由于禁止并发所以它能保证数据的一致性。
3.4优点四节约成本:
- 可构建在廉价机器上,降低了服务器的费用成本,通过多副本机制,提高可靠性。
3.5缺点一不适合低延时数据存储,
- 比如毫秒级的存储数据,是做不到的。
- 存储进行寻址很慢,还要拷贝冗余数据。
3.6缺点二无法高效的对大量小文件进行存储。
- 存储大量小文件会造成NameNode的内存上涨会特别快不利于维护。
- 小文件存储的会独占一个block块,会造成内存浪费!
- 扩展:处理小文件的方案;
- 创建HAR文件,建立一个两层索引的结构来索引到具体的小文件可以缓解;
- 创建Sequence Files文件,将小文件组装成key-value的形式合并成一个大文件的过程;
3.7缺点三并发写入、文件随机修改。
- 一个文件只能有一个写,不允许多个线程同时写。
- 仅支持数据 append(追加),不支持文件的随机修改。
3.8缺点四namenode存储的元数据大小受限。
- NameNode在内存中存储所有的元数据(metadata),因此单个namenode所能存储的对象(文件+块)数目受到namenode所在JVM的heap size的限制。
- 如果业务太大,不同应用可以使用不同NameNode进行数据管理。
4.HDFS的HA高可用
4.1高可用的概念
-
在HDFS集群中NameNode存在单点故障,如果NameNode出现问题那么整个集群将不可用;
-
HDFS HA功能通过两个nameNodes实现在集群中对NameNode的热备来解决上述问题。如果出现故障,如机器崩溃或机器需要升级维护,这时可通过此种方式将NameNode很快的切换到另外一台机器,来保证整个集群可用。
4.2自动故障转移工作机制
- 自动故障转移为HDFS部署增加了两个新组件:ZooKeeper和ZKFailoverController(ZKFC)进程。ZooKeeper是维护少量协调数据,通知客户端这些数据的改变和监视客户端故障的高可用服务。
- HA的自动故障转移依赖于ZooKeeper的以下功能:
- 故障检测:集群中的每个NameNode在ZooKeeper中维护了一个临时会话,如果机器崩溃,ZooKeeper中的会话将终止,ZooKeeper通知另一个NameNode需要触发故障转移。
- 现役NameNode选择:如果目前现役NameNode崩溃,另一个节点从ZooKeeper获得特殊的排外锁以表明它应该成为现役NameNode。
- ZKFC是自动故障转移中的客户端,是高可用功能的实现。
- 高可用中主从节点的数据同步:
- 如果按照之前主节点同步给从节点日志记录,因为不确定从节点信息,所以通过在主从节点之前加一个高可用的日志管理系统,主节点写日志从节点读日志来保证数据最终一致而不是直接丢失。
- 活动节点同步给待命节点的操作记录。这类数据由活动节点同步给日志节点,再由日志节点同步给待命节点。日志又至少有 3 态机器的集群保管,每个上放一个日志节点。
- 高可用中zookeeper的故障转移:
- 通过zookeeper每个server创建一个顺序临时节点,保证最小的节点处于active状态,通过watch机制来进行监听实现故障转移;
- 当有server宕机那么节点会删除掉,watch监听到后就会通知其他server;
4.3内存受限问题
- 一个NameNode的元数据大小受限于JVM的堆内存;
- HDFS Federation(联邦) ,可以水平扩展,支持多个NameNode;
- 每个NameNode分管一部分目录,所有NameNode共享所有DataNode存储资源;