整点闲话

小二在工作之余突发奇想,整篇关于Hadoop的基础原理的知识,希望能帮助大家更容易去学习更多技术知识。我了解到大学现在很多大数据和数据分析的专业,涉及到大数据必须得把这个Hadoop搞定啊,Hadoop在数据提取,变形和加载的自身优势使其在超大数据集的应用程序上不仅提供海量数据的存储,同时也提供了高速计算的手段。

Hadoop介绍

针对分布式系统架构,Apache开发出Hadoop,让我们可以开发分布式的程序。重要的两点就是其分布式存储文件系统(HDFS)和高速运算(MapReduce)。这两兄弟也是Hadoop的核心设计,其中HDFS的高容错性也让我们的开发和维护人员的负担减轻不少,它的高吞吐量又让我们访问应用程序的数据又多又快。
我们理解Hadoop的HDFS和MapReduce时,把HDFS当作一个分布式的,能冗余能备份还能动态扩展的硬盘就行了;MapReduce就理解成一个计算引擎,用它的规则去写map或reduce的计算程序就可以对数据进行计算。

实际应用

我们的强大的Hadoop既然能分布存储海量数据,又提供运算,所以非常适合日志分析。

因其架构比较复杂,小二就不赘述(不是卖关子!)

那我们常用的酷狗音乐,它的架构也使用到了Hadoop这项技术。

hadoop培训就业 hadoop及大数据培训_hadoop

简单讲一下它的大数据平台吧,首先就是在前后端和数据库获取日志信息,前后端的日志数据会存入kafka代理和集群然后通过清洗数据再次进入kafka重用缓存,然后就是进入redis,spark这些地方做存储计算,计算出的结果通过service服务最后到应用消费数据。

比如你今天听英文歌连续听了半小时或一小时,那么你听歌的歌曲信息等数据存入日志,其中通过系统的计算规则,比如一些推荐算法,你明天听歌的时候,日推肯定是英文歌占多数的。推荐算法不一定是按照时间,也可能是按照听单首歌曲的次数,时段等去计算的,所以具体的推荐算法你得去问推荐算法工程师。
通过这张图我们知道,其中存储计算的部分是包含了我们使用的Hadoop的HDFS。这就是一个实际应用。

Hadoop的生态系统

hadoop培训就业 hadoop及大数据培训_java_02

稍作解释:
ETL:数据抽取到mysql,Oracle,DB2,mongoDB等主流数据库
数据挖掘可以做比较流行的广告推荐,个性化广告推荐等
Apache+Mahout项目就是个机器学习的应用
记住HBase,Hive,以后会讲哟。

HDFS

既然我们要学习Hadoop,首当其冲就是HDFS。(终于进入正题了。。)

hadoop培训就业 hadoop及大数据培训_java_03


首先,我们使用一台机子存储我们的数据,很容易因数据过大撑爆硬盘,加磁盘是解决不了问题的 ,数据不断增多,总有一天撑不住。所以我们使用分布式的方式去存储数据。多机一起存储不仅使存储量增大很多,还可通过一些策略使容错率和吞吐提高不少。

文件也有大有小,小的几kb,大的文件几百G都有。所以我们有很多方式去一一解决这些问题。
针对大文件,我们的HDFS默认以128mb的大小去切分文件,每个128mb的文件,在HDFS中叫块。
这个大小也是有讲究的,设置大了文件传输的时间会很长,因为一次假如传输1个G,那就只能慢慢等,设置小了,我们文件系统寻址时间又会很长,又要花时间等。。。
(温馨提示:2.7.3版本后是128mb,老版本是64mb)

假如有一个100G的文件要存储,但是你的硬盘只有50G,这是我们就要用到HDFS,将此文件切分为块,然后分别存到多台机器中,为了方便找到我们的文件块,我们提供一个统一的接口去管理我们 的文件。我们要查一个文件的时候,如果遍历机器去找我们这个文件所有的块,这样的时间复杂度是o(n)的,不仅慢,而且万一有一个存储其中文件块的机器宕掉了,那就查不到了。这样不是徒增麻烦嘛!

hadoop培训就业 hadoop及大数据培训_hadoop培训就业_04


