java基础巩固-宇宙第一AiYWM:为了维持生计,大数据Hadoop之HDFS分布式文件系统(HDFS读写流程、主从集群两种问题“单点故障”及“压力过大内存受限”、HDFS的架构设计)~整起


目录

一、大数据

  • 大数据重点:
    • 分而治之
      • 你分治了后,就得找个类似于注册中心这种中介中间商来记账,帮咱们管理这一帮被分开的小的
    • 并行计算
    • 计算向数据移动
      • 分布式计算追求的目标:
        • 计算向数据移动:由block和split两个合力,使得map和reduce等过程去找,哪有数据呀,哪有数据呀,找到了数据之后再计算,不就相当于计算追着数据跑,不就是说计算向数据移动嘛
        • 并行(度)、分治
        • 数据本地化读取
    • 数据本地化读取
  • 分治思想:
    • 假如刚开学或者新进一个公司,有人问你,喂大锅,一万个数字或者单词怎么存?,你告诉他,单双列集合。
      • 如果查找某一个元素,时间复杂度为O(N)
      • 如果我期望的时间复杂度为O(4) 怎么保证,理想情况下,此时我们可以把一万个数字或单词分为2500个链表,每个链表上四个元素,然后搞一个长度为2500的数组用来当作2500个链表的索引,也就是存这2500个链表。此时咱们如果找X,就用X.hashCode() % 2500 ,得到的值【对应长为2500那个数组的下标】是多少,相当于要去哪条链表中去找,这样一找不就是O(4)了嘛。那这么一搞就牵涉到了很多事情…
    • 单机下处理大数据:IO是单机最大瓶颈,IO太慢且内存太小,用多机
      • 如果有一个很大的文件,如1T,里面有很多行,只有两行相同,要找到这两行一样的行,咱们只有单机,可用的内存很少就几十兆【说明放不到内存中】
        • 内存寻址比磁盘寻址快了快十万倍
      • 暴力遍历,把每一行拿到内存中和其他行进行对比,因为IO是单机最大瓶颈,太慢了,所以不太行
      • 用取出的每一行的【readLine()】的hashCode值模一个数,比如2000,将这个大文件散列为2000个小文件,然后重复的行会落到一块,因为哈希算法是稳定的
    • 分布式集群处理大数据
      • 如果有一个很大的文件,如1T,里面有很多行,只有两行相同,要找到这两行一样的行,假设咱们用2000台机器,每台存储1/2000,也就是500MB左右的数据,然后2000台并行计算,每台readLine().hashCode() % 2000,处理500MB的数据,然后,让2000台中所有的同号码文件归到一台中
        在这里插入图片描述
    • 不管是单机还是分布式集群,明眼人一看,你小子不就是在玩分治思想嘛

二、HADOOP

在这里插入图片描述

  • Hadoop:
    • 项目有四个模块
      在这里插入图片描述
    • 而Hadoop生态中包含了Spark、Flink、HDFS等【https://cloud.tencent.com/developer/article/2088864】
      在这里插入图片描述

三、HDFS

