从零开始大数据--Hadoop、HDFS、MapReduce、HBase、Hive


概述

IT领域每隔十五年就会迎来一次重大变革:

  • 1980:个人计算机
  • 1995:互联网
  • 2010:物联网、云计算和大数据

信息科技为大数据时代提供技术支撑:

  • 存储设备容量不断增加
  • CPU处理能力大幅提升
  • 网络带宽不断增加

image-20191224153853092

大数据是由结构化和非结构化数据组成的

  • 10%的结构化数据,存储在数据库中
  • 90%的非结构化数据,它们与人类信息密切相关

大数据技术的不同层面及其功能:
在这里插入图片描述

大数据计算模式及其代表产品:
在这里插入图片描述

云计算与物联网:

  • 云计算:虚拟化、分布式存储、分布式计算、多租户

image-20191224155023923

  • 物联网:利用局部网络或互联网等通信技术把传感器、控制器、机器、人员和物等通过新的方式联在一起,形成人与物、物与物相联,实现信息化和远程管理控制。【识别和感知技术(二维码、RFID、传感器等)、网络与通信技术、数据挖掘与融合技术】

大数据与云计算、物联网的关系:
在这里插入图片描述


Hadoop

Hadoop是基于Java语言开发的,具有很好的跨平台特性,并且可以部署在廉价的计算机集群中。

它的核心是为海量数据提供存储的分布式文件系统HDFS(Hadoop Distributed File System)和对数据进行计算的MapReduce

MapReduce模型包括两个函数Map和Reduce,Map负责把任务分解为多个任务,Reduce负责把分解后的多个任务处理结果汇总起来。把对大数据集的操作分发给主节点管理下的从节点共同完成,然后通过整合各从节点的中间结果,从而得到最终结果。

BigTable

为处理 PB 级别数据的非关系数据库,是一个稀疏的、分布式的、持久化存储的多维度排序 Map。

采用键值对(key-value)方式存储,键(key)有三维:行键、列键、时间戳。

(row:string, column:string, time:int64)→string

Hadoop

而Hadoop是一个能够对大量数据进行分布式处理的软件框架,具有高可靠性、高效性、高可扩展性、高容错性、低成本、支持多种编程语言的特性。

Hadoop版本分为两代:Hadoop1.0 (MapReduce、HDFS)、Hadoop2.0(MapReduce、HDFS、YARN)。

项目结构:

Hadoop安装配置

  • 创建Hadoop用户

sudo useradd -m hadoop -s /bin/bash //创建 hadoop 用户,并以 /bin/bash 为shell

sudo passwd hadoop //设置 hadoop 用户的密码

sudo useradd hadoop sudo //给 hadopp 用户添加管理员权限

  • SSH登录权限设置

Secure Shell 是建立在应用层和传输层基础上的安全协议。

Hadoop 名称节点需要通过 SSH 启动集群中所有 Hadoop 的守护线程,而它没有提供SSH输入密码登录的形式,所以每台机器的 Hadoop 用户需要配置免密登录。

  • 安装Java环境 JDK
  • 三种运行模式:单机模式、伪分布式模式、分布式模式

解压 hadoop-2.x.y.tar.gz,在 sbin 下执行 start-all.sh 可启动(启动之前需要初始化文件系统hadoop namenode -format)。

默认为单机模式,可以修改 /usr/local/hadoop/etc/hadoop/ 下的 core-site.xml、hdfs-site.xml、mapred-site.xml 等配置文件,使用其他模式。

  • 访问web界面,http://ip:50070

hadoop fs、hadoop dfs、hdfs dfs 的区别:

hadoop fs 适用于任何不同的文件系统,比如本地文件系统和 HDFS 文件系统,hadoop dfs 只能适用于 HDFS 文件系统,而 hdfs dfs 与 hadoop dfs 相同。

一个基本的Hadoop集群中的节点主要有:

  • NameNode:负责协调集群中的数据存储
  • DataNode:存储被拆分的数据块
  • JobTracker:协调数据计算任务
  • TaskTracker:负责执行由JobTracker指派的任务
  • SecondaryNameNode:帮助NameNode收集文件系统运行的状态信息

HDFS