看一下它的基本架构,这里NameNode相当于一个管理者,所有的文件存储和查找都要通过NameNode,DataNode就是真正存储文件的地方。NameNode知道每一个DataNode的 存储情况,client就是那个对外操作的统一接口。所以client要查询文件时,也是先去NameNode里面询问要找文件在哪个DataNode上,写入文件时也是一样的,要先经过NameNode。这样就是o(1)的。

这时又有问题:如果DataNode宕掉了怎么办,数据不就缺失了嘛?
当HDFS在写入一个数据库块的时候,会写入到多个DataNode中,这样,其中一个DataNode坏了,还可以从其它备份的DataNode中拿数据,保证数据不丢失。(数据可靠性)


HDFS的写入文件流程

  1. client请求写入文件。
  2. NameNode检查文件和父目录是否已存在,返回确认可以上传的信息给client
  3. client会先把文件进行切分,我们的block设置块为128mb时,假如一个文件有500mb,那么就会切分为128mb,128mb,128mb,116mb四个块。client请求第一个块要传到哪些DataNode中。
  4. NameNode收到请求返回DataNode服务器
  5. client请求DataNode上传数据块,第一个DataNode收到请求会继续调第二个DataNode,依次建立一个传输通道。
  6. client开始上传第一个数据块,写入数据的时候第一台DataNode收到后会传给下一台,依次传输,这里传输的都是第一个数据块。这里也是个备份的处理。
  7. 第一个数据块传输完后,client再请求下一块,直到整个文件传输完成。

写入流程中NameNode做了什么:

  1. client请求写入文件。
  2. NameNode把这个事件记录到editlog,记录的内容就是元数据,文件被分为几块,存在哪些DataNode中。
  3. 其中SecondNameNode相当于NameNode 的小弟,他会帮大哥定期把editlog读入,把它合并到一个某一时刻的内存快照fsimage中,然后清空editlog。
  4. 如果NameNode挂掉了,重启NameNode后,会先从fsimage中加载,然后从editlog中按顺序读取操作去恢复。
  5. 然后将当前内存存到fsimage作为下个快照,同时清空editlog

HDFS的读取流程

  1. 首先client询问NameNode,要读取某个路径下的文件,让NameNode提供文件在哪些DataNode中的信息。
  2. 然后选一台DataNode,建立socket流(相当于我们的Java中的流)
  3. DataNode发送数据(使用packet做校验)
  4. client接收后,在本地缓存,然后写到目标文件,最后把所有块append拼成一个完整的文件。

HDFS的删除流程

  1. client发起请求到NameNode
  2. NameNode收到请求后,将这个操作先记录到editlog中,然后将数据从内存删掉,并返回信息给client
  3. client收到信息认为数据已经删除,实际数据还在DataNode上,上一步只是在日志文件editlog中删掉而已(逻辑删除)
  4. 当DataNode向NameNode发送心跳时,NameNode检查到这个DataNode的节点数据,如果发现有多的数据(比如被删掉的),在元数据中没有记录了,NameNode就会响应并命令对应的DataNode删掉指定数据。这时才真正删掉了。

  • 讲完删除就要知道如果某个DataNode掉线了,HDFS就是通过心跳去获取状态的。
    DataNode启动的时候会先去NameNode注册,然后他们维持心跳,超过时间阈值还没收到DataNode心跳,那么就认为此DataNode挂掉了
  • 下一个问题就是:我们把数据块存到DataNode上,可能这个DataNod 的磁盘有部分损坏,但是我们的DataNode并没有下线,但我们也不知道有没有损坏怎么办?
    所以我们的数据块(block)除了存放数据本身,还会存放一份元数据(数据块长度,块数校验和,时间戳)。DataNode还会定期向NameNode上报所有当前所有数据块的信息,通过元数据就可以校验当前的数据块是否为正常状态。

元数据(metadata)是指描述数据的数据,这里是指描述文件的数据,比如文件分成几块,在哪些DataNode中的数据就是元数据。
NameNode存储了文件的元数据(metadata),但是如果重启了,或机器意外宕机,那么元数据不就没了?
所以写入时需要把元数据持久化到硬盘

HDFS会把操作日志记录下来,存在editlog中,下次重启的时候,先加载editlog,把所有的日志都恢复一遍,达到重启前的那个状态。
操作之前先写log,这就是WAL思想,保证机器挂了,数据及操作不会丢失
(WAL思想简单来说就是在做实际的数据操作之前要保证已经记录相关日志)