1.HDFS基本概念

  • 葵花宝典:【官方文档:https://hadoop.apache.org/】
    • 上面你分治了后,就得找个类似于注册中心这种中介中间商来 记账帮咱们管理这一帮被分开的小的,比如A为总记账管家,B、C、D…Z都是由文件分割而来的不同块
      • 假设B要干活,到A管家这记录一下,等B干完了后我A这再记录,A不能立即记录,如果你立即记录B由于什么原因没干成活岂不是出错了,这就是HDFS,先分治,再找一台主机来记账
      • HDFS体现了一种分治思想,我有一个文件(一批数据),这个文件要被切割为很多的块,这个切开的块块要被散列到集群中不同的主机中,这种散列其实就是一种分治的思想
        • HDFS的重点在于HD而不是FS文件系统上,他注意的是一次上传多次读取
  • Hadoop-HDFS:分布式文件系统,本质上就是一个文件系统【有用户的概念,当然对应的就有权限的概念】
    • hdfs暴露很多文件元数据等信息,可以更好的支持分布式计算,相比于其他分布式文件系统时,不然分布式文件系统已经很多了hadoop为啥还要自己搞一个
      • 或者说,此时就是HDFS的相比较与其他分布式文件系统的优点了,因为HDFS可以暴露文件的偏移量,HDFS支持client输出文件的offset自定义连接哪些block的DataNode,自定义获取数据【我就没必要非要从头开始读,灵活性高了不少】,这个是支持计算层的分治、并行计算的核心
    • 存储模型:存储层,或者说HDFS位于存储层
    • 光说分治,HDFS咋分,分的过程中有这么多事…
      • 文件线性按字节切割成块,具有offset【第一块的offset不就是0嘛】、id等属性
        • 只要是文件,就可以视为一个字节数组,相当于字节数组可以切割为块
        • 这些块会变成一个个小文件,每个块对应的小文件会被打散放到集群的多台机器中,每台机器中会有一个DataNode,每个DataNode角色相当于一个JVM进程【一个角色相当于一个进程】,DataNode会把小文件存到DataNode这个进程所在的OS的本地磁盘文件系统中
      • 按照字节可能会把内容切坏,但是后期在计算层会解决这个问题
      • 文件与文件的block大小可以不一样【后期运维可以调整块大小】,一个文件除最后一个block,其他block大小一致,block的大小依据硬件的I/O特性调整
        在这里插入图片描述
      • block被分散存放在集群的节点中【你不散列,你跟单机有啥区别】,具有location【得知道块在哪】
      • block具有副本,没有主从概念,副本不能出现在同一个节点中【你把鸡蛋都放在一个篮子里,那你搞个副本或者集群的意义在哪?】
        • 副本是满足可靠性和性能的关键
        • 文件上传可以指定block的大小和副本数,上传后只能修改副本数
        • 一个文件中的一个块Block的副本放置策略
          • 第一个副本:放置在上传文件的DataNode;如果是集群外提交,则随机挑选一台磁盘不太满,CPU不太忙的节点
          • 第二个副本:放置在与第一个副本不同的机架的节点上
          • 第三个副本:与第二个副本相同机架的节点
            • 此时二三副本在同一个交换机下,成本较小
          • 更多副本:随机节点
      • 文件包含:文件数据和元数据
        • 元数据指的是比如:文件属性、每个块的副本存在哪个DataNode上
      • 一次写入多次读取,不支持修改,支持追加数据
        • 支持上传删除,就是不能修改,而且删除针对的是整个文件,不能对文件中的某个块操作

2.HDFS的架构设计

在这里插入图片描述

  • HDFS是一个主从架构,有一个NameNode(主)和多个DataNode组成
    • NameNode为主,
      • NameNode负责 存储和管理文件元数据,并维护了一个层次型的文件目录树
      • 完全基于内存存储文件元数据、目录结构、文件block的映射
        • 因为NameNode要快速对外服务
      • 需要持久化方案保证数据可靠性【内存掉电易失且大小有限】
        • 数据持久化有两种技术,不同的需要数据持久化的中间件,如Redis、HDFS等各自有各自的实现
          • 日志文件:记录实时发生的增删改的操作,以append形式向后添加
            • 完整性比较好,缺点就是比如要恢复数据就要进行加载,慢,还占空间
          • 镜像、快照:有一定时间间隔(小时、天、分钟,秒钟等),内存全量数据基于某一个时间点做的磁盘全量数据备份
            • 优点就是恢复速度快。缺点就是有一定时间间隔,这个时间间隔要出了啥问题就容易丢失数据
        • 元数据持久化:文件属性会持久化,但是文件的每一个块不会持久化,在恢复时NameNode会丢失块的位置信息
          • 任何对文件系统元数据产生修改的操作NameNode都会使用一种称为EditLog的事务日志记录下来,使用本地磁盘保存EditLog和FsImage
          • 使用FsImage存储内存所有的元数据状态,使用本地磁盘保存EditLog和FsImage
      • 提供副本放置策略
      • NameNode一般有两件外交事项:
        • DataNode与NameNode维持心跳,并汇报自己持有的block信息
        • Client和NameNode交互文件元数据
    • DataNode为从,
      • DataNode负责存储文件数据块,并提供block的读写
      • 基于本地磁盘存储block(文件的形式)
      • 并保存block的校验和数据【客户端取走后块会再算一次,如果你俩的算法结果一样证明数据没被破坏或者修改】,保证block的可靠性
        • 用算法来验证数据有没有被破坏或者修改过
      • DataNode的外交事项:
        • 与NameNode保持心跳,汇报block的列表状态
          • 处于安全模式后,NameNode从所有的DataNode接收心跳信号和块状态报告
        • client和DataNode交互文件block数量