分布式文件系统把文件分布存储到多个计算机节点上,成千上万的计算机节点构成计算机集群。

分布式文件系统在物理结构上是由计算机集群中的多个节点构成的,这些节点分为两类,一类叫“主节点”(Master Node)或者也被称为“名称结点”(NameNode),另一类叫“从节点”(Slave Node)或者也被称为“数据节点”(DataNode)。

优点:

  • 兼容廉价的硬件设备
  • 流数据读写
  • 大数据集
  • 简单的文件模型
  • 强大的跨平台兼容性

局限性:

  • 不适合低延迟数据访问
  • 无法高效存储大量小文件
  • 不支持多用户写入及任意修改文件

HDFS采用抽象的块概念,默认一个块64MB,一个文件被分成多个块,以块作为存储单位。块的大小远远大于普通文件系统,可以最小化寻址开销。

HDFS 主要组件及其功能:

image-20191224165519470

  • NameNode:

image-20191224165851900

对应 HDFS 的命名空间,即目录、文件和块。

在 NameNode 启动的时候,它会将 FsImage 文件中的内容加载到内存中,之后再执行 EditLog 文件中的各项操作,使得内存中的元数据和实际的同步。

  • **SecondaryNameNode:**保存 NameNode 中对HDFS 元数据信息的备份(GET/POST),并减少 NameNode 重启的时间。

  • **DataNode:**负责数据的存储和读取,会根据客户端或者是名称节点的调度来进行数据的存储和检索,并且向名称节点定期发送自己所存储的块的列表。

HDFS1.0体系结构:

image-20191224171254232

HDFS 存储原理(策略):

  • 冗余数据保存,即一个副本被分不到不同的数据节点。加快数据传输速度,容易检查数据错误且保证了数据可靠性。
  • 数据存取

**存:**第一个副本放在上传文件的数据节点或随机选取一台状态良好的节点,第二个副本会放置在与第一个副本不同的机架的节点上,第三个副本放置在与第一个副本相同机架的其他节点上,更多副本则随机节点。

**取:**从名称节点获得数据块不同副本的存放位置列表(所属的机架ID),就优先选择机架ID相同的副本读取数据,如果没有发现,就随机选择一个副本读取数据。

  • 数据错误与恢复

    • 名称节点出错,对应 SecondaryNameNode 的备份机制;

    • 数据节点出错,每个数据节点会定期向名称节点发送“心跳”信息,向名称节点报告自己的状态。名称节点就无法收到来自数据节点的心跳信息时,标记该数据节点为”宕机“并不再发送 I/O 请求。同时名称节点会定期检查数据块的副本数量,小于冗余因子会生成新的副本;

    • 数据出错,采用md5和sha1对数据块进行校验,防止网络传输和磁盘错误造成的数据错误。校验出错则会请求另外一个数据节点读取该文件块,并且向名称节点报告这个文件块有错误,名称节点会定期检查并且重新复制这个块。

HDFS 常用 shell 命令:

  • hadoop fs -ls <path>:显示<path>指定的文件的详细信息
  • hadoop fs -mkdir <path>:创建<path>指定的文件夹
  • hadoop fs -cat <path>:将<path>指定的文件的内容输出到标准输出(stdout)
  • hadoop fs -copyFromLocal <localsrc> <dst>:将本地源文件<localsrc>复制到路径<dst>指定的文件或文件夹中
  • hadoop fs –put <localsrc> <dst>:将本地源文件<localsrc>上传到HDF服务器的<dst>目录下
  • hadoop fs –get <src> <localdst>:从HDFS拷贝文件到本地文件系统
  • hadoop fs –mv <src> <dst>:将制定格式的文件 move到指定的目标位置
  • hadoop fs –rm <src>:删除匹配pattern的指定文件
  • hadoop fs –rmr <src>:递归删掉所有的文件和目录

Java API 操作 HDFS:

  • 导入 jar,在 /usr/local/hadoop/share/hadoop
  • 读写过程

