zoukankan      html  css  js  c++  java
  • 复习整理(一)——HDFS

    1.问题

    分布式文件系统那么多,为什么hadoop项目中还要开发一个分布式文件系统呢?

    2.存储模型

    • 文件线性字节切割成块(Block),具有offset,id
    • 文件与文件的block大小可以不一样
    • 一个文件除了最后一个block,其他block大小一致
    • block大小依据硬件I/O进行调整
    • block被分散存放在集群节点中,具有location
    • block具有副本(replication),没有主从概念,副本不能出现在同一个节点
    • 副本是满足可靠性和性能的关键
    • 文件上传可以指定block大小和副本数,上传后只能修改副本数
    • 一次写入多次读取,不支持修改
    • 支持追加数据

    3.架构设计

    • HDFS是一个主从(Master/Slaves)架构
    • 由一个NameNode和一些DataNode组成
    • 面向文件包含:文件数据(data)和文件元数据(metadata)
    • NameNode负责存储和管理文件元数据,并且维护了一个层次性文件目录树
    • DataNode负责存储文件数据(block块),并提供block读写
    • DataNode与NameNode维持心跳,并汇报自己持有的block信息
    • Client和NameNode交互文件元数据和DataNode交互文件block数据

    HDFS Architecture

    Replication

    4.角色功能

    NameNode

    • 完全基于内存存储元数据、目录结构、文件block映射
    • 需要持久化方案保证数据可靠性
    • 提供副本放置策略

    DataNode

    • 基于本地磁盘存储block(文件形式)
    • 并保存block校验和数据保证block的可靠性
    • 与NameNode保持心跳,汇报block列表状态

    5.安全模式

    • HDFS搭建时会格式化,格式化会产生一个空的FsImage
    • 当NameNode启动,会加载Editlog和FsImage
    • 将所有Editlog中事务作用在内存中的FsImage上
    • 这个新版本的FsImage从内存保存在磁盘上
    • 删除旧的Editlog,旧的Editlog事务已经作用在FsImage上了
    • NameNode启动时候会进入一个安全模式的特殊状态
    • 处于安全模式的NameNode是不会进行数据块复制的
    • NameNode从所有的DataNode接收心跳信号和块状态报告
    • 每当NameNode检测确认某个数据块副本数目达到这个最小值,那么该数据库就会被认为是副本安全(safely replicated)的
    • 在一定百分比数据块被NameNode确认是安全后,加上30s的等待时间,NameNode会退出安全模式
    • 接下来它会确定还有哪些数据库副本没有达到指定数目,并将这些数据库复制到其他DataNode上

    6.HDFS中的SNN

    Log System

    • EditsLog FsImage

    • 可以由某一点开始溢写全量,其余增量

    • 思考:全量和增量的好处

    • 在非Ha模式下,存在SNN,SNN一般是独立节点,周期完成对NN的EditLog想FsImage合并,减少EditLog大小,较少NN启动时间

    • 根据配置文件设置时间间隔fs.checkpoint.period 默认3600秒

    • 根据配置文件设置edits log大小 fs.checkpoint.size 规定edits文件的最大值默认64MB

    日志流程

    7.Block副本放置策略

    • 第一个副本:放置在上传文件的DataNode

    如果是集群外提交,则随机挑选一台磁盘不太满,CPU不太忙的节点

    • 第二个副本:放置在与第一个副本不同的机架节点上
    • 第三个副本:与第二个副本相同机架的节点
    • 更多副本:随机节点

    副本放置策略

    8.读写流程

    write flow

    • Client和NN连接创建文件元数据
    • NN判定元数据是否有效
    • NN触发副本放置策略,返回一个有序的DN列表
    • Client和DN简历Pipeline连接
    • Client将块切分成packet(64KB),并使用chunk(512B) + chunksum(4B)填充
    • Client将packet放入dataqueue中,并向第一个DN发送
    • 第一个DN收到packet后本地保存并发送给第二个DN
    • 第二个DN收到packet后本地保存并发送给第三个DN
    • 这个过程,上游节点同时发送下一个packet

    生活中类比流水线,进行,结论:流式也是变种并行计算

    • HDFS使用这种传输方式、副本数对于client是透明的
    • 当block传输完成后,DN各自向NN汇报,同时client继续传输下一个block
    • 所以,client传输和block汇报也是并行的

    读流程

    • 为了整体带宽和读演示,HDFS会尽量读取程序离最近副本
    • 如果读取程序的同一个机架上有一个副本,直接读取该副本
    • 如果一个HDFS集群跨越多个数据中心,那么客户端也将首先本地数据中心的副本

    download:

    client与NN交互,获取fileBlockLocation -> NN会按照距离策略排序返回 -> Client尝试下载block并且返回校验数据的完整性

    • HDFS支持client给出文件的offset自定义连接block的DN,自定义获取数据
    • 这个是支持计算层分治、并行计算的核心

    9.伪分布式模式的搭建

    伪分布式节点分布

    1.安装VMWare WorkStation,直接下一步,输入激活码即可安装

    2.安装Linux(需要100GB)

    引导分区Boot200MB

    交换分区Swap2048MB

    其余分配到/

    3.配置网络服务

    vim /etc/sysconfig/network-scripts/ifcfg-eth0
    
    DEVICE=eth0
    TYPE=Ethernet
    ONBOOT=yes
    NM_CONTROLLED=yes
    BOOTPROTO=static
    IPADDR=192.168.118.11
    NETMASK=255.255.255.0
    GATEWAY=192.168.118.2
    DNS1=114.114.114.114
    DNS2=233.5.5.5
    

    注意点:

    1.关于IPADDR的前三个网关,要与虚拟网络编辑器的VMnet8的子网IP的前三个网关一样

    2.关于GATEWAY要与NAT下的GATEWAY一样,详情如下

    虚拟网络编辑器:在VMWare编辑下打开

    img

    点击NAT设置,查看GATEWAY

    img

    4.修改主机名称

    vi /etc/sysconfig/network
    NETWORKING=yes
    HOSTNAME=node01
    

    5.设置Host(关于Host,是指IP和主机名的映射关系)

    vi /etc/hosts
    192.168.150.11 node01
    192.168.150.12 node02
    

    6.关闭防火墙,开机不启动防火墙

    service iptables stop
    chkconfig iptables off
    

    7.关闭selinux(selinux是Linux下一种安全模式,打开可能会连不上XShell)

    vi /etc/selinux/config
    SELINUX=disabled
    

    8.时间同步

    使用yum安装ntp,并把原有的server注释,替换成

    server ntp1.aliyun.com
    service ntpd start
    chkconfig ntpd on
    

    img

    9.安装jdk,使用xftp上传rpm文件

    jdk-8u181-linux-x64.rpm
    

    修改JAVA_HOME

    vi /etc/profile 
    export JAVA_HOME=/usr/java/default
    export PATH=$PATH:$JAVA_HOME/bin
    source /etc/profile
    

    10.安装ssh免密

    (1)检验ssh是否可以登录

    ssh localhost
    

    需要输入密码,则不免密

    (2)设置免密

    ssh-keygen -t dsa表示使用dsa算法加密
    -p ''表示密码为空
    -f ~/ .ssh/id_dsa 将公钥放在/home/.ssh/id_dsa下

    ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa
    cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys
    

    不能自己私自创建目录,关于ssh的目录权限,必须为755或者700,不能是777,否则不能使用免密

    11.安装Hadoop

    mkdir /opt/bigdata
    tar xf hadoop-2.6.5.tar.gz
    mv hadoop-2.6.5 /opt/bigdata/
    pwd
    /opt/bigdata/hadoop-2.6.5
    

    设置Hadoop的环境变量

    vi /etc/profile    
    export JAVA_HOME=/usr/java/default
    export HADOOP_HOME=/opt/bigdata/hadoop-2.6.5
    export PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
    source /etc/profile
    

    12.修改hadoop-env.sh,此文件为hadoop启动脚本,将JAVA_HOME改为具体的环境变量

    cd $HADOOP_HOME/etc/hadoop
    vi hadoop-env.sh
    export JAVA_HOME=/usr/java/default
    

    13.给出NN角色在哪里启动vi core-site.xml

    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://node01:9000</value>
    </property>
    

    14.配置一个hdfs副本

    <!-- 副本数量为1 -->
    <property>
        <name>dfs.replication</name>
        <value>1</value>
    </property><!-- NameNode的路径-->
    <property>
        <name>dfs.namenode.name.dir</name>
        <value>/var/bigdata/hadoop/local/dfs/name</value>
    </property><!-- DataNode的路径-->
    <property>
    <name>dfs.datanode.data.dir</name>
        <value>/var/bigdata/hadoop/local/dfs/data</value>
        </property><!-- SecondaryNameNode在哪个端口启动-->
    <property>
    <name>dfs.namenode.secondary.http-address</name>
        <value>node01:50090</value>
        </property><!-- SecondaryNameNode的路径-->
    <property>
        <name>dfs.namenode.checkpoint.dir</name>
        <value>/var/bigdata/hadoop/local/dfs/secondary</value>
    </property>
    

    15.配置Slave

    vi slaves
    node01
    

    16.初始化&启动

    hdfs namenode -format 
    

    创建目录,并且初始化一个空的fsimage

    VERSION CID

    start-dfs.sh
    

    17.修改windows: C:WindowsSystem32driversetchosts(注意这边IP要与端口一样)

    192.168.150.11 node01
    192.168.150.12 node02
    192.168.150.13 node03
    192.168.150.14 node04
    

    18.简单创建目录

    hdfs dfs -mkdir /bigdata
    hdfs dfs -mkdir -p /user/root
    

    19.HDFS的常见命令

    hadoop fs == hdfs dfs
    
    命令的执行要在bin目录下
    例:./hadoop fs -ls /
    hadoop fs -ls / 查看
    hadoop fs -lsr
    hadoop fs -mkdir /user/haodop 创建文件夹
    hadoop fs -put a.txt /user/hadoop 上传到hdfs
    hadoop fs -get /user/hadoop/a.txt 从hdfs下载
    hadoop fs -cp src dst 复制
    hadoop fs -mv src dst 移动
    hadoop fs -cat /user/hadoop/a.txt 查看文件内容
    hadoop fs -rm /user/hadoop/a.txt 删除文件
    hadoop fs -rmr /user/hadoop 删除文件夹
    hadoop fs -text /user/hadoop/a.txt 查看文件内容
    hadoop fs -copyFromLocal localsrc dst  与hadoop fs -put功能类似
    hadoop fs -moveFromLocal localsrc dst 将本地文件上传到hdfs,同时删除本地文件
        2、帮助命令查看
    
    hadoop帮助命令查看,不需要输入help,只需要在bin目录下输入即可。
    例:./hadoop 
        ./hadoop fs
    

    10.完全分布式

    img

    1.建立4台Linux主机

    img

    2.修改自己的主机名和网关

    vim /etc/sysconfig/network-scripts/ifcfg-eth0
    

    img

    IPADDR分配4个不一样的IP

    img

    分配4个主机名

    vim /etc/sysconfig/network
    

    img

    3.重启网卡

    service network restart
    

    4.重启网卡要记住删除文件

    rm -f /etc/udev/rules.d/70-persistent-net.rules
    

    5.文件命令

    scp xxx node:0x/xx scp是一种远程拷贝
    

    6.pwd可以在另一台主机同样位置进行定位

    接下来就是从单节点变为多节点的配置,仅需要把各个node的节点修改为各个节点

    11.HDFS单点故障解决方案

    • 高可用方案:HA(High Available)
    • 多个NN,主备切换:面临问题,压力过大,内存受限
    • 联邦机制:Federation(元数据分片)
    • 多个NN,管理不同元数据
    • HADOOP 2.x 只支持HA一主一备
    • HADOOP 3.x 支持最多5个主,官方推荐3个

    12.HDFS-Federation解决方案

    • NameNode压力过大,内存受限问题
    • 元数据分治,复用DN存储
    • 元数据访问隔离性
    • DN隔离block

    联邦机制

    13.HA模式

    HA模式

    img

    HA节点分布

    JoinNode 分布在node01,node02,node03

    1.停止之前的集群

    2.免密:node01,node02

    node02: 
    cd ~/.ssh
    ssh-keygen -t dsa -P '' -f ./id_dsa
    cat id_dsa.pub >> authorized_keys
    scp ./id_dsa.pub node01:`pwd`/node02.pub
    node01:
    cd ~/.ssh
    cat node02.pub >> authorized_keys
    

    3.zookeeper 集群搭建 java语言开发(需要jdk)

    node02:
                tar xf zook....tar.gz
                mv zoo...    /opt/bigdata
                cd /opt/bigdata/zoo....
                cd conf
                cp zoo_sample.cfg  zoo.cfg
                vi zoo.cfg
                    dataDir=/var/bigdata/hadoop/zk
                    server.1=node02:2888:3888
                    server.2=node03:2888:3888
                    server.3=node04:2888:3888
                mkdir /var/bigdata/hadoop/zk
                echo 1 >  /var/bigdata/hadoop/zk/myid 
                vi /etc/profile
                    export ZOOKEEPER_HOME=/opt/bigdata/zookeeper-3.4.6
                    export PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$ZOOKEEPER_HOME/bin
                . /etc/profile
                cd /opt/bigdata
                scp -r ./zookeeper-3.4.6  node03:`pwd`
                scp -r ./zookeeper-3.4.6  node04:`pwd`
            node03:
                mkdir /var/bigdata/hadoop/zk
                echo 2 >  /var/bigdata/hadoop/zk/myid
                *环境变量
                . /etc/profile
            node04:
                mkdir /var/bigdata/hadoop/zk
                echo 3 >  /var/bigdata/hadoop/zk/myid
                *环境变量
                . /etc/profile
    
            node02~node04:
                zkServer.sh start
    

    4.配置hadoop的core和hdfs

    core-site.xml
            <property>
              <name>fs.defaultFS</name>
              <value>hdfs://mycluster</value>
            </property>
    
             <property>
               <name>ha.zookeeper.quorum</name>
               <value>node02:2181,node03:2181,node04:2181</value>
             </property>
    
     hdfs-site.xml
            #下面是重命名
            <property>
                <name>dfs.replication</name>
                <value>1</value>
            </property>
            <property>
                <name>dfs.namenode.name.dir</name>
                <value>/var/bigdata/hadoop/ha/dfs/name</value>
            </property>
            <property>
                <name>dfs.datanode.data.dir</name>
                <value>/var/bigdata/hadoop/ha/dfs/data</value>
            </property>
            #以下是  一对多,逻辑到物理节点的映射
            <property>
                <name>dfs.nameservices</name>
                <value>mycluster</value>
            </property>
            <property>
                <name>dfs.ha.namenodes.mycluster</name>
                <value>nn1,nn2</value>
            </property>
            <property>
                <name>dfs.namenode.rpc-address.mycluster.nn1</name>
                <value>node01:8020</value>
            </property>
            <property>
                <name>dfs.namenode.rpc-address.mycluster.nn2</name>
                <value>node02:8020</value>
            </property>
            <property>
                <name>dfs.namenode.http-address.mycluster.nn1</name>
                <value>node01:50070</value>
            </property>
            <property>
                <name>dfs.namenode.http-address.mycluster.nn2</name>
                <value>node02:50070</value>
            </property>
    
            #以下是JN在哪里启动,数据存那个磁盘
            <property>
                <name>dfs.namenode.shared.edits.dir</name>
                <value>qjournal://node01:8485;node02:8485;node03:8485/mycluster</value>
            </property>
            <property>
              <name>dfs.journalnode.edits.dir</name>
              <value>/var/bigdata/hadoop/ha/dfs/jn</value>
            </property>
            
            #HA角色切换的代理类和实现方法,我们用的ssh免密
            <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>/root/.ssh/id_dsa</value>
            </property>
            
            #开启自动化: 启动zkfc
             <property>
               <name>dfs.ha.automatic-failover.enabled</name>
               <value>true</value>
             </property>
    

    5.分发两个配置文件

    scp命令

    6.开启1,2,3台的journalnode

    hadoop-daemon.sh start journalnode
    

    7.选择一个NN 做格式化

    hdfs namenode -format
    

    8.启动该NN的namenode

    hadoop-daemon.sh start namenode 
    

    9.在另一台NN进行同步

    hdfs namenode -bootstrapStandby
    

    10.在node01下格式化zk

    hdfs zkfc  -formatZK
    

    11.启动

    start-dfs.sh    
    

    12.验证

    kill -9  xxx
            a)杀死active NN
            b)杀死active NN身边的zkfc
            c)shutdown activeNN 主机的网卡 : ifconfig eth0 down
                2节点一直阻塞降级
                如果恢复1上的网卡   ifconfig eth0 up  
                最终 2 变成active
    

    14.HDFS权限、企业级搭建、IDEA+Maven开发HDFS

    hdfs权限介绍

    HDFS是一个文件系统,所以权限也有

    node01~node04:
    	1)添加用户:root
    		useradd god
    		passwd god
    		root
    	2)资源与用户绑定(a.安装部署程序 b.数据存放的目录)
    		chown -R god hadoop-2.6.5
    		chown -R god /var/bigdata/hadoop/
    	3)给god做免密
    		ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa
    		cd ~/.ssh
    		cat id_dsa.pub  >> authorized_keys
    	4)切换到god去启动
    		start-dfs.sh
    

    用户权限实操

    node01:
    	su god
    	hdfs dfs -mkdir /temp
    	hdfs dfs -chown god:ooxx /temp
    	hdfs dfs -chmod 770 /temp
    node04:
    	root:
    		useradd good
    		groupadd ooxx
    		usermod -a -G ooxx good
    		id good
    	su good
    		hdfs dfs -mkdir /temp/abc  <失败
    		hdfs groups
    			good:     <因为hdfs已经启动了,不知道你操作系统
    						偷偷创建了用户和组
    node01:
    	root:
    		useradd good
    		groupadd ooxx
    		usermod -a -G ooxx good
    	su god:
    		hdfs dfs -refreshUserToGroupsMappings
    	node04:
    		good:
    			hdfs groups
    				good: good ooxx
    

    结论:默认hdfs依赖操作系统上的用户和组

    hdfs IDEA开发
    hdfs的pom:
    	hadoop:(common,hdfs,yarn,mapreduce)
    		我们导入common 2.6.5  hdfs 2.6.5
    		
    public Configuration conf = new Configuration(true);
    //这边为true会自动加载core-site.xml 默认在resource文件夹里面
    fs = FileSystem.get(conf)
    //去取环境变量 HADOOP_USER_NAME 的值 
    
    //创建文件夹
    Path dir = new Path("/xxx00");
    if(fs.exists(dir)){
    	fs.delete(dir,true);
    }
    fs.mkdirs(dir);
    
    //上传文件
    BufferedInputStream bis = new ..
    Path  out = new Path("/xxx.txt");
    FSDataOutputStream output = fs.create(out)
    IOUtils.copyBytes(input,output,conf,true)
    
    //查看块信息
    Path file = new Path("xxx");
    FileStatus fss = fs.getFileStatus(file);
    BlockLocation[] blks = fs.getFileBlockLocations(
    								fss,0,fss.getLen();
    for(BlockLocation b:blks){
    	System.out.println(b)
    }
    这边记录了偏移量信息,所以这边是大数据中计算向数据移动的体现
    
  • 相关阅读:
    reids学习redis的五种基本数据类型
    CentOS下配置Java开发环境安装redis
    CentOS下配置Java开发环境安装Tomcat
    如何去除掉inlineblock元素之间的默认间距
    js按值传递还是按引用传递?
    overflow: hidden用法,不仅仅是隐藏溢出
    关于WinForm中的DataGridView控件显示数据字典的解决方案。
    C#中对Winform中的DataGridView的控制技巧。(单独控制某单元格的按钮不显示、某单元格的ReadOnly)
    改进版网页表格的合并单元格(支持不连续的列合并)
    [共享]MT随机算法(符合正态分布的随机算法)
  • 原文地址:https://www.cnblogs.com/littlepage/p/11986859.html
Copyright © 2011-2022 走看看