但是又有一个问题:

  • 如果NameNode运行很久了,文件操作了很多很多,editlog对应就非常大了,
    那么重启的时候,恢复操作后,启动时间就很长了。

这时那个SecondNameNode起到作用了,
其实NameNode回放editlog时,不是每次都从头回放,它会先加载一个fsimage。
这个fsimage文件是之前某一时刻整个NameNode的文件元数据的内存快照,
然后再在这个基础上去回放editlog,然后,清空editlog,再把当前文件数据的内存状态写入fsimage,方便下一次加载。使用某一时刻的fsimage,解决了每次都从头回访操作降低效率的问题。
这就是全量回放变成了增量回放

  • 但是如果NameNode很长时间没有重启,editlog也一样会很大,怎么解决呢?

其实 SecondNameNode 会定期将editlog的操作写入fsimage,然后清空editlog。保证它不会一直无限增大,SecondNameNode是个定时任务,有了它 ,editlog 就不会超级大了。

  • 那如果NameNode挂了,谁接替它工作?

如果一个集群中只有一个NameNode,那么这个NameNode挂了,整个系统就挂了,这里是个单点。(单点故障)SecondNameNode并不会接替它工作。

所以引发一个版本知识:
hadoop1.x版本时,整个集群只能有一个NameNode,有可能发生单点故障的,所以很不稳定。
hadoop2.x版本之后,可以再集群中配置多个NameNode,但是配置了多个NameNode需要注意的就更多了,因为这时的系统更复杂。

那么,我们的集群中就有了主备故障转换控制器
就是说,如果有两个NameNode,那么只能有一个是活跃的(active),另一个就是备份或者说备用状态(standby)
两个NameNode通过JournalNode实时同步editlog,状态一致可相互替代。
注意这里的 同步!!! active的NameNode挂了后,standby的NameNode就要马上接替active,所以他们的数据要保持一致。写入数据时,两个NameNode内存中和都要记录数据的元数据信息,并保持一致。
JournalNode就是用来在两个NameNode中同步数据的。而standby NameNode是实现了SecondNameNode的功能的。

主备怎么同步数据呢?

  • active NameNode有了操作后,它的editlog会被记录到JournalNode中,
    而standby NameNode则会从JournalNode中读取并同步,同时standby NameNode会监听记录的变化。
  • 大致就是editlog会通过JournalNode同步给standby NameNode实现实时同步(监听功能)。
    standby NameNode就实现了Second NameNode的功能。

注意:hadoop2.x后如果只部署一个NameNode,还是会用SecongNameNode的。

醒醒,别睡着了!

hadoop培训就业 hadoop及大数据培训_hadoop_05

HDFS的优点:

  1. 可以存储海量数据,并且高可用,主从备份保证了数据的高可靠,出现宕机,也不会影响整个系统的使用。

HDFS的缺点:

  1. 每个小文件都有元数据信息,他们都存在NameNode里面,会造成NameNode的内存不足。
  2. HDFS不适合存储大批量的小文件
  3. HDFS不提供编辑文件的功能,文件写入后无法随机修改,只能追加,如果要改中间部分内容,就只能覆盖了。
  4. HDFS不支持并发写入数据。
  5. HDFS设计出来是用来做离线计算的,查询效率也不高,一般是秒级的,可以说是很慢了。

咳咳,别看它这么多缺点,Hadoop工程师薪资一直在涨喔,平均好像有1.6了都。学好还是很有用的,这里的HDFS也只讲了个基础大概,知识无穷无尽,学海无涯,回头无岸。

简单了解一下MapReduce

概念

MapReduce是一种编程模型,采用分而治之的思想。它的核心也分为两部分:Map和Reduce。

每个文件分片由单独的机器去处理,这就是Map的方法。把各个机器计算的结果汇总并得到最终结果,这就是Reduce的方法。

工作流程

提交一个计算作业到MapReduce框架时,会先把计算作业拆分成若干个Map任务,然后分配到不同的节点执行,Map任务完成后,会生成中间文件,这些文件会作为Reduce任务的输入数据。Reduce任务主要是把前面的Map输出结果汇总,再输出结果。

hadoop培训就业 hadoop及大数据培训_hadoop培训就业_06