读:

	Configuration conf = new Configuration();
    conf.set("fs.defaultFS","hdfs://localhost:9000"); 
    conf.set("fs.hdfs.impl","org.apache.hadoop.hdfs.DistributedFileSystem");
    FileSystem fs = FileSystem.get(conf);
    Path file = new Path("test"); 
    FSDataInputStream getIt = fs.open(file);
    BufferedReader d = new BufferedReader(new InputStreamReader(getIt));
    String content = d.readLine(); //读取文件一行
    System.out.println(content);
    d.close(); //关闭文件
    fs.close(); //关闭hdfs

写:

	Configuration conf = new Configuration();  
	conf.set("fs.defaultFS","hdfs://localhost:9000");
	conf.set("fs.hdfs.impl","org.apache.hadoop.hdfs.DistributedFileSystem");
    FileSystem fs = FileSystem.get(conf);
    byte[] buff = "Hello world".getBytes(); // 要写入的内容
    String filename = "test"; //要写入的文件名
    FSDataOutputStream os = fs.create(new Path(filename));
    os.write(buff,0,buff.length);
    System.out.println("Create:"+ filename);
    os.close();
    fs.close();

HBase

BigTable:一个分布式存储系统

  • 使用 MapReduce 分布式并行计算模型来处理海量数据
  • 使用分布式文件系统 GFS 作为底层数据存储

HBase 则是 BigTable 的开源实现,用来存储非结构化和半结构化的松散数据,具有高可靠、高性能、面向列、可伸缩特性的分布式数据库。

两者对比:

image-20191224204424116

HBase与传统的关系数据库的区别:

  • 数据类型:关系数据库采用关系模型,具有丰富的数据类型和存储方式,HBase则采用了更加简单的数据模型,它把数据存储为未经解释的字符串。
  • 数据操作:关系数据库中包含了丰富的操作,其中会涉及复杂的多表连接。HBase操作则不存在复杂的表与表之间的关系,只有简单的插入、查询、删除、清空等。
  • 存储模式:关系数据库是基于行模式存储的。HBase是基于列存储的,每个列族都由几个文件保存,不同列族的文件是分离的
  • 数据索引:关系数据库通常可以针对不同列构建复杂的多个索引,以提高数据访问性能。HBase只有一个索引——行键,HBase中的所有访问方法都使用行键。
  • 数据维护:在关系数据库中,更新操作会用最新的当前值去替换记录中原来的旧值,旧值被覆盖后就不会存在。而在HBase中执行更新操作时,并不会删除数据旧的版本,而是生成一个新的版本,旧有的版本仍然保留
  • 可伸缩性:关系数据库很难实现横向扩展,纵向扩展的空间也比较有限。相反,HBase和BigTable这些分布式数据库就是为了实现灵活的水平扩展而开发的,能够轻易地通过在集群中增加或者减少硬件数量来实现性能的伸缩

HBase的访问接口:

Java API、HBase Shell、Thrift Gateway、REST Gateway、Pig、Hive

HBase当中的表:

image-20191224205844366

注:根据行键、列族、列限定符和时间戳来确定一个单元格,视为一个“四维坐标”。

实现原理

HBase的实现包括三个主要组件

  • 库函数
  • 一个 Master 主服务器:管理维护 HBase 表的分区信息以及 Region 服务器列表,分配 Region,实现负载均衡。
  • 多个 Region 服务器:负责存储和维护分配给自己的 Region,处理来自客户端的读写请求(客户端通过Zookeeper来获得Region位置信息)。

**三层结构:**可以保存最多 2^34个 Region

image-20191224211218922

于是从前面的 HDFS 体系扩展为 HBase 的系统架构如下:
在这里插入图片描述

  • 客户端:包含访问HBase的接口,同时在缓存中维护着已经访问过的Region位置信息,用来加快后续数据访问过程。
  • Zookeeper:是一个很好的集群管理工具,选举出一个 Master 作为集群的总管,并保证在任何时刻总有唯一一个Master在运行。

Regin服务器原理

数据的读写:

  • 写入数据:

    请求相应 Region 服务器->操作写入Hlog -> 数据写入MemStore 缓存->commit() 调用写入磁盘

  • 读取数据:

    请求相应的 Region 服务器->访问 MemStore 缓存->不存在查找磁盘上的 StoreFile

缓存刷新与StoreFile的合并:

系统会周期性地把MemStore缓存里的内容刷写到磁盘的StoreFile文件中,清空缓存,并在Hlog里面写入一个标记。

每次刷写都生成一个新的StoreFile文件,如果 StoreFile 文件过多会调用 Store.compact() 进行合并;而单个StoreFile过大时,又触发分裂操作。

Hlog 原理

HBase系统为每个Region服务器配置了一个HLog文件。

用户更新数据必须首先写入日志后,才能写入MemStore缓存,并且,直到MemStore缓存内容对应的日志已经写入磁盘,该缓存内容才能被刷写到磁盘。

Zookeeper 发现故障 Region 服务器,就会通知 Master 主服务器。

Master 主服务器则会处理遗留的 Hlog 文件(包含多个 Region 对象),将失效的 Region 以及日志记录重新分配到可用的Region服务器。

HBase安装与使用

安装:

三种运行模式,单机模式、伪分布式模式、分布式模式

需要环境:JDK、Hadoop(单机模式不需要)、SSH、Zookeeper

HBase Shell:

  • 创建表、列出所有表

    create ‘tempTable’,‘f1’,‘f2’,‘f3’ //三个列族

    list

  • 添加数据、浏览表信息

    put ‘tempTable’,‘r1’,‘f1:c1’,‘hello,hbase’

    scan ‘tempTable’

  • 获取单元格数据

    get ‘tempTable’,‘r1’,{COLUMN=>‘f1:c1’}

  • 使表有效或无效、删除表

    enable/disable

    drop


NoSQL数据库

关系数据库已经无法满足Web2.0的需求。主要表现在以下几个方面:

  1. 无法满足海量数据的管理需求
  2. 无法满足数据高并发的需求
  3. 无法满足高可扩展性和高可用性的需求

NoSQL和关系数据库的比较:

  • 关系数据库
    优势:以完善的关系代数理论作为基础,有严格的标准,支持事务ACID四性,借助索引机制可以实现高效的查询,技术成熟,有专业公司的技术支持
    劣势:可扩展性较差,无法较好支持海量数据存储,数据模型过于死板、无法较好支持Web2.0应用,事务机制影响了系统的整体性能等
  • NoSQL数据库
    优势:可以支持超大规模数据存储,灵活的数据模型可以很好地支持Web2.0应用,具有强大的横向扩展能力等
    劣势:缺乏数学理论基础,复杂查询性能不高,大都不能实现事务强一致性,很难实现数据完整性,技术尚不成熟,缺乏专业团队的技术支持,维护较困难等

典型的NoSQL数据库通常包括键值数据库(Redis)、列族数据库(HBase)、文档数据库(MongoDB、ElasticSearch)和图形数据库。

与关系型数据库的 ACID 四个特性类似,NoSQL 数据库也有三个


MapReduce

MapReduce 是谷歌的分布式并行编程模型,而 Hadoop MapReduce是它的开源实现。

MapReduce 体系结构:
在这里插入图片描述

由四个部分组成:

  • Client:我们的 MapReduce 程序通过 Client 提交给 JobTracker 端。
  • JobTracker:负责资源监控和作业调度。
  • TaskTracker:周期性地通过“心跳”将本节点上资源的使用情况和任务的运行进度汇报给JobTracker,同时接收JobTracker 发送过来的命令并执行相应的操作。
  • Task:分为 Map Task 和 Reduce Task 两种,由 TaskTracker 启动。

MapReduce工作流程:

image-20191225154803886

HDFS 以固定大小的block(数据块)为基本单位存储数据,而对于MapReduce 而言,其处理单位是split(分片)。

Shuffle 过程

下图从map( )的输出到reduce( )的输入,中间的过程被称为shuffle过程

image-20191225155549839

所以 Shuffle 过程可以分为Map端跟Reduce端的Shuffle过程

  • Map端

    在Map任务全部结束之前进行归并得到一个大的文件,放在本地磁盘;

    文件归并时,如果溢写文件数量大于预定值(默认是3)则可以再次启动Combiner,少于3不需要;

    JobTracker会一直监测Map任务的执行,并通知Reduce任务来领取数据。

    image-20191225160000258

  • Reduce端

    Reduce任务通过RPC向JobTracker询问Map任务是否已经完成,若完成,则领取数据;

    Reduce领取数据先放入缓存,来自不同Map机器,先归并,再合并,写入磁盘;

    当数据很少时,不需要溢写到磁盘,直接在缓存中归并,然后输出给Reduce。
    在这里插入图片描述