3.HDFS自己对于上面两种数据持久化技术的实现:

  • HDFS的NameNode使用了FsImage+EditLog整合的方案:【滚动()将增量的EditLog更新到FsImage中,以保证更新时点的FsImage和更小的EditLog体积
    在这里插入图片描述
    • HDFS使用了最近时点的FsImage+增量的EditsLog。比如现在10点,9点的FsImage+9点到10点的增量的EditsLog,此时如果恢复时就可以通过三步【加载FsImage,加载EditsLog,那么内存就得到了关机前的全量数据】
    • EditsLog:日志。优点是体积小,记录少
      • EditLog具有完整性,数据丢失少,但恢复速度慢,并有体积膨胀风险
    • FsImage:镜像、快照。如果能更快的滚动的更新时间点
      • FsImages具有恢复速度快,体积与内存数据相当,但不能实时保存,数据丢失多
      • HDFS搭建时会格式化,格式化操作会产生一个空的FsImage
        • 当NameNode启动时,他从硬盘中读取EditLog和FsImage,将所有Editlog中的事务作用在内存中的FsImage上,并将这个新版本的FsImage从内存中保存到本地磁盘中,然后删除旧的Editlog,因为这个旧的Editlog的事务都已经作用在FsImage上了。也就是说NameNode启动时会更新一次FsImage和EditLog,然后后期更新的话就需要依靠帮手SNN和…
        • Namenode启动后会进入一个称为安全模式的特殊状态,处于安全模式的NameNode是不会进行数据块的复制的。
          • 每当NameNode检测确认某个数据块的副本数量达到这个最小值,那么该数据块就会被认为是副本安全的。
          • 在一定百分比(这个参数可配置)的数据块被NameNode检测确认是安全的之后(加上一个额外的30秒等待时间),NameNode将退出安全模式状态
        • 接下来NameNode还有确定还有哪些数据块的副本没有达到指定数目,并将这些数据块复制到其他DataNode上
      • FsImage时点是怎么滚动更新的???有两种更新的方式
        • 要么由NameNode八点写一次,九点写一次,但是IO太慢了,这太占资源了,这种方法不能用
        • 要么,假设八点时,NameNode第一次开机时只写一次FsImage,九点时有一个EditsLog,这个EditsLog记录的是八点到九点的日志,此时就只需将八点到九点的日志记录更新到八点的FsImage中,那么FsImage的数据时点就变成了九点。
          • 有个问题:直接九点落个日志,十点落个日志…,不好嘛,非要脱裤子放屁多此一举
          • 所以找一个帮手来做“将八点到九点的日志记录更新到八点的FsImage中”这种事【减少EditLog大小,并减少NameNode启动时间,恢复的较快】,你NameNode专心干自己的事就行,这个帮手就是SNN
    • hdfs的SNN(SecondaryNameNode),也是一个JVM进程
      在这里插入图片描述
      • 在非HA模式下,SNN一般是独立的节点周期的完成对NameNode的EditLog向FsImage合并,减少EditLog大小,并减少NameNode启动时间
      • 根据配置文件设置的时间间隔fs.checkpoint.period,默认3600秒
      • 根据配置文件设置edits log大小,fs.checkpoint.size规定edits文件的最大值默认为64MB

