Hadoop技术总概
Hadoop1
HDFS
解决海量数据的存储
一个主节点namenode,多个从节点datanode
namenode:存储元数据,响应用户的操作请求。
datanode:存储数据,block64M,有三个副本。
secondarynamenode
作用:进行元数据的合并,备份元数据。
hdfs格式化以后会生成一个FSimage的镜像文件,用于保存元数据。
fsimage的信息有两份一份存在内存中一份存在磁盘上。当有文件上传到hdfs上时,会先把元数据存成两份,一份存入内存,一份以editlog线性追加的方式写入磁盘。
为了在namenode重启时,加快磁盘元数据载入内存的速度,磁盘上fsimage文件和editlog文件需要进行合并,合并过程需要再内存中进行,所以就出现了secondarynamenode,它把fsimage和编辑日志进行合并之后回传给namenode,自己也作为元数据的备份者。
secondarynamenode可以作为nanode备份但需要安装第三方软件和修改源码
image.pngMapReduce
-
主节点Jobtracker,
接受用户提交的任务
分配任务给taskTracker
监控taskTracker执行的情况 -
从节点TaskTracker
处理jobTracker分配的活
Hadoop1的架构问题
HDFS问题:
-
存在单点故障问题
-
内存受限
namenode存储元数据,响应用户操作请求。
为了能快速响应用户请求,把元数据放入到内存中。
如果元数据量大,导致内存不够怎么办? -
权限的问题
MapReduce1的问题:
- 只有一个主节点单点故障问题。
- 即要分配任务又要分配资源,干的活太多
- 难以支撑第三方框架(不可以给他们分配计算资源,如不能给spark分配计算资源只能分配MapReduce的计算资源)
Hadoop2
hdfs
解决单点故障问题
-
解决两个namenode元数据实时一致
方式1:共享目录(几乎不用)
方式2:QJM(使用奇数个节点)
引用了JournalNode:可以保持数据的事务性一致,namenode传输元数据数据到journalNode要么全部成功要么全部失败。
active实时写数据,standby实时读数据。 -
解决两个namenode自动切换
- 引入zookeeper
-
每个namenode节点配置一个zkfc
过程:两个namenode启动之后去zookeeper抢占锁,抢到的就是active。zkfc实时监控namenode健康状况,通过心跳机制汇报给zookeeper。
注意:Hadoop2HA的实现只支持两个namenode
image.png
解决内存受限问题
使用用两套namenode,这两套的namenode的元数据是不一样的,而且各自是高可用的,这就叫做联邦federation。
在进行存数据时要指定存在哪个namenode上,就像存在哪个盘一样。如Hadoop dfs -put hello.txt hdfs://hadoop01:9000/hello/
联邦,可以按照部门或者项目来划分各套namenode存取的地址。
联邦也存在一定问题比如有的计算框架依赖于磁盘有的依赖于内存,不好管理。
image.png
MapReduce
- 解决单点故障
- 解决任务分配和资源分配都做的问题
- 解决不能支持其它计算框架的问题
yarn的出现解决了以上问题。
YARN
YARN 是一个资源调度平台,负责为运算程序提供服务器运算资源,相当于一个分布式的操作系统平台,而 MapReduce 等运算程序则相当于运行于操作系统之上的应用程序。 YARN 集群,具有更好的扩展性,可用性,可靠性,向后兼容性,以及能支持除 MapReduce 以外的更多分布式计算程序。
-
YARN也是一个主从式的架构:主节点叫Resourcemanager从节点叫NodeManager
-
YARN 并不清楚用户提交的程序的运行机制。只提供运算资源的调度(用户程序向 YARN 申请资源,YARN 就负责分配资源)
-
YARN 中的主管角色叫ResourceManager,YARN 中具体提供运算资源的角色叫 NodeManager这样一来,YARN 其实就与运行的用户程序完全解耦,就意味着 YARN 上可以运行各种类型的分布式运算程序(MapReduce 只是其中的一种),比如 MapReduce、Storm 程序,Spark程序,Tez ……;所以,Spark、Storm 等运算框架都可以整合在 YARN 上运行,只要他们各自的框架中有符合 YARN 规范的资源请求机制即可。
-
YARN/MRv2 最基本的想法是将原 JobTracker 主要的资源管理和 Job 调度功能分开作为两个单独的守护进程。
-
yarn有一个全局的 ResourceManager(RM)和每个 应用程序有一个ApplicationMaster(AM),Application 相当于 MapReduce Job 或者 DAG jobs。
-
ResourceManager和 NodeManager(NM)组成了基本的数据计算框架。
-
ResourceManager 由两个组件构成: 调度器(Scheduler )和 应用程序管理器(ApplicationsManager ,ASM )。协调集群的资源利用,任何Client或者运行着的 ApplicatitonMaster 想要运行Job 或者 Task 都得向RM 申请一定的资
源。 -
YARN 本身为我们提供了多种直接可用的调度器,比如 FIFO,Fair Scheduler
和 Capacity Scheduler 等 -
ApplicatonMaster 是一个框架特殊的库,对于 MapReduce 框架而言有它自己的 AM 实现,用户也可以实现自己的 AM,在运行的时候,AM 会与 NM 一起启动和监视 Tasks。
image.png
ApplicationMaster
如果一个AM运行到80%挂了,会由另一个nodeManager节点上的备用AM接着运行。AM的信息是存在zookeeper之上的,其它备用AM成为active之后会继续运行80%之后的任务。
Yarn在2里面只能管理内存和cpu但不能管理磁盘和网络,这是未来发展的一个方向。
- Hadoop3
支持两个nameNode以上。纠删码解决备份存储浪费的问题。
- Hadoop就是按一个类Linux操作系统来设计的。
如果把Hadoop看成一个操作系统
HDFS:分布式文件系统,配置文件目录放在/etc/
Yarn:资源管理器
MapReduce:就是一个自带的计算程序
计算程序还有:Spark,Flink
Hbase和Hive是数据库,的配置文件目录是conf
Hive
调优
- 从架构层面:
网络如何配置
防火墙如何规划
带宽如何规划
文件格式
压缩格式
资源的管理方式(yarn,Mesos等) - 从源码层面:
修改源码 - SQL层面
SQL经验要丰富 - 参数层面
HDFS,YARN,MapReduce,Hive
防止数据倾斜问题
自定义UDF
-
新建一个java项目导入hivejar包
-
新建一个类继承extend UDF
-
在这个类的内部实现一个到多个重载的名叫evaluate的方法
-
将编写好的自定义函数类打成jar包添加到hive的classpath中
add jar /home/hadopp/**.jar ;
list jar; -
创建一个零时函数管理到用户自定义的类
create temporary function myfunc as "类全限定名" -
验证函数
show functions;可以看到自定义的函数
select myfunc(3,4);补充:当前会话断开后临时函数就失效。
hive hql
DDL的语句不需要跑MapReduce,因为涉及到的是元数据的操作。
另外还有select * from user;也不需要跑,因为user 是一张表,体现为hdfs上的一个目录。select * 负from user where p="1" 分区也体现为hdfs上的一个目录所以不需要计算。select name from user 特殊点:现在的版本不需要跑了。
HBase
HBase是一个分布式的面向列的,适合非结构化,半结构化,结构化,高性能的,可扩展的开源NoSQL数据库。
关系型数据库:
没有分布式时:如果库存不下可以分库,表存不下可以分表(水平分表,垂直分表)。
mysql和Oracle都是支持分布式的为什么扩展性不好呢?因为扩展时牵一发而动全身,而HBase只需要添加节点就可以了。
缺点
-
面向行:关系型数据库,行的长度是已知的,线性表的的方式进行存储。需要做磁盘预留,有的列的数据存不满。
-
数据量大时磁盘空间浪费就多。需要多表进行查询,会把多张表合并成一张大表。这样磁盘预留就比较多就导致磁盘利用率不高。
-
内存利用率不高:查询数据时需要把整张表放入内存。
在面向列的存储中进行select name from user的查询的时候,只需要把name加入内存。 -
半结构化的数据,存不了。
-
HBase能不使用就不使用原因:
- 不好 驾驭
- 如果数据不大的情况下,处理起来没有关系型数据库处理起来快。
-
什么样的情况下适合:
- 数据量大
- 实时处理
- 数据的分布比较稀疏。
-
最成功的概念region
把一张表分成各个region,把这些rejoin分到不同节点。
一次读数据的过程:
get ’tableName‘,’rowkey‘
- 通过zookeeper找到.meta.表,查询到region所在的regionserver
- 查找内存MemStore
- 通过布隆过滤器查找在哪一个StoreFile中
- 读取这个storeFile的Trailer,获得Datablock位置
- 把DataBlock加入内存找到rowkey
一次写数据过程:
put 't_Name','rk001','cf1:name','zhangsan'
- 通过跳表结构找到rejoin
- 把数据写入HLog文件
- 把数据写入MemStore(在其中排序)
- MemStore达到阈值,溢写到磁盘。
a. 如果StoreFile达到3个进行一个minorCompact,只删除TTL=0且MIN_VERSION=>'0'的数据。
b. 手动进行majorCompact合并Store内的所有文件为一个大文件,把相应put和delete进行抵消。
c. 如果当前store所在的rejoin大于10G就会进行分裂,分裂的原则是保证一个rowkey所有的数据只存在于一个region之中的前提下进行均分。
一台rejoinserver挂了
关键点在于把利用HLog内存中数据恢复出来。因为其它的StoreFile都是持久化到成HFile的文件,也就是都有备份。
一台master挂了
所有元数据(namespace,table,column family)被冻结,无法创建表,删除表,修改表,在rejoin分裂的时候,无法进行rejoin的负载均衡。但是表的读写是正常的。
rowkey的设计三原则
- 长度越短越好,防止资源浪费
- 散列原则防止数据热点。
加盐、哈希、反转、时间戳反转 - 唯一性原则。把经常一起读取数据设计成连续rowkey,存储在一起。
flume:日志收集系统
自动的把业务系统中的日志收集迁移到数据仓库中。
kafuka
在进行实时计算时会先把前端收集来的数据先缓存在kafka中。类似于一个缓存,
- flume去收集日志,存入kafka中,分析系统再从kafka中取数据。
实时处理系统的架构
- 批处理层
进行数据的清洗,数据的预处理,得到可以进行快速的查询的数据。 - 服务层
支持批处理层,对批处理成的数据进行快速查询。 - 速度层
解决实时处理的需求。- 实时处理就像商场中的扶梯,来一个人上一个人。离线计算使用MapReduce就像直升梯。
大数据流程图
image.png