案例:

  • 输入:一个包含大量单词的文本文件。
  • 输出:文件中每个单词及其出现次数(频数),并按照单词字母顺序排序。
    在这里插入图片描述

Hive

Hive 是一个基于 Hadoop 的数据仓库工具,可以用于对存储在 HDFS 中的数据集进行数据整理、特殊查询和分析处理。它提供了类似于关系数据库 SQL 语言的查询语言——HiveQL,Hive 会将 HQL 语句快速转换成 MapReduce 任务进行运行。

Hive 可以看作是用户编程接口,其本身并不存储和处理数据,而是依赖 HDFS 来存储数据,依赖 MapReduce 来处理数据。

Hive 系统架构:

image-20191225162850707

三个模块:

  • 用户接口模块:(CLI、HWI、JDBC、ODBC、Thrift Server)用来实现外部应用对 Hive 的访问。
  • 驱动模块:编译器、优化器、执行器,负责把 HiveSQL 语句转换成一系列 MapReduce 作业。
  • 元数据存储模块:是一个独立的关系型数据库,通常是与 MySQL 数据库连接后创建的一个 MySQL 实例,也可以是 Hive 自带的derby 数据库实例。

Hive 中 HQL 语句的 MapReduce 作业转化过程:
在这里插入图片描述

用户向 Hive 输入命令首先进入驱动模块,由驱动模块中的编译器进行解析编译,并由优化器对该操作进行优化计算,然后交给执行器去执行。执行器通常的任务是启动一个或多个 MapReduce 任务,有时也不需要启动 MapReduce 任务,比如,执行包含*的操作时(如 select * from 表),就是全表扫描,选择所有的属性和所有的元组,不存在投影和选择操作,因此,不需要执行 Map 和 Reduce 操。

Hive 的数据类型

Hive 支持关系数据库中的大多数基本数据类型,同时 Hive 还支持关系数据库中不常出现的的 3 种集合数据类型:

image-20191225171430004

Hive 的基本操作

  • 创建数据库

    create database hive;

  • 创建表

    • 创建表 user,并指明存储路径

      create table if not exists usr(id bigint,name string,age int);

      location "/usr/local/hive/warehouse/hive/usr‟;

    • 创建外部表 user,可以读取以“,”分隔的数据

      create external table if not exists hive.usr(id bigint,name string,age int)

      row format delimited fields terminated by ‘,’;

    • 创建分区表,还存在分区字段

      create table hive.usr(id bigint,name string,age int) partition by(sex boolean);

      create table if not exists usr1 like usr;//复制usr表

  • 创建视图

    create view little_usr as select id,age from usr;

  • 删除数据库、表、视图

    drop database hive;

    drop database if exists hive cascade; //数据库+表

    drop table if exists usr;

    drop view if exists little_usr;

  • 修改数据库、表、视图

    alter database hive set dbproperties(“edited-by‟=lily”);

    alter table usr rename to user; //重命名表

    alter table usr add if not exists partition(age=10); //增加分区

    alter table usr drop if exists partition(age=10); //删除分区

    alter table usr change name username string after age;//修改列名并置于age字段后

    alter table usr add columns(sex boolean); //增加一个新列 sex

    alter table usr replace columns(newid bigint,newname string,newage int); //重新为表指定字段

  • 查看数据库、表、视图

    show databases/table;

  • 描述数据库、表、视图

    describe database hive;

    describe hive.usr;

  • 向表中装载数据

    load data local inpath "/usr/local/data‟ overwrite into table usr;

    load data inpath "hdfs://master_server/usr/local/data‟ overwrite into table usr;

  • 查询表中数据:与 SQL 基本相同

  • 插入数据或导出数据

    insert overwrite table usr1

    select * from usr where age=10; //向表 usr1 中插入来自 usr 表的数据

猜你喜欢

转载自blog.csdn.net/MOKEXFDGH/article/details/106259787