4.HDFS读写流程

  • HDFS写流程
    在这里插入图片描述
    • 某一时间点的客户端在传其中一个块的状态【一个文件有很多块】
    • 客户端将手中的文件切成块,要上传到HDFS中,首先客户端就得跟NameNode交互,说,NameNode,我要上传一个叫xxx的文件【此时Client和NameNode连接创建文件元数据】,此时NameNode判定文件元数据是否有效,有效则此时NameNode会触发副本放置策略,【安排第一个第二个第三个副本分别放在哪里】,NameNode会进行排序,返回排好序的每个块的三个节点对应的一个有序的DataNode列表【第一个块位于DataNode所在的本地中,第二个第三个副本放置在其他机架中】
      • 这里的返回每个块的几个节点,就看你副本数设置的是几,然后按照副本放置策略进行副本的放置
    • Client和DataNode建立Pipeline连接,客户端会跟第一个DataNode建立TCP连接,第一个DataNode再跟第二个DataNode建立连接,第二个DataNode再跟第三个DataNode建立连接...此时就形成了一个Pipeline of datanodes
    • 然后客户端再把文件切割出来的块再切割为更小的package(64KB,使用chunk(512B)+chucksum(4B,校验和)填充),顺着pipeline跟生产流水线一样手递手流水线传下去
      • dataNode收到第一个package后,会在内存存一份,磁盘存一份
      • 流水线也就是并行,都没停着呀
      • 得把这个package填满了,才发
    • Client将package放入发送队列dataqueue中,并向第一个DataNode发送package,第一个DataNode收到package后本地保存并发送给第二个DataNode,第二个DataNode收到package后本地保存并发送给第三个DataNode,这个过程中上游节点不断向下游节点同时发送下一个package
      • 哪个DataNode挂了,跳过这个坏的,手递手下一个【由心跳等机制来维持DataNode的数量等】,坏了,隔壁的左右邻居来帮忙
      • hdfs使用这种传输方式,副本数对于client是透明的
    • 当block传输完成,DataNode各自向NameNode汇报,同时client继续传输下一个block
      • 只要有一个DataNode活着,那么最后块不够,NameNode说,你这个存活的DataNode去帮我…,反正你要给我汇报,我就可以趁汇报这回事给你发命令
      • 所以,client的传输和block的汇报也是并行的
  • HDFS读流程
    在这里插入图片描述
    • 比如客户端要把已经上传的文件下载到本地
    • 第一步同样是客户端和NameNode建立联系【获取文件的元数据,NameNode会按照距离策略排序返回,client尝试下载block并校验数据完整性】,get 文件中的block的locations,客户端会从文件的块的副本中挑一个距离自己最近的,挨个去下载,但是没必要挨个下载,既然你可以下载第一个和最后一个,我就可以指定某个偏移量的一个块我下载回来,
      • 此时就是HDFS的相比较与其他分布式文件系统的优点了,因为HDFS可以暴露文件的偏移量,HDFS支持client输出文件的offset自定义连接哪些block的DataNode,自定义获取数据【我就没必要非要从头开始读,灵活性高了不少】,这个是支持计算层的分治、并行计算的核心
    • 为了降低整体的带宽消耗和读取延时,HDFS会尽量让读取程序读取离他最近的副本,比如在读取程序所在的同一个机架上就有一个副本,那么就读取该副本
    • 如果一个HDFS集群跨越多个数据中心,那么客户端也将首先读取本地数据中心的副本

5.HDFS实操步骤及经验记录

  • hadoop实操葵花宝典依旧是官方网站:https://hadoop.apache.org/docs/r2.6.5/hadoop-project-dist/hadoop-common/SingleCluster.html
  • 第一大步:搭建基础设施
    • 1.设置IP以及主机名:
      • vi /etc/sysconfig/network-scripts/ifcfg-eth0
      • vi /etc/sysconfig/network
    • 2.关闭防火墙&selinux【出于安全考虑:vi /etc/selinux/config,改SELINUX=enforing为disabled】:
      • service iptables stop
      • chkconfig iptables off
    • 3.设置hosts映射
      • 后期IP地址变化了,只需要改这个配置文件即可,不然还得找哪里用了这个IP地址去改IP地址,多麻烦,这样一来就解耦了
      • vi /etc/hosts
    • 4.时间同步:yum install ntp -y
    • 5.安装jdk:用.rpm这个安装包比自己解压那个tar.gz包安装,方便,rpm -i xxx.rpm
    • 6.设置SSH免秘钥,分发自己的公钥出发,就可以对别的机子进行免密登陆了
      • ssh localhost看需要输入密码不,如果需要则设置免密,ssh localhost不仅会验证是否已免密,还有帮咱们生成一个.ssh文件
        在这里插入图片描述
      • ssh-keygen -t dsa -P ‘’ -f /root/.ssh/id_dsa,利用dsa算法生成密钥对
      • 然后把你的公钥放到谁的authorized_keys中,你就可以免密管理谁了【都免密了我还治不了你嘛】,那我也可以对自己进行免密呀【只要机器A的authorized_keys有了B机器的id_dsa.pub里面的内容,相当于此时B包含了A的公钥,B基于A的公钥承认了A的身份,那么A就可以免密登陆B,A中执行ssh-keygen...,B中执行cat ...
        在这里插入图片描述
        • cat代表读取谁的内容;>>代表追加内容到…
        • cat id_dsa.pub >> ~/.ssh/authorized_keys,最后的效果就是id_dsa.pub和authorized_keys中的内容是一样的,就相当于免密成功了
  • 第二大步:具体应用部署配置搭建:*【https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-common/SingleCluster.html】
    • 其实部署配置就是主要两步:角色在哪里启动、角色启动时的需要配置的细节*
      • 角色在哪里启动
        • NameNode:core-site.xml: fs.defaultFS hdfs://node01:9000
        • DataNode:slaves: node01
        • SecondaryNameNode:hdfs-site.xml: dfs.namenode.secondary.http.address node01:50090
      • 角色启动时的需要配置的细节
        • dfs.namenode.name.dir
        • dfs.datanode.data.dir
    • 具体应用部署配置搭建之伪分布式,单一节点应用部署配置搭建
      • 1.规划部署路径:
        • 在~根目录中mkdir /opt/bigdata,然后解压hadoop-2.6.5.tar.gz
          • 最终pwd查询得到hadoop的部署路径为:/opt/bigdata/hadoop-2.6.5
        • 另外,vim /etc/profile,在其中跟配置java环境变量一样配置HADOOP的环境变量
      • 2.配置文件:
        • hadoop-env.sh
          • vi /opt/bigdata/hadoop-2.6.5/etc/hadoop/hadoop-env.sh,在其中配置JAVA_HOME改为绝对路径
        • core-site.xml:定义NameNode在哪里
          在这里插入图片描述
          • 配置这个后,client就知道我要去中的那个路径中找NameNode,而DataNode就知道我要去中的那个路径去找NameNode,反正就是告诉client和DataNode这俩询问者,我NameNode在哪里,你们要到哪里找我
          • 定义NameNode元数据放到哪个磁盘刷回路径下
            在这里插入图片描述
          • 定义DataNode元数据放到哪个磁盘目录下
            在这里插入图片描述
        • hdfs-site.xml
          • 目前咱们玩的是伪分布式,所以副本数量就是1
            在这里插入图片描述
        • slaves:配置DataNode这个角色在哪里启动
    • 具体应用部署配置搭建之完全分布式,多个节点【https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-common/SingleCluster.html】
      • 第一步停止stop-dfs.sh,也就是第一台机子上执行这个命令
        • 因为规划为第一台机子放NameNode,后三台上分别放一个DataNode,然后第二台放一个SecondaryNameNode
        • 先保证集群中各节点能够互相ping通,并且保证各个节点的jdk等环境齐全:
        • 比如咱们有node01、node02、node03、node04
          在这里插入图片描述
          • node01要想免密登陆别人,就得把自己的公钥发给别人让别人认可自己:scp /root/.ssh/id_dsa.pub node0x:/root/.ssh/node01.pub
      • 然后配置部署,修改配置文件
        在这里插入图片描述
        • 只需要在第一台上配置好,然后进行分发即可
          在这里插入图片描述
        • 格式化启动:
          • 各个节点中:hdfs namenode -format
          • start-dfs.sh
  • 第三大步:初始化运行:主要是生成目录中的文件夹以及文件,然后利用start-dfs.sh脚本启动,这个脚本会帮咱们加载各个配置文件,通过ssh免密启动相应的角色
    • hdfs namenode -format,创建目录并初始化一个空的fsimage
    • 在/var/bigdata/hadoop/local/dfs下执行start-dfs.sh,启动NameNode、DataNode、SecondaryNameNode【帮忙滚动更新日志的家伙】、Jps
      • 第一次启动时,datanode和secondary角色会在/var/bigdata/hadoop/local/dfs下初始化创建自己的数据目录
    • 在window的hosts文件中配置虚拟机IP映射:192.168.1.164 node01,然后浏览器node01:50070就可以看到hadoop的web页面
    • 此时就可以知道:
      • cd /car/bigdata/hadoop/local/dfs/name/current,其中editLog的id是在Fsimage的后边
        在这里插入图片描述
      • cd /var/bigdata/hadoop/local/dfs/secondary/current,可以看到SecondaryNameNode是只需要从NameNode拷贝最后时点的FsImage和增量的EditLog,然后合并为一个新的
        在这里插入图片描述
  • 第四大步:hdfs命令行命令使用
    • hdfs dfs -mkdir /bigdata:给hdfs中创建一个/bigdata文件夹,而不是给本地,本地不会受影响
    • hdfs dfs -mkdir -p /user/root:
    • hdfs dfs -put xxx.tar.gz /user/root:把xxx.tar.gz上传到hdfs中的/user/root目录底下
    • hdfs dfs -狗…:这个hdfs dfs后面可以-狗跟很多参数,可以自己设定
      • 比如hdfs dfs -D dfs.blocksize=1048576 按照1M=(1048576个Byte)切割文件,
      • 比如…-put xxx.txt /user/…将xxx.txt上传到/user/…目录中

6.HDFS的主从集群固有问题两种解决方案【“单点故障”以及“压力过大内存受限”两个问题是独立的,之间没啥联系】

  • 单点故障,集群整体不可用
    • 解决方案:高可用方案:HA,搞多个NameNode,主备切换【一主多备】
      在这里插入图片描述
      • 整体流程就是当Active和Standby这两台NameNode服务器启动起来之后,两个服务器会向zookeeper集群中某个节点争取一把锁,谁抢到这把锁谁就是active,没抢到的就是standby;
        在这里插入图片描述
        在这里插入图片描述
        在这里插入图片描述
        在这里插入图片描述
        • 随着时间的推移,当active挂掉后,监控active的zookeeperFailoverController会发现,然后会立即删除之前active抢到的那把锁,锁删除之后会产生删除事件,事件会回调当时你zkfc注册到zookeeper上的方法,先去抢到那把锁,然后去检查对方是否真的变成一个坏了的active,如果真的active坏了,那么就把对方active降级为standby,然后把自己监控的那个standby升级为active
        • 可以利用kill 9模拟杀死NameNode以及ZookeeperFailoverController,看一下锁的抢占情况
          在这里插入图片描述
          在这里插入图片描述
          在这里插入图片描述
        • zkfc挂了后,你之前抢到的锁也会被删除,然后这把锁就会被别人强到,然后别人触发事件发生回调调用方法,实现NameNode的升级降级
      • 多台NameNode主备模式,Active和Stangby状态,Active对外提供服务,Standby周期性同步内存,不对外提供服务,滚动落FsImage;增加journalnode角色,数量大于3台,负责同步NameNode的editLog,用来保证Active和Standby最终一致性【因为强一致性会牺牲可用性,而我搞集群出来的初衷就是提高可用性,你这强一致性不是捣乱嘛,所以得保证最终一致性,就是我允许过程中出现短暂的数据不一致也就是不可靠的情况】;增加zkfc角色与NameNode同主机,通过Zookeeper集群协调NameNode的主从选举和切换,这里用的就是zookeeper的事件回调机制,同时DataNode向NameNode们汇报block清单
        • HA模式下,集群中只能有一个active的nameNode,不然你要是多个active时有的DataNode连这个active的NameNode,有的DataNode连接那个active的NameNode,不就产生脑裂的现象了嘛,不就数据不一致了嘛
          • HA模式下,client只能连接Active
          • HA模式的主机各角色部署安排
            在这里插入图片描述
        • HA模式下有了Standby来滚动同步FsImage,就不需要SecondaryNameNode,只有非HA模式才需要SNN
        • Active挂掉后Standby立即补上,所以得提前通过journalNode的过半机制选主,从而利用journalnode集群来保证Active和Standby的同步,才能等Active挂了Standby有能力填坑
          • 并且journalnode自己是通过过半机制来选主,来保证Active和Standby的同步的,因为只有过半才能保证最终一致性,然后才能通过journalNode集群的过半选主机制保证NameNode(Active)和NameNode(Standby)的同步,不能要不就偏向强一致性要不就偏向可用性
      • 本来需要手动去NameNode集群中设置Active和Standby,但是这也太麻烦了,所以上面那部分用ZK来实现自动化(用ZK来进行自动的分布式选主)
      • ZKFailoverController,跟NameNode一样,是一个实实在在的JVM进程,跟NameNode同主机,用ZKFC来监控NameNode是不是活的(一个ZKFC监控一个NameNode,这俩放在同一主机上可以避免网线带来的监控不可靠);另外ZKFC的第二个作用是利用多节点的ZK集群的快速恢复抢锁(在ZK节点下创建子节点)。第三个作用是完成整体流程中的升级降级
        • zkfc的本质就是抢锁,抢到锁了你才能干活
    • 非HA模式下,是通过core-site.xml中配置的hdfs://node01:9000指明了NameNode所在位置,然后client和DataNode才能找得到,但是现在HA集群模式下,有多个NameNode节点,该咋弄?在core-site.xml中和在hdfs-site.xml中这样搞,https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/HDFSHighAvailabilityWithNFS.html
      • 在core-site.xml中配置:
        在这里插入图片描述
        • 配置zookeeper
          在这里插入图片描述
      • 在hdfs-site.xml中配置:逻辑的一对多以及逻辑到物理节点的映射
        在这里插入图片描述
        • journalNode的配置,配置journal在哪里启动,数据存在哪个磁盘
          在这里插入图片描述
        • HA角色切换的代理类和实现方法,我们用的SSH的免密
          在这里插入图片描述
        • 自动故障转移,开启自动化,启动zookeeperFailoverController
          在这里插入图片描述
    • HA流程:还是上面实操的四大步
      • 第一大步:基础设施:
        • SSH免密:有两个作用,一是启动start-dfs.sh脚本的机器需要将公钥分发给别的节点;二是在HA模式下,每一个NameNode身边会启动ZookeeperFailoverController,ZKFC会用免密的方式控制自己和其他NameNode节点的NameNode状态
      • 第二大步:应用搭建:
        • HA依赖ZK,所以要搭建ZK集群
        • 修改hadoop的配置文件,并集群同步
        • 配置hadoop的core和hdfs
        • 分发配置,给每一台都分发
      • 第三大步:初始化启动:
        • 1.先启动JournalNode,hadoop-daemon.sh start journalNode
        • 2.选择一个NameNode做格式化:hdfs namenode -format,格式化或者初始化只有第一次搭建时做,以后不用重复做了
        • 3.启动这个格式化或者初始化后的NameNode,以备另外一台NameNode同步 hadoop-daemon.sh start namenode
        • 4.在另外一台机器中: hdfs namenode -bootstrapStandby
        • 5.格式化zk: hdfs zkfc -formatZK ,只有第一次搭建做,以后不用重复做【格式化zookeeper其实就是创建了一个节点目录,原来zookeeper中只有zookeeper一个节点,初始化后就有hadoop-ha节点了】
          在这里插入图片描述
          在这里插入图片描述
        • 6.start-dfs.sh
          在这里插入图片描述
      • 第四大步:使用:
        在这里插入图片描述
        • 停止之前的集群
        • 免密:node01【cd ~/.ssh;ssh-keygen -t dsa -P ‘’ -f ./id_dsa;cat id_dsa.pub >> authorized_keys;scp ./id_dsa.pub node01: ‘pwd1’ /node02.pub】、node02【cd ~/.ssh;cat id_dsa.pub >> authorized_keys】
        • zookeeper集群搭建,zookeeper使用java开发的,所以也需要JDK环境,将zookeeper部署在2,3,4主机上【搭建zookeeper步骤:先解压安装、tar xf zookeeper…tar.gz;mv zookeeper… /opt/bigdata;cd /opt/bigdata/zookeeper…;cd conf;cp zoo_sample.cfg zoo.cfg;vim zoo.cfg,在这个配置文件中写datadir=/var/bigdata/hadoop/zk、server.1=node02:2888:3888、server.2=node02:2888:3888、server.3=node02:2888:3888,2888和3888分别代表zookeeper无主以及选主等不同状态;mkdir /var/bigdata/hadoop/zk;echo 1 > /var/bigdata/hadoop/zk/muid;】
          在这里插入图片描述
          在这里插入图片描述
        • node02到node04:zkServer.sh start
  • 压力过大,内存受限(用的比较少)
    • 解决方案:联帮机制:Federation(元数据分片),多个NameNode管理不同的元数据,每个NameNode持有总数据的1/N,N为分片数
      在这里插入图片描述
      • 联邦解决内存压力过大问题,隔离性比较好,但是我涉及到统一访问的问题时就比较麻烦,此时为了解决统一访问问题,在最上层搞出了一个虚拟文件系统,相当于找个大管家或者说代理层,我要是进行统一全局性的访问时我不需要自己来回这跑那跑,我直接找虚拟文件系统就行

7.HDFS的本质上就是一个分布式文件系统【有用户的概念,当然对应的就有权限的概念】

  • hdfs没有相关命令和接口去创建用户,默认情况下使用的是操作系统提供的用户来标识客户端是谁,比较信任客户端。可以扩展kerberos、LDAP等集成第三方用户认证系统
    • hdfs中有超级用户这个概念,就是NameNode进程的启动用户,对应linux中的root。也就是说面向操作系统时root叫做管理员其他都叫做普通用户,面向操作系统的软件,谁启动管理这个进程,那么这个用户叫做这个软件的管理员【你root在hdfs中不一定是最大的,人家只承认谁创建启动了NameNode这个进程,这个用户就是超级用户,而不一定是你root】
      • 实际企业工作中不会实际用root干什么事,会添加新用户,比如god,然后将资源与新用户绑定,切换到新用户god去启动
        在这里插入图片描述
        在这里插入图片描述
        在这里插入图片描述
        在这里插入图片描述
    • hdfs中的权限是自己控制的,来自于hdfs的超级用户
      在这里插入图片描述
      • 就可以得到一个结论:默认的hdfs依赖操作系统上的用户和组,自己没有

8.HDFS的API

  • 在window用集成开发环境IDE或者Eclipse进行开发,安装环境,开发HDFS的client代码
    • 权限:参考环境变量;代码中给出;
    • window中给出HADOOP_USER_NAME god
      在这里插入图片描述
    • jdk版本,集成和开发jdk版本要一致
    • maven:构建工具,里面包含了依赖管理(pom),相当于一个jar包的仓库,还可以进行打包、测试、清除以及构建项目目录等操作
      • hadoop的pom由两个部分组成:hadoop-common、hadoop-hdfs
      • IDEA中的项目目录结构:
        • 把hdfs-site.xml以及core-site.xml拷贝到src/main/java/…/resource下
        • 可以编写测试类,用Configuration加载resource中的配置文件,然后就可以用配置文件中的配置信息了,测试类中的主要内容如下:
          在这里插入图片描述
          在这里插入图片描述
          在这里插入图片描述
          在这里插入图片描述
          • 文件上传,其实相当于做一个流的对接,从本机开启一个流进入内存,然后给数据从内存中开启一个输出流,两个一对接,就成了
            在这里插入图片描述
          • 关于block的方法
            在这里插入图片描述
            在这里插入图片描述

巨人的肩膀

Hadoop官方文档:https://hadoop.apache.org/
凤凰架构
深入理解计算机系统
https://cloud.tencent.com/developer/article/2088864

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值